"Pretty" function expression names

# P T Withington (16 years ago)

Assuming we're allowed to speculate on futures here...

I was thinking about improving debug-ability by adding descriptive
names to function expressions thusly,

var myFun = function "my description here" (...) { ... };

I.e., be able to use an arbitrary string as the "name" of a function
expression. It seems to me this would be an unambiguous extension,
only giving up an unlikely syntax error. No runtime is required to do
anything with the name, although it would be encouraged to make it
available as the .name property of the function object. Comments?

# Michael (16 years ago)
# Mark Miller (16 years ago)

On Mon, May 4, 2009 at 11:12 AM, Michael <Michael at lanex.com> wrote:

From what I understand arguments.callee is going away. If that is the case, then from within that function how would I call it?

function "my description here" () {        ...        "my description here"(foo) };

That doesn't seem right, but maybe I'm overlooking something.

Indeed. PT's original example was:

var myFun = function "my description here" (...) { ... };

in which case you could call it as

myFun(foo)

(Note that this clarification should not be taken as an endorsement of PT's proposal. I don't yet know what I think of it.)

# Michael Haufe (16 years ago)

I apologize if this double posts, my other mail client seems a bit finicky.

# Brendan Eich (16 years ago)

On May 4, 2009, at 10:45 AM, P T Withington wrote:

Assuming we're allowed to speculate on futures here...

I was thinking about improving debug-ability by adding descriptive
names to function expressions thusly,

var myFun = function "my description here" (...) { ... };

Is this better for your purposes than

var myFun = function (...) { ... }; myFun.prettyName = "my description here";

# Mike Wilson (16 years ago)

Mark Miller wrote:

On Mon, May 4, 2009 at 11:12 AM, Michael <Michael at lanex.com> wrote:

From what I understand arguments.callee is going away. If that is the case, then from within that function how would I call it?

function "my description here" () {        ...        "my description here"(foo) };

That doesn't seem right, but maybe I'm overlooking something.

Indeed. PT's original example was:

var myFun = function "my description here" (...) { ... };

in which case you could call it as

myFun(foo)

I think Michael was referring to the fact that you can supply a local identifier on function literals, that can only be used inside the function body, typically used for recursion:

var myFun = function x() { x() };

This enables recursion independently of what external identifier the function is bound to, just like arguments.callee does.

Best Mike Wilson

# P T Withington (16 years ago)

On 2009-05-04, at 14:46EDT, Brendan Eich wrote:

On May 4, 2009, at 10:45 AM, P T Withington wrote:

Assuming we're allowed to speculate on futures here...

I was thinking about improving debug-ability by adding descriptive
names to function expressions thusly,

var myFun = function "my description here" (...) { ... };

Is this better for your purposes than

var myFun = function (...) { ... }; myFun.prettyName = "my description here";

Just that it's shorter and easier to type. It would be a shorthand
notation for setting the .name property of the function object
created. I wouldn't expect the function to be referenceable by the
name, but I'd want Function.toString to display it (as a string
literal).

# Brendan Eich (16 years ago)

On May 4, 2009, at 2:00 PM, P T Withington wrote:

On 2009-05-04, at 14:46EDT, Brendan Eich wrote:

On May 4, 2009, at 10:45 AM, P T Withington wrote:

Assuming we're allowed to speculate on futures here...

I was thinking about improving debug-ability by adding descriptive
names to function expressions thusly,

var myFun = function "my description here" (...) { ... };

Is this better for your purposes than

var myFun = function (...) { ... }; myFun.prettyName = "my description here";

Just that it's shorter and easier to type. It would be a shorthand
notation for setting the .name property of the function object
created. I wouldn't expect the function to be referenceable by the
name, but I'd want Function.toString to display it (as a string
literal).

As Michael Haufe and Mike Wilson point out, this might leave some
wanting to call the function by that name within its own body. I'm
interested in why you wouldn't care about that use case -- because you
can guarantee that myFun never varies?

An intrinsic name for toString and reflection is a fine thing, but
people tend to expect functions with names to be callable in some
scope. There's the rub.

