A member of our excellent customer support staff in the United Kingdom asked me this morning what “anonymous functions” are in JavaScript. It’s a little complicated. Two things come to mind: realio-trulio anonymous functions, and what we used to call “scriptlets”.
First up are actual anonymous functions — functions which do not have names are, unsurprisingly enough, called “anonymous functions”.
“What the heck do you mean, functions without names?” I hear you ask. “Surely all functions have names!” — well, no, actually, some don’t. This is perfectly legal in JavaScript:
print(function(x) { return x * 2; } (3) );
That prints out “6”. What’s the name of that function? It has no name. Of course, we could give it one if we chose. This is exactly the same as declaring a named function:
function double(x) { return x * 2; } print(double(3));
But functions don’t need names any more than strings or numbers do. Functions are just functions whether they’re named or not.
Remember, JavaScript is a functional language: functions are objects and can be treated like any other object. You don’t have to give an object a name to use it, or you can give them multiple names. Functions are no different. For example, you can assign them to variables:
var myfunc = function(x) { return x * 2; } var myfunc2 = myfunc; print(myfunc(3));
Those of you who are familiar with more traditional functional languages, such as Lisp or Scheme, will recognize that functions in JavaScript are fundamentally the lambda calculus in fancy dress. (The august Waldemar Horwat — who was at one time the lead Javascript developer at AOL-Time-Warner-Netscape — once told me that he considered Javascript to be just another syntax for Common Lisp. I’m pretty sure he was being serious; Waldemar’s a hard core language guy and a heck of a square dancer to boot.) I’ll discuss other functional language properties of JavaScript in a future post.
One can also construct anonymous functions at runtime with the Function
constructor, though why you’d want to is beyond me:
print(new Function("x", "return x * 2;")(3));
I recommend against constructing new functions at runtime based on strings, but that’s also a subject for a future post.
Interestingly enough, what this does internally is constructs the following script text, and compiles it:
function anonymous(x) { return x * 2; }
So in fact, this actually does not compile up an anonymous function — it compiles up a non-anonymous function named “anonymous”! The mind fairly boggles.
Second, there are the “anonymous functions” constructed when the browser builds an event handler.
Aside: In the source code for the script engine these things are called “scriptlets”, which is a terrible, undescriptive, confusing name. At one point there were three technologies all competing for the name “scriptlet”. The technology presently known as Windows Script Components was originally called “Scriptlets”, which explains the name of the Wrox book “Instant Scriptlets” — they published based on a beta released before the name was finalized. We considered calling Windows Script Components “Scriptoids” and “Script Thingies”, but fortunately cooler heads prevailed.
I digress. When you have a button in IE with an event handler, the script engine creates a separate compilation scope for the form and compiles up this string:
function anonymous() { window.alert('Oooh, you clicked me!'); }
It then passes the function object back as a dispatch pointer and the browser assigns it to the button’s onclick
property. Again, this is a non-anonymous function named “anonymous”.
Some comments from readers:
You can also use anonymous functions to make closures:
function MakeAdder(a) { return function(b) { return a + b; } } var Add7 = MakeAdder(7); var Add13 = MakeAdder(13); WScript.Echo(Add13(Add7(22)));
Indeed, that is a subject for another posting. Though I note that closures are sometimes not your friend; there are memory leaks associated with closures in some scenarios.
I’ve always thought of functional languages as being like Haskell, or even XSLT, where the emphasis is on expression evaluation without side-effects
By “functional” in this context I just mean “functions are first class objects”. Now, one can certainly argue that so-called “pure” functions are, well, pure. You know, the way, the truth, the light, all that good stuff. The notion that there is a right way and a wrong way to design functions is certainly endemic to users of more traditional functional languages like Scheme, ML, Haskell, etc.
Here’s another way to think about it — “functional programming” is writing programs in functional style: no side effects, etc, etc, etc. A “functional programming language” is a language in which one can do functional programming.
JavaScript provides you the tools necessary to do functional programming, so it is a functional language. Most people treat JavaScript as a procedural language or an object oriented language, but that doesn’t mean that it isn’t also a functional language!
Here’s an example that shows the true utility of anonymous functions:
A.sort(function(a,b){return a.x<b.x?-1:1})
That’s a great point; the nice thing about anonymous functions is that you can express an intention close to where it is being used.
I’m curious about how anonymous functions work in C#. In the code below, isn’t the value type int stack-allocated by the runtime thereby allowing you to change the value of a non-existent stack variable by executing the code below?
class Program { delegate int TestDelgate(); private static TestDelgate d; static void Main(string[] args) { SetupDelegate(); Console.WriteLine(d().ToString()); Console.WriteLine(d().ToString()); Console.WriteLine(d().ToString()); Console.ReadKey(); } static void SetupDelegate() { int x = 5; d = delegate() { ++x; return x; }; } }
First, the notion that integers are allocated “on the stack” is a common misperception. An array of integers is not allocated on the stack, and an integer field of a class is not allocated on the stack. The reason why locals are allocated on the stack is because usually their lifetimes are short; in this case, the lifetime of the local is not short, and so it is not allocated on the stack! The local is hoisted to be a field of a class, and is therefore allocated off the heap. That is, your code is equivalent to:
class Program { [...] private sealed class Locals { public int x; public int M() { ++x ; return x; } } static void SetupDelegate() { Locals locals = new Locals(); locals.x = 5; d = locals.M; } [...]
Pingback: Porting old posts, part 1 | Fabulous adventures in coding