ARGUMENTS.SHOULD.BE.ARRAY bug-fix

# Vassily Gavrilyak (19 years ago)

Spec states that arguments should be an object that delegates to Array.prototype So now actually argument will finally be array and used as such.

The question is - will the caller side of function arguments be fixed the same way. So the following code will work

function foo(){ alert(arguments.join()); }

foo.apply(this, [1,,2]); foo.call (this, 1,,2); this.fool(1,,2);

All 3 statements means the same and looks symmetrically, but second and third give compiler errors. Is that addressed too, so we will actually have arguments === Array?

, Vassily Gavrilyak

# liorean (19 years ago)

On 18/03/07, Vassily Gavrilyak <gavrilyak at gmail.com> wrote:

The question is - will the caller side of function arguments be fixed the same way. So the following code will work

function foo(){ alert(arguments.join()); }

foo.apply(this, [1,,2]); foo.call (this, 1,,2); this.fool(1,,2);

All 3 statements means the same and looks symmetrically, but second and third give compiler errors. Is that addressed too, so we will actually have arguments === Array?

Isn't the first more analogous to the following?

foo.call(this,1,undefined,2);
this.foo(1,undefined,2);

fn.apply destructures the array, with undefined taking place of elisions, into the arguments to send. The arguments array of the function activation is constructed from those sent arguments, not from the array sent to apply.

On the other hand I don't see why elisions in function calls would really be a problem...

# Vassily Gavrilyak (19 years ago)

On 3/18/07, liorean <liorean at gmail.com> wrote:

On 18/03/07, Vassily Gavrilyak <gavrilyak at gmail.com> wrote:

The question is - will the caller side of function arguments be fixed the same way. So the following code will work

function foo(){ alert(arguments.join()); }

foo.apply(this, [1,,2]); foo.call (this, 1,,2); this.fool(1,,2);

All 3 statements means the same and looks symmetrically, but second and third give compiler errors. Is that addressed too, so we will actually have arguments === Array?

Isn't the first more analogous to the following?

foo.call(this,1,undefined,2);
this.foo(1,undefined,2);

fn.apply destructures the array, with undefined taking place of elisions, into the arguments to send. The arguments array of the function activation is constructed from those sent arguments, not from the array sent to apply.

On the other hand I don't see why elisions in function calls would really be a problem...

David "liorean" Andersson


Es4-discuss mailing list Es4-discuss at mozilla.org, mail.mozilla.org/listinfo/es4-discuss

Yes, of course it's the same. But still two different cases to remember and deal with. One behavior will be more consistent and less things to think about.

Vassily Gavrilyak

# Brendan Eich (19 years ago)

The bug fix is clearly talking only about making arguments objects
delegate to Array.prototype. It's not talking about new syntax to
allow holes in actual parameter lists.

Note also how arguments' type may not be Array, but something
delegating to Array.prototype. We need to finalize the spec, but
already ES1-3 makes arguments a magic type that aliases arguments[0]
to a in function f(a){...}. That's not something Array instances can
do, and implementations take advantage of the fact that arguments
appears to be an Object with magic native getter and setter behavior.
Making arguments an Array would mean mixing in the magic, somehow. So
when I wrote that bug fix originally, I intentionally described the
fix as making the arguments object delegate to Array.prototype.

Holes in actual parameter lists are something I've never heard
requested, and people already "remember" how to pass parameters in
any C-like language. The issue is whether novices somehow might be
confused by the ability to write [1, , 3] but not f(1, , 3). I doubt
anyone would be much confused.

# Vassily Gavrilyak (19 years ago)

On 3/19/07, Brendan Eich <brendan at mozilla.org> wrote:

The bug fix is clearly talking only about making arguments objects delegate to Array.prototype. It's not talking about new syntax to allow holes in actual parameter lists.

Note also how arguments' type may not be Array, but something delegating to Array.prototype. We need to finalize the spec, but already ES1-3 makes arguments a magic type that aliases arguments[0] to a in function f(a){...}. That's not something Array instances can do, and implementations take advantage of the fact that arguments appears to be an Object with magic native getter and setter behavior. Making arguments an Array would mean mixing in the magic, somehow. So when I wrote that bug fix originally, I intentionally described the fix as making the arguments object delegate to Array.prototype.

The spec is clear, of course arguments can't be Array. They just "feels" as Array.

Holes in actual parameter lists are something I've never heard requested, and people already "remember" how to pass parameters in any C-like language. The issue is whether novices somehow might be confused by the ability to write [1, , 3] but not f(1, , 3). I doubt anyone would be much confused.

/be

Well, I sometimes get confused. It's very rare cases, but still happens to me. Don't remember any C-like language, but our cousin VBScript allows this. And those guys are sometimes confused too. Like here. www.thescripts.com/forum/thread91618.html That's 'very corner' case, but why not just fix it, if the fix will not break anything?