I'm adding strawman and harmony pages to the wiki based on existing
discussions, so I'll roll up the function name proposal thread and add
this item. Thanks.

# P T Withington (16 years ago)

On 2009-05-04, at 17:39EDT, Brendan Eich wrote:

On May 4, 2009, at 2:00 PM, P T Withington wrote:

On 2009-05-04, at 14:46EDT, Brendan Eich wrote:

On May 4, 2009, at 10:45 AM, P T Withington wrote:

Assuming we're allowed to speculate on futures here...

I was thinking about improving debug-ability by adding
descriptive names to function expressions thusly,

var myFun = function "my description here" (...) { ... };

Is this better for your purposes than

var myFun = function (...) { ... }; myFun.prettyName = "my description here";

Just that it's shorter and easier to type. It would be a shorthand
notation for setting the .name property of the function object
created. I wouldn't expect the function to be referenceable by the
name, but I'd want Function.toString to display it (as a string
literal).

As Michael Haufe and Mike Wilson point out, this might leave some
wanting to call the function by that name within its own body. I'm
interested in why you wouldn't care about that use case -- because
you can guarantee that myFun never varies?

An intrinsic name for toString and reflection is a fine thing, but
people tend to expect functions with names to be callable in some
scope. There's the rub.

My real use case is passing an anonymous (non-recursive) function as
an argument. I don't actually know what identifier my function will
be bound to when it is called. If I need a recursive function and a
pretty name, presumably I could use either your proposal or:

let x = function "pretty name" () { ... x() ... }

I see that people might expect to be able to say:

"pretty name"()

but I wasn't asking for that. (OTOH, there is precedent for using
string literals for attribute names that are not valid identifiers.)

# Brendan Eich (16 years ago)

On May 4, 2009, at 2:58 PM, P T Withington wrote:

I'm adding strawman and harmony pages to the wiki based on existing
discussions, so I'll roll up the function name proposal thread and
add this item. Thanks.

Thanks!

strawman:name_property_of_functions

I did not reproduce all the details from the thread, but I tried to
capture the essential points. Please point out omissions and errors.
Thanks,

# John-David Dalton (16 years ago)

I just wanted to point out trac.webkit.org/changeset/42478. The changeset states: "This change adds the displayName property to functions, which when set overrides the normal name when appearing in the console."

  • John-David Dalton
# Mike Wilson (16 years ago)

P T Withington wrote:

Assuming we're allowed to speculate on futures here...

I was thinking about improving debug-ability by adding descriptive
names to function expressions thusly,

var myFun = function "my description here" (...) { ... };

I.e., be able to use an arbitrary string as the "name" of a function
expression.

I'd like to ask everybody what you see as the primary use- case for this function description? Examples (using ptw's syntax and disregarding current grammar issues):

function f() { function "local worker method in f"() {...} }

-or-

name1: { subname2: { fn: function "name1.subname2.fn"() {...} } }

For debugability I often miss support for the latter case. Could we possibly find cases when an automatically generated property could actually create this hierarchical name for us?

name1: { subname2: { fn: function() {...} } } var f = name1.subname2.fn f.prettyname == "name1.subname2.fn"

This would only solve some use-cases, but those would be solved with less keystrokes and effort, and without grammar changes.

All this may be way off from what is practical, but I just wanted to throw in that maybe the hierarchical naming scenario is one of the primary use-cases everybody is thinking of? Or maybe not?

Best Mike Wilson

# Lasse R.H. Nielsen (16 years ago)

On Mon, 04 May 2009 19:45:19 +0200, P T Withington <ptw at pobox.com> wrote:

Assuming we're allowed to speculate on futures here...

I was thinking about improving debug-ability by adding descriptive names to function expressions thusly,

var myFun = function "my description here" (...) { ... };

I.e., be able to use an arbitrary string as the "name" of a function expression. It seems to me this would be an unambiguous extension, only giving up an unlikely syntax error. No runtime is required to do anything with the name, although it would be encouraged to make it available as the .name property of the function object. Comments?

