Lambda the Ultimate

inactiveTopic Environment, scripting, and behavior
started 3/24/2003; 12:20:29 PM - last post 3/31/2003; 12:30:35 PM
Dan Shappir - Environment, scripting, and behavior  blueArrow
3/24/2003; 12:20:29 PM (reads: 3095, responses: 18)
Environment, scripting, and behavior
Jon Udell on VMs and dynamically typed PLs:

Mark Dulcey wrote to point out that the Parrot VM is not intended to support Perl only, but any dynamic language ... It would be best, in my view, if the JVM and CLR could serve this purpose. My gut tells me the obstacles are cultural, not technical.

And

I'm no VM guru. Maybe there really is no way for the JVM and CLR virtual machines to properly support dynamic languages. But somehow, I doubt that.

Putting aside the ST vs. DT argument (if we can :-) I think we can all agree that it would be for the best if a single VM could support both as first class citizens. Is this possible?
Posted to cross-language-runtimes by Dan Shappir on 3/24/03; 12:50:57 PM

Dan Shappir - Re: Environment, scripting, and behavior  blueArrow
3/24/2003; 12:55:13 PM (reads: 1943, responses: 1)
Another item on Jon's blog that is relevant to this issue.

Note to Ehud: server response time is getting so bad that posting news items is just too painful.

Ehud Lamm - Re: Environment, scripting, and behavior  blueArrow
3/24/2003; 1:00:31 PM (reads: 2016, responses: 0)
Strange. The response times I am getting are improving.

Dominic Fox - Re: Environment, scripting, and behavior  blueArrow
3/24/2003; 2:10:50 PM (reads: 1927, responses: 0)

This white paper on Mark Hammond's efforts to port Python to .NET provides an interesting perspective on this question.

Patrick Logan - Re: Environment, scripting, and behavior  blueArrow
3/25/2003; 8:07:24 AM (reads: 1758, responses: 0)
I've mentioned the approach I would take toward a universal machine in several forums recently. Summarizing I would say it like this...

The underlying mechanisms for the CLR as well as for the JVM *are* dynamic. The problems for making these systems universal are in the necessity to use nearly the entire language model of C# or Java, rspectively, in order to achieve any kind of integration.

A better approach, IMHO, would be to make integration more abstract and more loosely coupled than the "shared object model" of the CLR or JVM.

Components written in various languages should be integrated via a simpler, asynchronous, shared-nothing, message passing model. Then those components could be instantiated in the same OS process, a different OS process, or on a distinctly different host on the network, without having to alter the mechanism for integration.

A virtual machine in this model would offer a reusable implementation of garbage collection, component instantiation, time-sharing, channel discovery, message formatting, optimized "intra-OS-process" message passing, and an instruction set for sequential processing. A universal virtual machine would not require a shared-memory, monitor-based, object model.

I would choose Scheme as the "instruction set" of my virtual machine, and not make language implementors deal with low level CPU models.

Gregory Williams - Re: Environment, scripting, and behavior  blueArrow
3/25/2003; 5:54:46 PM (reads: 1649, responses: 0)
Dan Sugalski, the designer of Parrot, responds in a blog entry regarding the reasons for Perl 6 targetting Parrot instead of the JVM or CLR.

Apparently, the main issues are portability and the support of polymorphic scalars, closures, co-routines, and continuations.

We have to run on any of a half-zillion platforms, and .NET is windows only. Mono makes that somewhat better, but still... got Mono for a Cray system, a VMS system, or a Palm? Probably not. I certainly don't.

...

To make perl work means completely rewriting the system allocation scheme, and using our own custom polymorphic object type. In JVM/.NET bytecode. Doable? Sure. Fast? No way in hell.

And continuations. Yow. To do continuations is non-trivial, and I don't think it's possible to do in the JVM or .NET without treating them as glorified CPUs and use none of their control and stack features.

Kimberley Burchett - Re: Environment, scripting, and behavior  blueArrow
3/26/2003; 10:25:09 AM (reads: 1587, responses: 2)
Actually, I'd be surprised if continuations are needed for Perl 6. Dan didn't even know what they were when he started working on the Parrot VM. If Perl 6 has sprouted continuations (I must have missed that apocalypse), it's only because they showed up in the Parrot VM first.

Ehud Lamm - Re: Environment, scripting, and behavior  blueArrow
3/26/2003; 11:21:20 AM (reads: 1641, responses: 0)
Perhaps it's worth mentioning that continuations, aside from being a useful programming construct, can be used as a general implementation technique. So even languages that don't require contiunuation support can benefit from (efficient) VM level continuations.