, Vassily Gavrilyak

# Brendan Eich (19 years ago)

On Mar 18, 2007, at 4:20 PM, Vassily Gavrilyak wrote:

Well, I sometimes get confused. It's very rare cases, but still happens to me. Don't remember any C-like language, but our cousin VBScript allows this. And those guys are sometimes confused too. Like here. www.thescripts.com/forum/thread91618.html

Thanks, good information.

That's 'very corner' case, but why not just fix it, if the fix will not break anything?

You're certainly right that this is a syntactic extension that won't
break any existing code. Jeff Dyer should comment, since he's the
grammar owner and has good taste ;-).

# Vassily Gavrilyak (19 years ago)

On 3/19/07, Brendan Eich <brendan at mozilla.org> wrote:

On Mar 18, 2007, at 4:20 PM, Vassily Gavrilyak wrote:

Well, I sometimes get confused. It's very rare cases, but still happens to me. Don't remember any C-like language, but our cousin VBScript allows this. And those guys are sometimes confused too. Like here. www.thescripts.com/forum/thread91618.html

Thanks, good information.

That's 'very corner' case, but why not just fix it, if the fix will not break anything?

You're certainly right that this is a syntactic extension that won't break any existing code. Jeff Dyer should comment, since he's the grammar owner and has good taste ;-).

/be

Thank you for considering this. While I can imagine why this functionality was disabled in ES1-3 (to protect programmer from misprints), in typed language typer could be responsible for handling this, not grammar. Well, let's wait for Jeff to comment.

Note also how arguments' type may not be Array, but something delegating to Array.prototype. We need to finalize the spec, but already ES1-3 makes arguments a magic type that aliases >arguments[0] to a in function f(a){...}.

So we have a magic that makes position->name transition for arguments.

We also have destructuring magic. Shouldn't we go further and add desctructuring magic to function call too? This way we will get named arguments functionality, and that's something that adds readability to code in some cases. We can do emulate it right now (and I already do it) with hashes. But having this magic in language will help to optimize such calls and add readability.

Example

function Person(name, age){ this.name = name; this.age = age; }

Now I can use it like person = new Person("Joe", 20)

But much readable that I prefer to use is person = new Person(name:"Joe", age:20);

I can simulate this with person = new Person({name:"Joe", age:20}) and pay performance penalty for readability, so my constructor will become something like this.

function Person(name, age){ if(typeof(name) == "object"){ var obj = name; this.name = obj.name; this.age = obj.age; }else{ this.name = name; this.age = age; } }

Again, not a big issue, but a little speed-up for correct and readable code will help. Probably named parameters were already considered, in this case I'm sorry for disturbing, just failed to find it in spec.

, Vassily Gavrilyak

# Jeff Dyer (19 years ago)

-----Original Message----- From: es4-discuss-bounces at mozilla.org [mailto:es4-discuss- bounces at mozilla.org] On Behalf Of Vassily Gavrilyak Sent: Monday, March 19, 2007 3:21 AM To: Brendan Eich Cc: es4-discuss at mozilla.org; liorean Subject: Re: ARGUMENTS.SHOULD.BE.ARRAY bug-fix

On 3/19/07, Brendan Eich <brendan at mozilla.org> wrote:

On Mar 18, 2007, at 4:20 PM, Vassily Gavrilyak wrote:

Well, I sometimes get confused. It's very rare cases, but still happens to me. Don't remember any C-like language, but our cousin VBScript allows this. And those guys are sometimes confused too. Like here. www.thescripts.com/forum/thread91618.html

Thanks, good information.

That's 'very corner' case, but why not just fix it, if the fix

will

not break anything?

You're certainly right that this is a syntactic extension that won't break any existing code. Jeff Dyer should comment, since he's the grammar owner and has good taste ;-).

/be

Thank you for considering this. While I can imagine why this functionality was disabled in ES1-3 (to protect programmer from misprints), in typed language typer could be responsible for handling this, not grammar. Well, let's wait for Jeff to comment.

I'm not sure the type system will help much since 'undefined' will silently convert to a value of most types. An argument list with holes looks like mistake to me. Why not force the user to say what he means?

Note also how arguments' type may not be Array, but something delegating to Array.prototype. We need to finalize the spec, but already ES1-3 makes arguments a magic type that aliases >arguments[0] to a in function f(a){...}. So we have a magic that makes position->name transition for arguments. We also have destructuring magic. Shouldn't we go further and add desctructuring magic to function call too? This way we will get named arguments functionality, and that's something that adds readability to code in some cases. We can do emulate it right now (and I already do it) with hashes. But having this magic in language will help to optimize such calls and add readability.

Example

