Bait taken: Arguments about arguments

Brendan Eich brendan at
Fri Jan 9 13:58:49 PST 2009

On Jan 8, 2009, at 10:17 PM, Mark S. Miller wrote:

> In other words, in exactly these functions, snapshot arguments  
> eagerly into a genuine array, and then replace all further uses of  
> arguments with the variable holding that snapshot. It's not quite a  
> source-to-source translation, since additional magic is required for  
> a free 'arguments' within an eval()ed script to address t1 rather  
> than L2's "arguments", which doesn't exist in L1. Actual  
> implementations can be more efficient than this, but this transform  
> is adequate to demonstrate lack of burden.

This is all onerous turd-polishing. It adds code bloat, memory-unsafe  
implementation language usage attack surface, and memory bloat to the  

It also penalizes strict mode performance unless the implementator  
sink yet more optimization cost (with attendant code/data/attack- 
surface bloat) into this corner case. Why is that a good thing?

Your explicit desire to make strict mode the new language everyone  
uses to write new code seems to me (a) quixotic; (b) wasteful of  
energy better spent on getting rest args and the spread operator into  
the language after 3.1.

I could be wrong about (a), but we can lay bets on the side. We should  
not be gambling in the 3.1 spec in the very little time remaining, and  
in the face of dissent from at least two (perhaps three if Pratap has  
joined Maciej and me now) implementors.

> Re #2: If foo is a strict function, then foo.arguments throws an  
> error. So the only functions where we need this eager creation are  
> those that either need arguments anyway, or those that directly use  
> the eval operator, both of which are statically visible.

Maciej's original (see 
5) was more qualified than my summary of it:

"2) arguments ever being a static array is problematic; unless  
function.arguments is banned for functions with those semantics, it  
would force a copy of the arguments to be made eagerly on entry to  
such a function, if the requirement is to provide the original  
arguments. If the requirement were "value of the arguments at the time  
the arguments property is retrieved" it would not be so bad, but kind  
of a weird semantic. "

Let's separate foo.arguments from the eager (eager enough) Array  
creation and freezing issue. Item #2 is an objection to eager Array  
instance creation and freezing for any strict mode function that uses  
arguments freely in its body.

> Re #3: Actual use of arguments aliasing is very rare. (Re bait,  
> compare to the frequency of feature testing.)

There's no point asserting "very rare" without evidence. Aliasing is  
required for web compatible JS engines to compete in the market --  
Google as well as Apple and Mozilla can testify to this. The question  
is why would you make "use strict" a non-starter for anyone without  
the time to do alias analysis on existing non-trivial code that would  
otherwise benefit from strict mode?

> We freeze arguments so most actual uses of such aliasing will result  
> in noisy failures.

Depending on code coverage!

> Probably much current aliasing is more of a source of buggy behavior  
> than a feature used intentionally.

Another guess/assertion, but browser vendors cannot compete without  
supporting aliasing. This suggests (but of course doesn't prove) that  
"use strict" should not ban it.

This migration tax issue is secondary, a sideshow, since I'm not  
confident "use strict" will take over (I hope it will; Perl's use  
strict; gives us hope on this count; but as I keep warning, too much  
gratuitous and puristic difference will make strict mode a dead  
letter, or less used than you hope). The main objection is the first  
one: implementation complexity burden.

> It is good if strict mode exposes bugs in ported programs. New  
> programmers should learn the strict language first or only, so we  
> want to remove such landmines from it. Intentional use of aliasing  
> is probably about as common as intentional use of implicit wrapping,  
> and so your #3 would equally argue against the happy bug fix  
> agreement we just had.

No, those are different cases, requiring different arguments and not  
wishful thinking or assertions. In particular, we can't get rid of  
primitives and wrappers from the strict language, even if we avoid  
implicit wrapping when |this|-binding (computing Reference bases). We  
agree trying to do that breaks too much code (e.g., code that object  
detects a property on a primitive, or makes an explicit wrapper to  
amortize implicit wrapping costs in certain implementations).

> Btw, I very clearly remember you agreeing in Kona that we should  
> freeze strict arguments for this reason. I raise this not to start a  
> "But you said. No you said" loop, but in hopes of jogging your  
> memory. Do you remember this?

I am 100% certain that I objected to making strict-mode arguments be  
an actual Array instance. Do you remember this?

I also remember thinking through, and talking about, how  
implementations that avoid creating an arguments object at all, e.g.  
for arguments.length or arguments[i] expressions where i was constant  
or could be bounded, could probably tolerate an "if (strict) throw"  
addition to their custom setters or [[Put]] implementations.

Allowing strict errors on writes to arguments[i] addressed one aspect  
of freezing, but I did not agree that aliasing was entirely out, for  
the simple reason that I'm not certain aliasing via assignment to  
formal parameters and reading back via arguments[i] is not the hard  
case to keep working when adding "use strict" to existing codebases.

Really, we need more evidence, which could only be gained by trial  
implementation and significant user testing.

The major bone of contention is whether strict mode should change  
arguments from its magic object nature in ES1-3 to an Array instance.  
Let's defer arguing about freezing (which may be ok as I allowed at  
Kona) until we get past this disagreement.

But to return to the highest priority point: browser implementors are  
telling you they do not want to make two arguments implementations.


More information about the Es-discuss mailing list