I think this is an attempt at combining two features into one (syntactic) field. The function name (the identifier after "function") allows you to bind a name to the function for recursive use. The string suggested here allows you to add a description, not a name.

While a description is nice for debugging, it's not the same as a name, not even a descriptive name.

If a description is wanted, I would prefer something similar to the the elisp way of doing it. If the first statement of the function body is a string literal, it is the description.

I.e., function foo(bar, baz) { "Way to foo the bar and baz"; // body }

This has the advantage of allowing descriptions and names on the same functions, and it is just as easily represented in the function's toString representation. Even internal functions can use it:

String.prototype.toString.toString() ->
'function toString() { "String.prototype.toString"; [ native code ] }'

You might then access it as functionRef.description (or something similar).

On the other hand, this is also just using one syntactic feature (string literal) for another purpose: a special type of comment.

It will allow a debugger to show different names for similarly named functions, e.g. {Object, String, Number, Boolean, Date, RegExp}.prototype.toString, which all have the exact same display now: function toString() { [native code] } (from Firefox).

On the other hand, nothing prevents an implementation from doing that already (it's already valid syntax, and only a small change of toString is needed to print it out). It's only a standardized accessor for the description that is missing.

# Laurens Holst (16 years ago)

Brendan Eich schreef:

strawman:name_property_of_functions

I did not reproduce all the details from the thread, but I tried to capture the essential points. Please point out omissions and errors. Thanks,

What I’m missing about Function.name is that you can only specify it using function literals (at least, currently in Firefox I think that is the case). It would be nice if you could also either set this with either the Function constructor, or after the object has been created.

This is functionality that is currently missing, so that function constructors are second-class citizens compared to function literals. (By the way, while you’re at it, it would be nice if the constructor also allowed closures to be specified, because that is also something functions created with the Function constructor unfortunately cannot do).

Also, it would be nice if when a function is declared as follows:

yyy.xxx = function() { … }

yyy = { xxx: function() { … } }

That in both these cases the function’s name property would be ‘xxx’ as well.

Both these would aid debuggability of functions. Currently we have code that looks like this to aid stack trace debugging:

xx.core.Events.createEvent = function xx_core_Events_createEvent() { … }

This makes the function show up with the name ‘xx_core_Events_createEvent()’ instead of ‘anonymous()’ in Firebug, which I guess is an improvement, but I think this is a terribly ugly way to go about it :). So it would be nice if I could just leave the name out and it would still show up as ‘createEvent()’ (I can make do without the xx.core.Events part).

~Laurens

# Laurens Holst (16 years ago)

Laurens Holst schreef:

Brendan Eich schreef:

strawman:name_property_of_functions

I did not reproduce all the details from the thread, but I tried to capture the essential points. Please point out omissions and errors. Thanks,

What I’m missing about Function.name is that you can only specify it using function literals (at least, currently in Firefox I think that is the case). It would be nice if you could also either set this with either the Function constructor, or after the object has been created.

Ah, I see this part is already covered by Maciej’s Function.create semi-constructor proposal. In that case, should make sure this Function.create also supports passing closures so that we won’t need a Function.create2 :). Maybe make the params parameter list an array so that create is less dependant on the length of the arguments passed and more extensible.

~Laurens

# Brendan Eich (16 years ago)

On May 10, 2009, at 2:25 PM, Laurens Holst wrote:

Laurens Holst schreef:

Brendan Eich schreef:

strawman:name_property_of_functions

I did not reproduce all the details from the thread, but I tried
to capture the essential points. Please point out omissions and
errors. Thanks,

What I’m missing about Function.name is that you can only specify
it using function literals (at least, currently in Firefox I think
that is the case). It would be nice if you could also either set
this with either the Function constructor, or after the object has
been created.

Ah, I see this part is already covered by Maciej’s Function.create
semi-constructor proposal. In that case, should make sure this
Function.create also supports passing closures so that we won’t need
a Function.create2 :).

Why would we ever want to mutate a closure? Please re-read

esdiscuss/2009-March/008940

