Re: Notes from Monday's meeting with TC39 folks

On Oct 8, 2009, at 1:00 AM, Maciej Stachowiak wrote:

> On Oct 7, 2009, at 11:46 PM, Brendan Eich wrote:
>
>> This section is normative.
>
> The first sentence above says "Not normative."

Yes, indeed I was correcting Cameron's notes. Sorry for being so blunt  
about it :-/.

We talked at the meeting about the required vs. optinoal normative  
distinction. I used "mandatory" and "advisory" at the time, but  
"required" and "optional" seem better in hindsight.


> Web IDL just specifies the notion of callable interfaces, not  
> callable collections per se.

We don't want a honey trap in WebIDL, or particular bears putting  
their noses in it in HTML5.


> The right way to make callable collections optional would be at the  
> HTML5 level.

There's no exclusive "right way" that leaves these in WebIDL to pop up  
again and again in other WebIDL-dependent specs.


>> The distinction is between required and optional feature. In both  
>> cases there is a normative spec.
>>
>> I agree that options, profiles, and "levels" or "modes" create  
>> complexity in which hide interop bugs, due to spec bugs or just  
>> implementation bugs arising from the complexity.
>>
>> On the other hand, we do not intend to support callable collections  
>> that WebKit and possibly Opera support, so either these don't get  
>> any normative spec, or they get an optional one. The latter seems  
>> better but I can live with the former.
>
> Really the linchpin is IE/Trident supporting them. I think WebKit  
> and Presto only support them only to chase IE compatibility. I'd  
> much rather come to consensus on this than make it implementation- 
> dependent.

Great, I hope Anne agrees. Sicking is carrying the torch on this issue  
to HTML5, IIRC but here we are in public-script-coord -- it would be  
excellent if we could resolve this promptly.


>>> I think it's a giant failure that ES5 takes this approach to  
>>> anything - it's just a cheap way to maintain a smug sense of  
>>> purity without actually serving interoperability of the Web  
>>> platform. Interoperability is more important than wrinkling our  
>>> noses at distasteful legacy.
>>
>> Fair enough, but bending current and future specs around legacy  
>> crap is the yin to your yang. I think we have to keep both sides in  
>> mind and strike a balance.
>
> But failing to spec the bad stuff doesn't make it go away.

Certainly not. The approach has to involve better forms to lead  
developers away from the legacy crap. When or whether this retires any  
particular feature is unpredictable. Not working on better forms at  
all, focusing only on legacy, will tend to perpetuate the legacy, all  
else equal.


> It's the actual existence of legacy crap (in content and  
> implementations) that constrains us, not its status as an  
> implementation requirement. In fact, trying to design features  
> without considering the impact of legacy implementation extensions  
> can result in features that don't actually meet their intended goal.  
> I recall some hard thinking to stop features that expose the call  
> stack from breaking strict mode.

Yes, the poison-pill ES5 strict mode throwing getters for foo.caller,  
etc. Permit me to expalin to public-script-coord a bit, it may be  
worthwhile:

