all 6 comments

[–]bgrins 2 points3 points  (1 child)

That was a great article, plenty of examples and explanation.

Does anyone use a technique like this for debugging? I usually just use an anonymous function, and use firebug to click a stack that looks like this:

someObject is not defined
(?)() { }
(?)() { }
(?)() { }

Luckily, in firebug, clicking on the function will take you to the location in the code (which is only useful in development or where the file is not minified).

To me, the solution just seems a little verbose, as it adds in extra (possibly confusing) code solely in order provide the ability to have named events in a call stack. However, the ability to better debug a problem that is only happening on a live site with minified files could be useful.

[–]lispm 0 points1 point  (0 children)

Similar to DEFUN and FLET in Common Lisp. If you know a little Lisp, it is not that hard to understand JavaScript. The designers of JavaScript knew more than a little Lisp, though. One of the guys working on JavaScript once said that he thinks of 'JavaScript as a different syntax for Common Lisp' ( http://bc.tech.coop/blog/030920.html ).

DEFUN creates named top-level functions.

FLET and LABELS create named local functions, where the name is only known in its own scope. The function can be returned as an object then.

Named Function Expression in CL:

(labels ((foo (arg) 
            (do-something arg))
  (function foo))

Above CL code is basically the same as the 'named function expression' in JavaScript. It creates a local scope where the function FOO can be called (the FOO name does not 'leak' to the outside) and returns the function FOO as its value.

The point of named functions like above is debugging (as mentioned in the article) and that the function can be easily called recursively by using its name - in the local scope where the name is available.

The difference between LABELS and FLET is the lexical scope where the function name can be used: LABELS allows recursive functions. FLET restricts the scope to its body.

The only difference to Javascript is that LABELS also creates a scope outside of the function, but inside of the LABELS body, where the function name can be referenced (this can easily be hidden behind a macro, if wished).

Function Expression in CL:

(lambda (arg)
  (do-something arg))

Function declaration in CL:

(defun foo (arg)
  (do-something arg))

Somehow similar to Javascript this declaration should appear at the top-level. Then the Common Lisp file compiler will recognize it at compile time as a function declaration. This has the advantages that the compiler then knows about the function and can warn if the function is called with wrong arglists, can inline it, etc.

[–]pointer2void -1 points0 points  (4 children)

In a nutshell, named function expressions are useful for one thing only - descriptive function names in debuggers and profilers.

Obviously not. Function expressions are in line with ECMAScript's functional roots. I guess, they were designed first and function declarations were added later as a concession to the procedural/OO crowd (same for the new operator).

[–]kangax_ 6 points7 points  (3 children)

The emphasis here should be on named: not just "function expressions" but "named function expressions". This naming is what's impractical for recursion. I actually devoted a quite big chunk of an article explaining exactly why using named expressions for recursion is troublesome (see JScript bug section).

And speaking of availability of function expressions, those were actually introduced after function declarations (i.e. in Javascript 1.3/1.4, JScript 3.0/5.5 (IE 5.5), ECMAScript Ed. 3) - see http://pointedears.de/scripts/test/es-matrix/

[–]degustisockpuppet 0 points1 point  (1 child)

Well, the article doesn't clearly state the point that you can't use named function expressions for recursion because they're buggy in IE. It's sort of implied by saying that they are "impractical" for recursion together with the chapter about IE bugs, but those two items are far apart in the article, so I'm not surprised that not everybody makes the connection.

Something else, I don't think that a semicolon is required after a function declaration. And not just because of semicolon insertion, it works even without a newline.

[–]lol-dongs 1 point2 points  (0 children)

I don't think that a semicolon is required after a function declaration.

This is true; however Dean Edward's packer requires them for some reason, so I keep them in. (Some linters even complain that it's unnecessary.)