Maybe make the params parameter list an array so that create is less
dependant on the length of the arguments passed and more extensible.

This sounds like a good idea to me. The counter-argument is the
obligatory overhead of an array of parameter names. Others should
weigh in.

One good thing about your proposal: it avoids (or fails to reuse, on
the down side) quirky standard behavior of the Function constructor.
Did you know ES1 specifies that new Function("a,b", "a+b") creates a
function similar to function anonymous(a, b) { return a + b; }? That
string-pasting feature of the Function constructor would seem to carry
over to Function.create, at first glance.

# Laurens Holst (16 years ago)

Brendan Eich schreef:

What I’m missing about Function.name is that you can only specify it using function literals (at least, currently in Firefox I think that is the case). It would be nice if you could also either set this with either the Function constructor, or after the object has been created.

Ah, I see this part is already covered by Maciej’s Function.create semi-constructor proposal. In that case, should make sure this Function.create also supports passing closures so that we won’t need a Function.create2 :).

Why would we ever want to mutate a closure? Please re-read

esdiscuss/2009-March/008940

I’m not sure how that message applies to what I had in mind when writing the above sentence… We are probably talking about different things, I might have used the term ‘closure’ incorrectly.

If a free variable is used in a function literal it will look it up in the local scope of the enclosing function, effectively allowing you to pass a variable to a function at the time it is created which will be available at all invocations. This is not possible with a function constructor.

So it would be nice if you could do something like this:

function a() { var x = 1; return function y(z) { return x + z; } } var y = a(); y(2);

…by using a function constructor:

function a() { var x = 1; return Function.create('y', ['z'], {x: x}, 'return x+z;'); } var y = a(); y(2);

Or perhaps you would rather want to pass a reference to the local scope (‘arguments’?) instead of an individual variables.

Now probably closures do not work exactly in this fashion, but this is just something else that functions literals can do and functions constructors currently can’t, making the latter a second-class citizen.

Maybe make the params parameter list an array so that create is less dependant on the length of the arguments passed and more extensible.

This sounds like a good idea to me. The counter-argument is the obligatory overhead of an array of parameter names. Others should weigh in.

One good thing about your proposal: it avoids (or fails to reuse, on the down side) quirky standard behavior of the Function constructor. Did you know ES1 specifies that new Function("a,b", "a+b") creates a function similar to function anonymous(a, b) { return a + b; }? That string-pasting feature of the Function constructor would seem to carry over to Function.create, at first glance.

Yep. Crazy! :)

~Laurens

# Brendan Eich (16 years ago)

Sorry, your use of closure was unclear enough that I went with door #1
(mutating a closure by giving it an intrinsic name). I did wonder if
you meant door #2 (creating an inner scope function other than by
eval), and you did, so let's deal with that:

On May 10, 2009, at 4:20 PM, Laurens Holst wrote:

…by using a function constructor:

function a() { var x = 1; return Function.create('y', ['z'], {x: x}, 'return x+z;'); } var y = a(); y(2);

No, that would not be nice. Consider the case where the created
function mutates x. Consider obfuscation or infeasible-to-analysis
arbitrary computation of the string parameters to Function.create, or
even of the reference to Function.create that function a calls.

Only eval has to exact the stupid-taxes here. Let's not have another
set of tax-hikes.

Or perhaps you would rather want to pass a reference to the local
scope (‘arguments’?) instead of an individual variables.

Write a closure, or pay the eval tax. Why should Function.create make
inner-scope closures? What is the real-world use case that can't use
eval?

# Dan Tsimbala (16 years ago)

On the other hand, this is also just using one syntactic feature (string literal) for another purpose: a special type of comment.

So why not do it as the first comment of the function, like Python does. String literal seems strange. But in any case I like this idea more than descriptive names.

The only problem for me is that it might overlap with for example JSDoc comments, and with string literal you can't do anything about it.

# Dan Tsimbala (16 years ago)

Just have remembered that Python has doc string, so it's not actually a comment. Is the problem about using comment for such purposes in parsing procedure? (that it ignores whitespace and comment tokens)