Dan - Re: Environment, scripting, and behavior  blueArrow
3/26/2003; 12:07:21 PM (reads: 1633, responses: 0)
Perl 6 will have continuations. Larry's not thought about what the syntax looks like, and to what extent they get expressed, so you've not missed any apocalypses there. (Though the fact that Parrot does them is one of the motivating factors in Perl 6 getting them)

Besides, continuations are really cool. While I didn't know about them back when the mail you reference was written, I do now and, well, I can do all sorts of nifty and profoundly evil things if I have them at hand, and what better reason to include them? (Well, OK, there's the fact that I need them if Parrot's to properly run both Ruby and Scheme, but...)

Göran Hultgren - Re: Environment, scripting, and behavior  blueArrow
3/28/2003; 4:30:55 AM (reads: 1432, responses: 2)
Hi all, just joined!

Gregory Williams wrote: "...and I don't think it's possible to do in the JVM or .NET without treating them as glorified CPUs and use none of their control and stack features."

Regarding .NET and continuations, David Simmons (Smalltalk VM guru and prime developer of SmallScript/S#) has support for continuations and much, much more.

He has been working on enabling SmallScript/S# (do not be fooled by the name, it is probably one of the most capable dynamic languages in existence today) on the .NET platform. Highly recommended reading at:

http://www.smallscript.org/Downloads/SSharp_NET_Notes.asp

So in short - yes, it can be done - no, it isn't easy.

Dan - Re: Environment, scripting, and behavior  blueArrow
3/28/2003; 6:16:59 AM (reads: 1467, responses: 1)
Actually I wrote that, and Greg quoted it. :)

Having talked with Dave Simmons and seen his presentations on what Evil Things he's done to .NET, my statement stands. I should've perhaps gone one step further and added "Or rewrite their firmware, in ways akin to the Alpha's PAL code, by changing their behaviour with add-on C code."

Which is what Dave's done--to get the features he needed, he wrote add-on native code in some spots. To get features equivalent to what you get with his very nice AOS platform on .NET you have to run as untrusted code because of what he's had to do.

This isn't to belittle his acoomplishments in any way, but he has had to change the base platform to get what he needs done.

Göran Hultgren - Re: Environment, scripting, and behavior  blueArrow
3/28/2003; 7:23:24 AM (reads: 1408, responses: 0)
Ah, sorry for the wrong attribution.

Yes, I agree that what David has had to do should probably be classified as "cheating". :-) By the way, Squeak has now gotten support for real closures and continuations - work done by Anthony Hannan (not yet included in a released version though):

http://minnow.cc.gatech.edu/squeak/2981

He has reworked Compiler, Debugger and the VM in a pretty impressive way and we are right now planning on how to integrate all that work into version 3.6 or later. And cool enough the new VM is plenty faster too.

Who needs CLR! ;-)

Dan Shappir - Re: Environment, scripting, and behavior  blueArrow
3/31/2003; 3:57:16 AM (reads: 1412, responses: 0)
Its nice to see a Dan doing something this interesting :-)

I've read your blog entry regarding Parrot vs. JVM and CLR. In it you write:

Perl 5 has two big features that make using the JVM or .NET problematic--closures and polymorphic scalars ... To do closures means capturing and maintaining persistent lexical state. Neither .NET nor the JVM have support for this, as they use a simpler stack-based allocation of lexical variables. To handle lexicals the way perl needs them means we'd have to basically ignore the system variable allocation system and do it ourselves.

And also

In this case mostly closures and continuations, which are the biggies. (weakly, runtime typed variables are less of a problem, though still a problem) The answer is yes, but they'd be stupid to do so. As I said, those features have unavoidable overhead. Running perl faster at the cost of running C# slower is not, at least in my estimation, a good tradeoff.

Emphasis is mine. You are the VM expert, not I, but it seems to me that at least for closures you can implement them in a way so that you only pay for them if you use them. IMO it should be pretty straightforward to determine at compile-time if a scope is being used as a closure. If its not then the standard stack-based allocation of lexical variables can be used. Only if a scope is being used as a closure would you allocate it as an object on the free-store (and place a ref to it on the stack).

Using this technique would mean that C# and VB.NET would not have to pay the price. Even Perl would benefit as I assume that most scopes aren't used as closures.

