Method definitions in classes/objects

# Juan Ignacio Dopazo (13 years ago)

When checking what Traceur/TypeScript do when compiling method definitions I found both convert methods to assignments of an anonymous function. Traceur changed it recently (see code.google.com/p/traceur-compiler/issues/detail?id=127).

I was under the impression that methods would desugar to a named function with the same name as the property, but I checked the wiki and there is no reference to named functions. Has this been discussed? Is there consensus on anonymous/named?

Thank you,

# Erik Arvidsson (13 years ago)

On Sun, Oct 7, 2012 at 11:19 AM, Juan Ignacio Dopazo <dopazo.juan at gmail.com> wrote:

Hi!

When checking what Traceur/TypeScript do when compiling method definitions I found both convert methods to assignments of an anonymous function.

It is crucial that you do not do assignment because assignment has side effects, fails on non writable etc.

class B { set m(v) { throw Error() } }

class C extends B { m() { } }

I was under the impression that methods would desugar to a named function with the same name as the property, but I checked the wiki and there is no reference to named functions. Has this been discussed? Is there consensus on anonymous/named?

It was agreed that methods would desugar to a named function. It should be in the ES6 draft under Property Definition Evaluation but I don't understand in which step that is described. Allen can probably point out where propName gets added to scope.

# Allen Wirfs-Brock (13 years ago)

On Oct 8, 2012, at 7:41 AM, Erik Arvidsson wrote:

On Sun, Oct 7, 2012 at 11:19 AM, Juan Ignacio Dopazo ...

I was under the impression that methods would desugar to a named function with the same name as the property, but I checked the wiki and there is no reference to named functions. Has this been discussed? Is there consensus on anonymous/named?

It was agreed that methods would desugar to a named function. It should be in the ES6 draft under Property Definition Evaluation but I don't understand in which step that is described. Allen can probably point out where propName gets added to scope.

Concise methods are specified in section 13.3 of the current specification draft.

At a recent TC39 meeting we discussed the scoping of class names and decide that the class object (the constructor function) would use the same local binding rules for its name as is used by FunctionExpressions/FunctionDeclarations. Named classes defined using a ClassExpression have a local binding for the class name. NameClasses defined using a ClassDeclaration do not have such a local binding and instead capture the outer binding created by the declaration.

I don't believe that we have discussed, at a meeting, property name capture (other than WRT super) of ConciseMethod definitions. It is however, something that I have thought about quite a bit. Concise methods, as currently specified, do not create a local binding for the property name whose value is the function.

obj = { method () {} };

is (approximately) equivalent to

obj = {}; Object.defineProperty(obj,"method", {value: function() {}, enumerable: true, writeable: true, configurable: true});

rather than

obj = {}; Object.defineProperty(obj,"method", {value: function method () {}, enumerable: true, writeable: true, configurable: true});

I need to reconstruct all of the reasons for this. One is that method "names" are not restricted to being identifiers. They can also syntactically be strings, numbers, and at-names. A method name binding that capture a reference to the function also complicates the transfer of a super referencing method from one object to another.

However, these issues could be dealt with and and I've always seen this as a pretty close call. Are there strong use cases for giving methods a FunctionExpression-like binding of the property name?

# Erik Arvidsson (13 years ago)

On Mon, Oct 8, 2012 at 11:54 AM, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:

I don't believe that we have discussed, at a meeting, property name capture (other than WRT super) of ConciseMethod definitions. It is however, something that I have thought about quite a bit. Concise methods, as currently specified, do not create a local binding for the property name whose value is the function.

I think we talked about this when we talked about concise methods in object literals, before classes where approved.

A local binding would only be added of the name was an identifier

However, these issues could be dealt with and and I've always seen this as a pretty close call. Are there strong use cases for giving methods a FunctionExpression-like binding of the property name?

In classes I don't think it matters much, because it is most likely the wrong to use the function without this.

# Allen Wirfs-Brock (13 years ago)

On Oct 8, 2012, at 9:20 AM, Erik Arvidsson wrote:

On Mon, Oct 8, 2012 at 11:54 AM, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:

I don't believe that we have discussed, at a meeting, property name capture (other than WRT super) of ConciseMethod definitions. It is however, something that I have thought about quite a bit. Concise methods, as currently specified, do not create a local binding for the property name whose value is the function.

I think we talked about this when we talked about concise methods in object literals, before classes where approved.

A local binding would only be added of the name was an identifier

However, these issues could be dealt with and and I've always seen this as a pretty close call. Are there strong use cases for giving methods a FunctionExpression-like binding of the property name?

In classes I don't think it matters much, because it is most likely the wrong to use the function without this.

this that was definitely a factor in my choice of semantics:

//bad class foo { recursive(p) {return recursive(f(p))} }

//good class foo { recursive(p) {return this.recursive(f(p))} }

# Kevin Smith (13 years ago)

Also, if concise methods introduce a binding, then there's the hazard that an outer binding of the same name will get unintentionally shadowed.

# Brendan Eich (13 years ago)

Kevin Smith wrote:

Also, if concise methods introduce a binding, then there's the hazard that an outer binding of the same name will get unintentionally shadowed.

I have to agree with Kevin and I think Allen: the |this| binding requirement means defining the method name as a free variable misleads. It can only be used correctly in general after "this." or "other.", so we should not translate concise method definitions to property definitions of named function expressions.

# Allen Wirfs-Brock (13 years ago)

On Oct 8, 2012, at 10:54 AM, Brendan Eich wrote:

Kevin Smith wrote:

Also, if concise methods introduce a binding, then there's the hazard that an outer binding of the same name will get unintentionally shadowed.

I have to agree with Kevin and I think Allen: the |this| binding requirement means defining the method name as a free variable misleads. It can only be used correctly in general after "this." or "other.", so we should not translate concise method definitions to property definitions of named function expressions.

The current draft spec. does not introduce a binding for the method name and this thread did a good job of re-identifying the reasons. I doesn't sound like we should change the draft in this regard.

# Juan Ignacio Dopazo (13 years ago)

Thank you all!

At first I thought it made sense for debugging and recursive functions, but I agree that it'll be confusing and debuggers can infer a name.