What Are "Anonymous Functions" In JScript?

What Are "Anonymous Functions" In JScript?

Rate This
  • Comments 9

One of our excellent customer support staff in the United Kingdom asked me this morning what "anonymous functions" are in JScript.

 

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 JScript:

 

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, JScript 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 JScript 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.) 

 

Anyway, I'll discuss other functional language properties of JScript 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 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 IE 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.

 

But I digress. When you have a button in IE

 

<BLAH BLAH BLAH NAME="BUTTON1" ONCLICK="window.alert('Oooh, you clicked me!');" >

 

then 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 IE assigns it to the button's onclick property.  Again, this is a non-anonymous function named "anonymous".

 

 

  • // Closures are your friend 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. Note that often closures are NOT YOUR FRIEND. There are serious memory-leaking scenarios associated with improper use of closures.
  • Thanks for the interesting read. I've passed around JScript function references, but had no idea they worked in this manner. Good stuff. One question regarding JScript as a "functional" language. I know the definition of functional languages is vague, but I've always thought of functional languages as being like Haskell, or even XSLT, where the emphasis is on expression evaluation without side-effects: http://www.cs.nott.ac.uk/~gmh//faq.html Am I thinking of the wrong "functional" in this case? Thanks again!
  • You're thinking of the right thing -- Haskell is a functional language. By "functional" I 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. JScript provides you the tools necessary to do functional programming, so it is a functional language. Now, most people treat JScript as a procedural language or an object oriented language, but that doesn't mean that it isn't also a functional language!
  • I didn't think your examples really made clear the utility of anonymous functions. One common usage that seems more illustrative is this:

    [given an array A of objects, each with property x]
    A.sort(function(a,b){return a.x<b.x?-1:1})
  • 2003/09/12 What's Up With Hungarian Notation? 2003/09/12 Eric's Complete Guide To BSTR Semantics 2003/09/12...
  • This is kind of unrelated...but I'm wondering about anonymous functions in C#.

    In the code below, isn't the primative value type "int x" 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; };

    }

    }

  • The local is hoisted so that it becomes a member of the class.  That is, your code is equivalent to

    class program {

    // ...

    private class Locals {

    public int x;

    public int M() { ++x ; return x; }

    }

    static void SetupDelegate() {

    Locals locals = new Locals();

    locals.x = 5;

    d = locals.M;

    }

    See my recent posts about C#/VB closures for more details.

Page 1 of 1 (9 items)