function Person(name, age){ this.name = name; this.age = age; }

Now I can use it like person = new Person("Joe", 20)

But much readable that I prefer to use is person = new Person(name:"Joe", age:20);

I can simulate this with person = new Person({name:"Joe", age:20}) and pay performance penalty for readability, so my constructor will become something like this.

function Person(name, age){ if(typeof(name) == "object"){ var obj = name; this.name = obj.name; this.age = obj.age; }else{ this.name = name; this.age = age; } }

Again, not a big issue, but a little speed-up for correct and readable code will help. Probably named parameters were already considered, in this case I'm sorry for disturbing, just failed to find it in spec.

Named arguments has been discussed from time to time, but never had the support to become a serious proposal. Both proposals here are future proof and so I say let's hold off for now. We need to have something to talk about when edition4 is done :)

Any else think differently?

# Brendan Eich (19 years ago)

On Mar 19, 2007, at 11:10 AM, Jeff Dyer wrote:

Thank you for considering this. While I can imagine why this functionality was disabled in ES1-3 (to protect programmer from misprints), in typed language typer could be responsible for handling this, not grammar. Well, let's wait for Jeff to comment.

I'm not sure the type system will help much since 'undefined' will silently convert to a value of most types. An argument list with holes looks like mistake to me. Why not force the user to say what he means?

Agreed. The type checker is an optional strict mode, anyway, so it
can't help catch mistakes even if hole is not compatible with
undefined or other typed values.

Note also that holes in arrays mean the property need not be
allocated, which can save memory and survive hole-preserving
operations. Not so with actual parameters or the arguments object, at
least not in any implementation I know of. An arguments object is not
an Array.

Probably named parameters were already considered, in this case I'm sorry for disturbing, just failed to find it in spec.

Named arguments has been discussed from time to time, but never had
the support to become a serious proposal. Both proposals here are future proof and so I say let's hold off for now. We need to have
something to talk about when edition4 is done :)

Agreed. Waldemar had these at one point, but we need to finish soon,
so leaving things out is important -- especially when they can be
done by object initialiser argument passing and destructuring formal
parameters.

# Vassily Gavrilyak (19 years ago)

On 3/19/07, Brendan Eich <brendan at mozilla.org> wrote:

On Mar 19, 2007, at 11:10 AM, Jeff Dyer wrote:

Thank you for considering this. While I can imagine why this functionality was disabled in ES1-3 (to protect programmer from misprints), in typed language typer could be responsible for handling this, not grammar. Well, let's wait for Jeff to comment.

I'm not sure the type system will help much since 'undefined' will silently convert to a value of most types. An argument list with holes looks like mistake to me. Why not force the user to say what he means?

Agreed. The type checker is an optional strict mode, anyway, so it can't help catch mistakes even if hole is not compatible with undefined or other typed values.

Note also that holes in arrays mean the property need not be allocated, which can save memory and survive hole-preserving operations. Not so with actual parameters or the arguments object, at least not in any implementation I know of. An arguments object is not an Array.

Probably named parameters were already considered, in this case I'm sorry for disturbing, just failed to find it in spec.

Named arguments has been discussed from time to time, but never had the support to become a serious proposal. Both proposals here are future proof and so I say let's hold off for now. We need to have something to talk about when edition4 is done :)

Agreed. Waldemar had these at one point, but we need to finish soon, so leaving things out is important -- especially when they can be done by object initialiser argument passing and destructuring formal parameters.

/be

Thanks for all the clarifications. Resolving those two would make the language just perfect for me, but that would be too much :-) Good luck with deadline and my best wishes!

, Vassily Gavrilyak

# zwetan (19 years ago)

On 3/18/07, Brendan Eich <brendan at mozilla.org> wrote:

The bug fix is clearly talking only about making arguments objects delegate to Array.prototype. It's not talking about new syntax to allow holes in actual parameter lists.

nothing much to add but glad that this delegating is possible because of the genericity of those methods :)

cf "The splice function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method. Whether the splice function can be applied successfully to a host object is implementation-dependent." etc...

but still out of curiosity, in a case where someone would want to do the same kind of methods delegation but with non-generic methods (this value required to be of the original type) does ES4 offers some way of doing it ?

I'm thinking of reusing Date methods for examples in a "new" classes like DateTime, TimeSpan, etc... but Date methods require that the this value be the Date Object.

or another ex, like trying to inherit from the class String on the prototype cf

class String2 { prototype = new String();

//etc...
}

I know that String is final, but if someone want a Char class that is not provided by default, but which reuse almost all of the String Object methods, just applying it to 1 char, String being final is kind of painfull, a way to circumvent that would be welcome :).

oups sorry for the HT subject in this thread, or maybe this can be use cases ?

cheers, zwetan

ps: testing with Tamarin and Flex2 SDK