BTW, JScript.NET does implement closures, for example the following sample (based on Paul Graham's Accumulator Generator pattern):

function accumulator(n : int) {
  return function(i : int) : int {
    return n += i;
  };
}

var acc = accumulator(3);
print(acc(2));
print(acc(3));

compiles just fine using jsc /fast. I don't know how MS implemented this, nor how efficient their implementation is.

Dan - Re: Environment, scripting, and behavior  blueArrow
3/31/2003; 7:03:28 AM (reads: 1295, responses: 5)
Miguel's example has issues in some cases--for it to work all variables referenced in a closure have to be heap-allocated and accessed by reference, and the closure construction he details is pretty expensive.

Still, I think I may have been a bit over-absolutist--if you don't mind things being really expensive in the case where you use closures, the non-closure case can still be cheap. I sort of alluded to this, but I wasn't clear and I think I got a bit enthusiastic for rhetorical reasons.

Bad Dan, no cookie for me! :)

Dan Shappir - Re: Environment, scripting, and behavior  blueArrow
3/31/2003; 10:19:09 AM (reads: 1340, responses: 4)
Yes, Miguel's example is nice (I had only noticed your second blog entry after posting my message). Also, I've found that this technique of doing closures in C# was previously descussed on LtU.

As I have previously stated I think that delegate support in the .NET VM could be leveraged to implement functional languages on that framework. Yes, the price you pay for closures is indeed a bit high, but you only pay for the closures you actually use.

But this type of payment is common in environments such is the JVM or .NET, at least when compared to a PL such as C++. The very fact that you use a VM, coupled with extensive heap usage and the GC, etc.

Closures and lambda's are some of the things I miss most when working in C++. Getting them in C# makes the switch tempting. Regardless, I think I'll wait until .NET becomes much more prevalent and C# gets generics.

Dan Shappir - Re: Environment, scripting, and behavior  blueArrow
3/31/2003; 10:40:19 AM (reads: 1397, responses: 3)
Another comment with regard to the issue of performance you raised. This sort of reminds me of the various exception implementations of C++. VC++ implementation (which is based on the Windows structured exception handling) has a cost whether an exception is thrown or not. Metrowerks C++ OTOH chose a scheme that costs nothing if no exception is thrown. The price you pay is a very significant overhead if an exception is thrown.

I think the Metrowerks approach is better (putting aside compatibility issues) because exceptions are, after all, exceptional.

This, of course, is not the same as closures. I, for one, would use closures quit a bit if I had access to the feature. But I believe that the .NET team assumes that closures usage in C# would be limited, and I think their assumption is correct in this case. Being able to add this feature to C# without having to modify the VM or degrade the performance of existing code is therefore quit a win for them.

I not sure what Sam Ruby is referring to when he states that "The danger is that 20% of the time you will get a result that you didn't expect".

Ehud Lamm - Re: Environment, scripting, and behavior  blueArrow
3/31/2003; 11:51:08 AM (reads: 1444, responses: 1)
But I believe that the .NET team assumes that closures usage in C# would be limited, and I think their assumption is correct in this case. Being able to add this feature to C# without having to modify the VM or degrade the performance of existing code is therefore quit a win for them.

But obviously if using closures has a large overhead, you guarantee that their usage would be limited. It's a vicious circle.

Dan - Re: Environment, scripting, and behavior  blueArrow
3/31/2003; 12:30:35 PM (reads: 1431, responses: 0)
If I understand the setup right, the 20% problem comes in with the differentiation in .NET between value and reference types. (Or some such terminology)

Basically there are reference types, like objects, that live in the heap, and value types, like integers and structs, that live on the stack. If you look at Miguel's example, you can see where the problem lies. If you're closing over a reference type, everything works since you're just passing around a reference to a heap variable. If, however, you're closing over a value type you're not copying in a reference to the variable but rather the value of the variable. That means that if multiple closures are made over the same variables, they won't interact as they should for value types, but will for reference types.

There are probably other issues, but that's the big one that springs to mind right from the start.

Dan Shappir - Re: Environment, scripting, and behavior  blueArrow
4/1/2003; 2:08:56 AM (reads: 1454, responses: 0)
The question is, of course, how high an overhead.

People use high-level PL features all the time that have significant runtime overhead because they make the development process easier/faster. You might even say that this is true for PLs themselves.

As I have pointed out MS made numerous design decisions in this vain with the move from native win32 programming to .NET. The same can be said about Sun and the JVM and the various scripting languages out there.

I think that unless the overhead is exceptionally high (in which case articles will appear admonishing developers not to use this feature) this feature will be used. If developers see samples on MSDN showing how this can make their code short and cool, they will copy these samples.

Having support for closures where non existed before is IMO a GOOD THING. If lots of software will leverage this capability I'm guessing that MS will invest effort in improving performance.

Now if MS only adds tail recursion ...