Thursday, March 04, 2010

A few weeks ago, some of my colleagues and I were discussing the idiosyncrasies of various programming languages (as we often find ourselves doing—we’re kind of geeky that way), when one of us pointed out that the following code is completely valid C++0x syntax:

[](){}();

The “operator soup”1 above defines a C++ lambda expression (denoted by the square brackets) which declares no parameters (the first empty parentheses) or body (the empty curly braces) and is immediately invoked (the final parentheses). Conceptually, this is a nop—an empty lambda that is immediately invoked.

We found ourselves fascinated by this idea of a do-nothing lambda, and went ahead to define the same thing in our respective languages. Our first attempt was C#.

() => { }();

While the code above looks quite pretty, it’s not exactly legal. In C#, lambdas must always have an explicit delegate type, so an ugly type-cast is required in order to compile:

((Action)(() => { }))();

Sigh, so close, yet so dissatisfying!

The stronger notion of type inference in F# allows for much more succinctness.2

(fun () -> ())()

However, my favorite version is written in Visual Basic 10.

Call (Sub() Exit Sub)()

What it lacks in succinctness,3 it makes up for with human-readable clarity.

 

How do you write a do-nothing lambda in your language?

 

1One could also declare the square brackets with either an = or & operator inside to define how variables that are declared in the same scope as the lambda are captured within the lambda function’s closure. It’s amazing how much one can do without typing a single identifier character!

[&](){}();

2Note that the F# example contains a subtle difference from the others in that it returns a value of type Unit. This implies that the entire F# expression could be passed as an argument to another function, but that is not true of the other examples.

3Though it’s the same size as the C# version when unnecessary whitespace characters are removed.

posted on Thursday, March 04, 2010 7:42:19 AM (Pacific Standard Time, UTC-08:00)  #    Comments [14]

kick it on DotNetKicks.com
Thursday, March 04, 2010 8:01:51 AM (Pacific Standard Time, UTC-08:00)
Ruby 1.8:

lambda{}.call

And yes it works in IronRuby ;)
Thursday, March 04, 2010 8:11:39 AM (Pacific Standard Time, UTC-08:00)
JavaScript:
(function(){})();

Function.call(); //returns an anonymous, empty function. Which is interesting, I wasn't expecting that.
Thursday, March 04, 2010 8:16:48 AM (Pacific Standard Time, UTC-08:00)
There's a bug in the C# sample. You should cast that to (InAction). *ducks*
Thursday, March 04, 2010 8:23:28 AM (Pacific Standard Time, UTC-08:00)
CoffeeScript:

(->)()

Just the empty lambda, without invoking it:

->
Thursday, March 04, 2010 8:24:34 AM (Pacific Standard Time, UTC-08:00)
(lambda ()) Scheme
josh
Thursday, March 04, 2010 8:27:25 AM (Pacific Standard Time, UTC-08:00)
I prefer the pragmatist's empty lambda, should work in any language:
Thursday, March 04, 2010 8:36:24 AM (Pacific Standard Time, UTC-08:00)
In case you want an operator soup, the F# example can be easily extended (ad infinitum):

(fun _ -> ())([|()|])
_
Thursday, March 04, 2010 8:46:56 AM (Pacific Standard Time, UTC-08:00)
Haskell:

(\()->())()
ShinNoNoir
Thursday, March 04, 2010 9:09:34 AM (Pacific Standard Time, UTC-08:00)
Groovy:

{}
AeonFlux
Thursday, March 04, 2010 9:16:54 AM (Pacific Standard Time, UTC-08:00)
Perl:
sub{}->();
Thursday, March 04, 2010 9:17:50 AM (Pacific Standard Time, UTC-08:00)
Scala:

(() => ())()
AeonFlux
Friday, March 05, 2010 5:29:57 AM (Pacific Standard Time, UTC-08:00)
Python:
(lambda : None)()
Friday, March 05, 2010 7:38:45 PM (Pacific Standard Time, UTC-08:00)
Now you just need a catchy title for your exercise. How about "Shut Up, World" or "Ninjas: They're Everywhere, World" ?
Brian Hartung
Tuesday, March 09, 2010 11:19:51 AM (Pacific Standard Time, UTC-08:00)
Call Sub() Return

What it lacks in human-readable clarity, it makes up for with succinctness :)

Turns out 4 of the parens are unnecessary. That makes 17 to C#'s 24, check-and-mate, sir!

Comments are closed.