JS implementations going back to 1997 era, and IIRC ES1 from that  
year, included some properties reflecting the language's control  
stack. The first was a function property, spelled foo.caller for  
function foo when active, which would link to the most-recently  
activated foo's calling function. It thus couldn't link through  
recursive activations of foo. A fix attempt moved this property to  
arguments.caller for each function activation's arguments object,  
avoiding the pigeon-hole problem. But Ecma TC39 (TG1 at the time, late  
'90s) was concerned about security flaws allowing backtrace across a  
trust domain boundary.

So the ES specs purged all mention of .caller, but implementations did  
not.

Separately, arguments.callee was implemented as a way to get the  
currently active function object from within its body, or within any  
code to which an active function's arguments object reference was  
passed.

This became popular in anonymous function expressions over against  
giving such "lambdas" their own names (which the ES3 spec supported),  
partly for copy-paste programming wins, partly because IE has  
notorious bugs in processing named function expressions, storing the  
function's name in the enclosing scope in violation of ECMA-262 Ed. 3  
and all plain sense (lambdas with names are supposed to be callable  
from their own bodies, and you can take a reference to them by their  
name, but the name must not leak or clobber an outer binding).

ES5 strict mode is a "better form" (or a suite of "better forms"  
including error checks, but also a few runtime semantic changes) which  
we hope (I subscribe to this hope) developers will opt into using. But  
if they do, the .caller and .callee properties are replaced by getters  
that throw. This relieves object-capability subset language systems  
such as Google Caja from having to do something expensive and painful  
at runtime to avoid capability leaks.

In the case of .caller this is not a problem AFAICT. JS programs that  
use .caller can confine it to non-strict code, for backtracing; or  
else use better de-facto standard ways of backtracing. A de-jure  
secure backtrace API is a subject for future ES standardization.

In the case of .callee, I think Ecma TC39 erred in not considering the  
IE bug as legacy that could undermine strict mode adoption.

But, to get back to the point at hand, if we only considered the IE  
bug or bugs in named function expression name-binding, we could easily  
get stuck in too conservative a mode of operation.

To your point that "[i]t's the actual existence of legacy crap ...  
that constrains us", this remains to be seen with IE's function  
expression naming bugs. If these really do constrain us, then worst- 
case we might standardize them somehow, or make a no-man's-land of non- 
interoperation (poison pills salting the earth!) in a de-jure spec.  
Neither of these seems good.

Between banning an old form such as arguments.callee with strict mode,  
and actually specifying it for the first time ten years too late, I  
think there is room for a better balance.

At this point we will try to measure how ES5 strict mode uptake is  
hampered by the loss of arguments.callee. Workarounds have been  
discussed starting with this thread-head message:

https://mail.mozilla.org/pipermail/es-discuss/2009-September/009851.html

in case anyone is interested in the gory details. It's not a black vs.  
white situation.

Sorry for the length of this aside, I hope it helps show why I do not  
agree that legacy constraints dictate only one way forward, namely  
specifying the legacy crap.


>>> In the specific case of document falsey-ness, I think it should be  
>>> mandatory, not optional (even though it is spec'd in HTML5, so  
>>> this discussion doesn't really apply).
>>
>> You mean document.all falsyness? The way WebKit implements this  
>> violates ECMA-262 (there's no exemption for a host object in  
>> ToBoolean).
>
> Indeed, and I think ECMAScript should be changed to allow  
> document.all falsy-ness in some way. Would you claim the way Gecko  
> implements it does not violate ECMA-262? (In tests I was unable to  
> figure out a model of the Gecko behavior is.)

Yes, I would. We reflect document.all only if it is used in a  
"detecting" context such as an if (condition). And since document is a  
host object in ECMA-262 terms, its implementation is free to make .all  
appear or disappear at will (time of day, toss of random coin,  
detecting context, etc.).


>> Considering your finding fault with ES5 for HTML5 and ES5 still  
>> conflicting over global code |this| binding (to something other  
>> than the global object, namely WindowProxy per HTML5), I think you  
>> are now in a glass house. Put down the stone. :-/
>
> Huh? My position is that ES5 should be fixed on that score to  
> conform to reality, and that an interoperable behavior should be  
> normatively required. I don't see how this conflicts with my  
> statement above.

Contrast concern about ES5 not resolving the conflict with HTML5 in  
the global-code |this| binding case, vs. no apparent concern about  
violating ES specs with falsy document.all in HTML5.


>> The Reject category is informative, for WebIDL users and would-be  
>> extenders.
>
> I don't think a spec needs to mention what's not in the spec. People  
> already complain that it's too long. If this information is really  
> valuable, we could publish it as a Note. That being said, I'm not  
> sure there is anything really in this cateogry.

Overloaded methods with different non-trailing argument types, as in  
canvas's imageData methods, were a candidate -- IIRC (Cameron and Mark  
should chime in here). These seem like anti-patterns.

Informative anti-pattern ("don't do this") advice seems critical with  
WebIDL as it is today, or we'll have ES binding woes tomorrow and  
forever.

/be

Received on Thursday, 8 October 2009 14:36:24 UTC