Lambdas in Promise, like other languages, are anonymous functions and first-class values. They act as closures over the scope they are defined in and can capture the free variables in their current lexical scope. Promise uses lambdas for all function definitions, going further even than javascript which has both named and anonymous functions. In Promise there are no named functions. Just slots that lambdas get assigned to for convenient access.
Straddling the statically/dynamically typed divide by allowing arguments and return values to optionally declare a Type, Promise mimicks C# lambda syntax more than say, LISP, javascript, etc. A simple lambda example looks like this:
var i = 0;
var incrementor = { ++i; };
print incrementor(); // => 1
This declaration doesn't have any input arguments to declare, so it uses a shortform of simply assigning a block to a variable. The standard form uses the lambda operator =>, so the above lambda could just as well be written as:
var incrementor = () => { ++i; };
I'm currently debating whether I really need the =>. It's mostly that i'm familiar with the form from C#. But given that there are no named functions, parentheses followed by a block can't occur otherwise, so there is no ambiguity. So, i'm still deciding whether or not to drop it:
var x = (x,y) => { x + y };
// vs.
var x = (x,y) { x + y };
The signature definition of lambdas borrows heavily from C#, using a left-hand side in parantheses for the signature, followed by the lambda operator. Input arguments can be typed, untyped or mixed:
var untypedAdd = (x,y) => { x + y; };
var typedAdd = (Num x, Num y) => { x + y; };
var mixedtypeAdd = (Num x, y) => { x + y; };
In dynamic languages, lambda definitions do not need a way to express whether they return a value–there is no type declaration so whether or not to expect a value is convention and documentatio driven. In C# on the other hand, a lambda can either not return a value, a void method, which uses one of the Action delegates, or return a value and declare it as the last type in the declaration using the Func delegates. In Promise all lambdas return a value, even if that value is nil (more about the special singleton instance nil later). Values can be returned by explicitly using the return keyword, otherwise it defaults simply to the value of the last statement executed before exiting the closure. Since return values can be typed, we need a way to declare that Type. Unlike C#, our lambdas aren't a delegate signature, so instead of reserving the last argument Type as the return Type, which would be ambiguous, Promise uses the pipe '|' character to optionally declare a return type:
var returnsUntyped = (x,y) => { x + y; };
var returnsTyped = (x,y|Num) => { x + y; };
var explicitReturn = (|Num) => { returnsTyped(1,2); };
Lambdas can also declare default values for arguments, which can be simple values or expressions:
var simple = (x=2,y=3) => { x + y; };
var complex= (x=simple()) => { x; };
Promise supports three different method calling styles. The first is the standard parentheses style as shown above. In this style, optional values can only be used by leaving out trailing arguments like this:
var f = (x=1,y=2,z=3) => { x + y +z; };
print f(2,2,2); // => 6
print f(2,2); // => 7
print f(4); // => 9
print f(); // => 6
If you want to omit a leading argument, you have to use the named calling style, using curly brackets, which was inspired by DekiScript. The curly bracket style uses json formatting, and since json is a first-class construct in Promise, calling the function by hand with {} or providing a json value behaves the same, allowing for simple dynamic argument construction:
print f{y: 1}; // => 5
print f{z: 1, y: 1}; // => 3
var args = {z: 5};
print f args; // => 8
Finally there is the whitespace style, which replaces parentheses and commas with whitespace. This style exists primarily to make DSL creation more flexible:
print f 2 2 2; // => 6 print f 2 2; // => 7 print f 4; // => 9 print f; // => 6
Note the final call simply uses the bare variable f. This is possible because in Promise a lambda requiring no arguments can take the place of a value and accessing the variable executes the lambda. Sometimes it's desirable to access or pass a reference to a lambda, not execute it, in which case the reference notation '&' is needed. Using reference notation on a value is harmless (at least that's my current thinking), since Promise has no value types, so the reference of a value is the value:
var x = 2;
var y = () => { x+10; };
var x2 = &x;
var y2 = &y;
var y3 = y;
x++;
print x2; // => 3;
print y2; // => 13;
print y3; // => 12;
The output of y3 is only 12, because assignment of y3 evaluated y, capturing x before it was incremented.
As mentioned above, Lambdas can capture variables from their current scope. Scopes are nested, so a lambda can capture variables from any of the parent scopes
var x = 1;
var l1 = (y) => {
return () => { x++; y++; x + y; };
};
print l1(2); // => 5
print l1(2); // => 6
print x; // => 3
Similar to javascript, a block is not a new scope. This is done primarily for scoping simplicity, even if it introduces some side-effects:
() => {
var x = 5;
if( x ) {
var x = 5; // illegal
var y = 10;
}
return y; // legal since the variable declaration was in the same scope
};
As I've said that lambdas are the basic building block, meaning there is no other type of function definition. You can use them as lazily evaluated values, you can pass them as blocks to be invoked by other blocks and as I will discuss next time, Methods are basically polymorphic, named slots defined inside the closure of the class (i.e. capturing the class definition's scope), which is why there is no need for explicitly named functions.
This is a post in an ongoing series of posts about designing a language. It may stay theoretical, it may become a prototype in implementation or it might become a full language. You can get a list of all posts about Promise, via the Promise category link at the top.
Considering my previous rant about RIA platforms, I’m a bit slow out the gate with my Silverlight comments. But there was a lot to digest before making half-baked comments.
While I was at MEDC, Mix07 was going on next door. I didn’t even hear the cool Silverlight announcements until I got back from Vegas. But now that i’ve played with it, it’s exactly what I had hoped for (minus a disconnected use model): We have a true VM to code against on the client side. That means the full breadth of .NET languages to control the reduced WPF presentation layer, plus with the DLR true scripting support at near-compiled performance.
As I expected, there was no linux support announced by MS and neither does it appear that they’ve opened a channel to the mono team. But Miguel de Icaza has addressed this issue independently with the Moonlight project and listening to the chatter on the dev list and following the wiki updates, that project is getting serious attention. I may even be better this way. I think a firefox plug-in coming from the mono team would be more willingly installed by linux users than something coming directly from MS.
We’ll have to see how much more of the WPF set of Xaml gets supported by Silverlight as 1.1 moves to beta and RTM. Obviously, the way custom controls are done is not ideal right now–the way properties are acting against implementationRoot (haven’t gotten deep enough to understand why it’s not using the DependencyObject/Property pattern) and the shadowing of inherited properties just make for a strange experience compared to Controls in WPF, Windows Forms or even ASP.NET. Hopefully that morphs into a better model as we move along. If nothing else, the development of the promised suite of UI controls provide internal motivation to refine the model. Not that I think that DependencyObject/Property is an elegant coding pattern (at least not until that legwork moves into code generation).
But while everyone is busy committing the same UI crimes that many Flash developers have been guilty of for years, I think the real significance of Silverlight is not it’s Xaml and rich media support. In my opinion the most amazing feat of Silverlight is its DOM interoperation. The Silverlight VM is accessible in both directions, complete with object serialization across boundaries. This means you can have managed code attached to DOM events, and managed code modifying the DOM itself or calling javascript in the page. With a minimum of glue, you could move all your code inside of Silverlight and even if you don’t care about C# et al., you’d at least get a much higher performance javascript out of the deal. Then add the rich communications infrastructure and the hinted at socket level networking in future versions and suddenly you can have very fast, very interactive web applications that could be truly stateful and have better event handling for asynchronous operation etc.
Right now, you need some 1×1 pixel Silverlight object that everything gets channeled through, but MS has already promised that that dependency is going away. So what you really have is a VM and rich framework addressable with bytecode compiled from a huge number of potential languages in the browser. Whether you use that VM to drive your HTML, Silverlight’s presentation layer or even the canvas tag is up to you. It’s what I hoped that the browser manufacturers would do themselves, but as a plug-in, the chance of this capability becoming ubiquitous is even better, imho.
Silverlight 1.1 alpha is clearly a very early peek into the tech, but it works just great already. I’m curious what it will look like by the time it’s an official release. And I certainly hope that by that time, MS has given the disconnected, self-hosted option some consideration. After all, when competing with Flash/Flex, one shouldn’t ignore Apollo.
If you’ve had the misfortune of mentioning AJAX in my presence, then you’ve heard me rant about the crappy user experience we are all willing to accept in the name of net connectness. This really is a lamentation about the state of Rich Internet Application Frameworks and my dislike for coding in Javascript. Well, it looks like there are more choices than I’d been aware of (the choice of google search terms makes all the difference). Still not what I’d hope, but at least its getting more digestible.
Programming based on the AJAX technique has certainly done much to elevate the quality of web apps, but I still feel they are always just a pale facsimile of good old desktop apps. Even the best webapp UI is generally great “for a webapp”. However lots of libraries are emerging, as are s number of widget sets, so that’s definitely improving. While most toolkits let you extend them, you’re always doing your server in one language and your custom UI in javascript.
What I personally have hoped for was a VM in the browser that was addressable by a number of compilers creating bytecode. Everytime I see a platform that runs a VM underneath and doesn’t let you address that VM directly, I feel like a great opportunity has been missed. Oddly, MS’ CLR is the best example of a VM that lets you address it in virtually any language. They certainly didn’t invent the concept but they’ve promoted it. I think Sun did a major disservice to itself and VMs in general when they married Java the language, the Virtual Machine and the Religion into a single marketing entity. I mean who even knows that there are lots of languages that can be used to target the JVM?
A while ago I found a post by Brendan Eich talking about the future of the Mozilla VM and mentioned mono and the jvm as options. Yesterday, he posted about open web standards and I seized the opporunity to ask about bytecode addressability of JS2′s VM. His answer about legal issues is likely a big reason why mono was abandoned as an option:
“there won’t be a standard bytecode, on account of at least (a) too much patent encrustation and (b) overt differences in VM architectures. We might standardize binary AST syntax for ES4 in a later, smaller ECMA spec — I’m in favor.”
But as he also pointed out there is always compiling to Javascript instead of bytecode. The options he and another poster mentioned were:
Of the three I initially liked the Morfik approach the best, but doing a bit more research, they seem to be well on the path of propagating the same patent issues that Brendan Eich attributes the lack of standard VMs to. Pity.
Looking around for Javascript compiler’s I noticed that this approach is also under development at MS as Script# although it hasn’t yet moved up to an official MS project. Interestingly this does pit MS vs. Google once again, framed in a C# vs. Java context with ASP.NET AJAX w/ Script# and GWT. And if there’s anything that’s just as great for innovation as open standards, in my opinion, it’s competition between giants. I look forward to seeing them try to outdo each other.
So far, we’re stuck in the browser, and even with tabs, I sure hope this isn’t the future of applications. If we are to move beyond browser, what are our options?
Clearly, Adobe is leading the RIA platform wars with Flash and with Flex, SWF certainly looks more like a platform than an animation tool forced to render User Interfaces.
And Apollo certainly looks to push Flash as a platform as well as making it a stand-alone app platform. I certainly think this is going to be the juggernaut to beat. Given my dislike for the syntax of (Java|Ecma|Action)Script, it’s unlikely to be my platform of choice. And i don’t see a Adobe supporting cross-language compilation and support for Eclipse or Visual Studio at the expense of their Dev suite.
I really like the concept of WPF. It’s philosophy is what I want the future to look like. Mark-up and code separate, common runtime addressable in many languages on client and server, well developed communications framework. Ah, it warms my heart.
But, a) it’s closed, b) it’s only Windows (i’ll get to WPF/E in a sec) and c) boy, is it over-architected. Now, it’s at 1.0 release and if there’s anything about MS releases, they seldomly get it right in 1.0. We’ll see what 2.0 looks like.
WPF/E looks like a combination of simplifying WPF (is this 2.0?) and going after Adobe. And with Script# and recent admissions of some type of CLR on Mac for WPF/E, we’re looking at a trojan horse to get Rich Internnet Application Development in .NET established in both the browser and the desktop across platforms. Unfortunately, “across platforms” for MS still means Windows and Mac, while Adobe’s Flash 9 has demonstrated their dedication to encompass the linux sphere as well. I don’t think that’s going to change… I just don’t see MS going to linux with the CLR and I find the likelyhood of them leveraging mono‘s efforts just as unlikely. I wouldn’t mind being wrong.
This isn’t a platform per se, but I’ve seen a lot of cool tech demo’s using XUL and/or the canvas tag. Also looking at the work that Micheal Robertson’s AJAX13 has done, I think there are the makings of a stand-alone app platform here. If your runtime requirements are “install firefox, but you don’t even have to use it as your browser if you don’t want to”, that’s a pretty small barrier for a platform that runs everywhere. Personally, I hope someone straps mono or the recently liberated jvm to XUL and builds a platform out of it (you’d get mature WS communication for free with either), because of all the options that looks the most appealing to me personally.
Considering that GWT and Script# had eluded my radar up until today, I’m sure there’s even more options for RIA’s out there. I just hope that people developing platforms take the multi language lessons of the legacy platforms to heart. All the successful OS’s of the past offered developers many ways of getting things done. You looked at your task, picked the language that was the best fit to the task and your style of programming and you delivered your solution. VMs have shown that supporting many languages in an OS independent way is viable, so if you’re building a platform now, why would you choose to mandate a language and programming model. I sure hope that the reason for not going this route isn’t going to be “because the patent system is stopping me” — that would be the ultimate crime of a system that was supposed to foster innovation.