Mike Samuel | 1 Feb 01:06
Picon
Gravatar

Re: Nested Quasis

2012/1/31 Allen Wirfs-Brock <allen <at> wirfs-brock.com>:
>
> On Jan 31, 2012, at 2:36 PM, Waldemar Horwat wrote:
>
>> On 01/28/2012 02:54 PM, Erik Arvidsson wrote:
>>> Under the open issues for Quasi Literals,
>>> http://wiki.ecmascript.org/doku.php?id=harmony:quasis#nesting , the
>>> topic of nesting is brought up.
>>>
>>> After implementing Quasi Literals in Traceur it is clear that
>>> supporting nested quasi literals is easier than not supporting them.
>>> What is the argument for not supporting nesting? Can we resolve this?
>>
>> This has been hashed out in committee before.  Do you have a solution to the grammar problems, such as
having a full ECMAScript parser inside the lexer?  You can't just count parentheses because that breaks regexps.
>
> I would think the solution to this is pretty straightforward.  Basically, a Quasi is not a single token.
  the grammar in the proposal can almost be read that way right now.   It should only take a little cleanup
to factor it into a pure lexical part and a syntactic part. A few [no whitespace here] tokens will probably
be needed

I addressed this at
http://js-quasis-libraries-and-repl.googlecode.com/svn/trunk/tokenize.html
_______________________________________________
es-discuss mailing list
es-discuss <at> mozilla.org
https://mail.mozilla.org/listinfo/es-discuss
Nebojša Ćirić | 1 Feb 01:23
Picon
Favicon

Re: I18n - defining format() and compare() as getters to simplify usage

31. јануар 2012. 15.50, Norbert Lindenberg <ecmascript-GJDRJytQelzDPFKH+ErY4/pXobYPEAuW@public.gmane.org> је написао/ла:
I can imagine doing this for Collator.prototype.compare because Array.prototype.sort is such a common use case for it, but why for the format() methods?

I heard a couple of reasons for format methods to be bound:

1. Can be passed as functions, thus hiding the object details
2. Makes it symmetrical to compare (in case we follow Allen's advice)
3. No binding gotchas for users
 
We don't want to impose the overhead of creating a bound function on each call to format() unless there's a good reason...

Would caching first one resolve the overhead, like so (not sure about syntax):

NumberFormat.prototype = {
  get format(date) {
     var that = this;
     if (that.__bound === undefined)
       that.__bound = function(a) { uses that; return a < b };
     return that.__bound;
  }
}

Of course, doing it for one and not the other is somewhat inconsistent. And since ES 5 has Function.prototype.bind (implemented in the leading browsers except Safari), it's not hard to bind compare() without library support:
myArray.sort(collator.compare.bind(collator));

Yes, we should probably pick one or the other - go jQuery route and force developers to .bind manually, or any other library where they either bind for the users or provide two versions of the same method (one bind the other one not).

It seems that both ways of solving binding issues are present in the real world, but we should resolve the issue so we can finalize the spec (and implementations).

Norbert


On Jan 31, 2012, at 10:04 , Nebojša Ćirić wrote:

> We (i18n group) mentioned slight problem with Collator.compare() method to Allen at the last i18n meeting.
>
> The problem is that you can't do:
>
> var col = new Intl.Collator(...);
> array.sort(col.compare);
>
> because of the binding loss.
>
> Allen proposed something like this as a possible solution (typing from memory):
>
> Collator.prototype = {
>   get compare(a, b) {
>      var that = this;
>      return function(a, b) { uses that; return a < b };
>   }
> }
>
> It seems that all major JS libraries*, except jQuery, try to help user not to stumble on this problem. Should we include this into spec?
>
> I think that if we do it for compare() method, we should then do it for format() methods too, since that would allow user to pass functions around instead of objects.
>
> This should not apply to supportedLocalesOf functions.
>
> What do you think?
>
> * http://www.alistapart.com/articles/getoutbindingsituations/ (see "JavaScript frameworks do it" section)
>
> --
> Nebojša Ćirić




--
Nebojša Ćirić
_______________________________________________
es-discuss mailing list
es-discuss@...
https://mail.mozilla.org/listinfo/es-discuss
Mark S. Miller | 1 Feb 02:34
Picon
Favicon

Re: block scope + direct non-strict eval



On Tue, Jan 31, 2012 at 1:53 PM, Brendan Eich <brendan <at> mozilla.org> wrote:
On this very thread we are hashing out how eval("let x = ...") interacts with the dynamic scope. I started advocating an ES5-like isolaed eval lexical scope, and we could do that for let and const -- but var for direct eval from non-strict code must affect the dynamic scope, same with function in all likelihood (i.e., that's how eval("function f(){...}") works now).

We already did the work in ES4/3.1 days, culminating in ES5, to distinguish direct from indirect eval. Direct eval from strict code is well-defined to have a fresh lexical scope in which to bind vars and functions in the eval'ed source:

js> function f(s){"use strict"; eval(s); return g}
js> var g = "global";
js> f("function g(){}")
"global"
js> f("var g=42")
"global"

For strict direct eval, it follows that let and const must bind in the fresh lexical scope created for eval. But direct eval from non-strict code still faces the two choices Allen outlined.

Indirect eval is always non-strict and scoped only by the global scope.

    (1,eval)(' "use strict"; let x = 8;')

is a strict indirect eval.

 

/be

Claus Reinke <mailto:claus.reinke <at> talk21.com>
January 31, 2012 1:05 PM


Btw, how does versioning work across eval? If I have a function body with an eval in it, will the body/eval run as in ES5 or as in ES6? Will that change if the body or the eval contain ES6 features? Will ES5/ES6
scripts be able to eval ES6/ES5 code?

Claus

_______________________________________________
es-discuss mailing list
es-discuss <at> mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Brendan Eich <mailto:brendan-4eJtQOnFJqFAfugRpC6u6w@public.gmane.org>
January 31, 2012 10:23 AM

I bet the "mode" was what got Sam's attention (mine too) in your "classic mode". We are not making hard mode walls or version opt-in. No engine will have a mode enum that must be advanced (implicitly or explicitly) and checked in order to tell what to do in unversioned script. Or so we think!

/be

Andreas Rossberg <mailto:rossberg-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
January 31, 2012 10:20 AM

You mean as in: "extend" is the new "eliminate"?

I'm sorry, I couldn't resist...

/Andreas
_______________________________________________
es-discuss mailing list
es-discuss <at> mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Allen Wirfs-Brock <mailto:allen-Lg0tYrq3bKnvQC8VwISyQA@public.gmane.org>
January 31, 2012 9:40 AM


What we agreed to eliminate is the concept of a"classic mode" that corresponds to unextended non-strict ES5. Both non-strict and strict code in ES6 will include support for the extended ES6 language features. In a few cases the semantics of extensions may differ slightly between strict and non-strict code and a few extensions may only be available for use by strict code

Allen


_______________________________________________
es-discuss mailing list
es-discuss <at> mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Andreas Rossberg <mailto:rossberg-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
January 31, 2012 8:44 AM


What do you mean? I don't see how it can be eliminated, except by name games.

/Andreas

_______________________________________________
es-discuss mailing list
es-discuss <at> mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
es-discuss <at> mozilla.org
https://mail.mozilla.org/listinfo/es-discuss



--
    Cheers,
    --MarkM
_______________________________________________
es-discuss mailing list
es-discuss@...
https://mail.mozilla.org/listinfo/es-discuss
Brendan Eich | 1 Feb 03:17
Picon
Favicon
Gravatar

Re: block scope + direct non-strict eval

Mark S. Miller wrote:
>
>     Indirect eval is always non-strict and scoped only by the global
>     scope.
>
>
>     (1,eval)(' "use strict"; let x = 8;')
>
> is a strict indirect eval.

Yes. I hope it was clear I meant that, absent any "use strict"; 
directive in the eval'd source, an indirect eval even from strict code 
does not inherit strictness from its caller. No dynamic scope.

/be
John J Barton | 1 Feb 04:01

Re: block scope + direct non-strict eval

>    2) people whose are writing code to dynamically construct the source code
> of a function that will be created via eval are probably think about
> different issues than. I hypothesize that they are more likely to place the
> eval in a block that conditionalized by a if statement.

Just to inform the discussion, some use cases for eval that I have seen:
  1) REPL  (dicey, users have to deal with it)
  2) JS source loaders  (dicey, we're desperate)
  3) Domain Specific Languages compiled into JS, eg domplate in
Firebug, calculators. (solid)

Conditional compilation per se isn't a common use case because
generating or downloading the code will probably be more expensive
than compiling it.

jjb
Claus Reinke | 1 Feb 16:08

Re: block scope + direct non-strict eval

>> Btw, how does versioning work across eval? If I have a function body with 
>> an eval in it, will the body/eval run as in ES5 or as in ES6? Will that 
>> change if the body or the eval contain ES6 features? Will ES5/ES6 scripts 
>> be able to eval ES6/ES5 code?
>>
> On this very thread we are hashing out how eval("let x = ...") interacts 
> with the dynamic scope.

Yes. Prompted by this, I am trying to understand how eval interacts with
implicit versioning ("no ES6 opt-in"; btw, is the current state of 
discussion
on opt-in summarized somewhere? I get lost in the threads here, and the
wiki seems to predate this discussion).

Both ES6 detection-by-feature-use and some ES6 features imply static
checks, with a clear phase distinction between a static and a dynamic phase.
eval ensures that ES is multi-staged (static/dynamic phase switches may
occur nested, with the static phase of an eval occurring during the dynamic
phase of the outer code that reaches that eval).

> ..[ points about direct vs indirect eval, strict vs non-strict code]..

These precedents seem to suggest that the eval code language version
will mostly be independent of versioning the outer code. Which seems
sensible: the eval source is dynamic data, so cannot be used for static
language version determination of outer code; and, on a larger scale,
we want to be able to eval both ES5 and ES6 code. But, on a smaller
scale, that means that eval can be used to embed ES5 features in ES6
code, and vice versa.

Take this problematic example from the old no-opt-in thread:

> function f(a) {
>     arguments[0]=2;
>     return a
> }
> print(f(1));  //2 if ES5, 1 if ES6
>
> There is nothing in the source file that implies which specification to 
> apply so for backwards computability a browser must default to 
> interpreting such program as a ES5 program. Anything syntactically
> unique to ES5 (eg, use of a with statment) or ES6 (eg, use rest or spread) 
> would force one interpretation or another

and embed the assignment in an eval:

> function f(a) {
>     eval("arguments[0]=2");
>     return a
> }
> print(f(1));  // 2 or 1?

If the language version for eval code is independent of the context,
we could have ES5 features used in the middle of ES6 code (so the
result could be 2 even if f is part of ES6 code, unless such cross-version
interactions are prevented by a dynamic barrier), and vice versa. If the
language version for the eval code is not independent of the context,
we have other problems.

Claus
Allen Wirfs-Brock | 1 Feb 17:21
Favicon
Gravatar

Re: block scope + direct non-strict eval


On Feb 1, 2012, at 7:08 AM, Claus Reinke wrote:


Take this problematic example from the old no-opt-in thread:

function f(a) {
   arguments[0]=2;
   return a
}
print(f(1));  //2 if ES5, 1 if ES6

There is nothing in the source file that implies which specification to apply so for backwards computability a browser must default to interpreting such program as a ES5 program. Anything syntactically
unique to ES5 (eg, use of a with statment) or ES6 (eg, use rest or spread) would force one interpretation or another

No, things changed at the last TC39 meeting.

New features can generally be used anywhere.  All code is non-strict unless it is either made strict using a use strict directive or contained within a module body (module bodes have an implicit "use strict").

The above code works the same in ES5 and ES6.  If it is strict code it returns 1.  If it is non-strict code it returns 2


and embed the assignment in an eval:

function f(a) {
   eval("arguments[0]=2");
   return a
}
print(f(1));  // 2 or 1?

same as above, same as ES5


If the language version for eval code is independent of the context,
we could have ES5 features used in the middle of ES6 code (so the
result could be 2 even if f is part of ES6 code, unless such cross-version
interactions are prevented by a dynamic barrier), and vice versa. If the
language version for the eval code is not independent of the context,
we have other problems.

Sticking with the strict/non-strict distinction, can you give an example where a ES6 feature within a strict direct eval within a non-strict code context would be problematic? 

Allen


_______________________________________________
es-discuss mailing list
es-discuss@...
https://mail.mozilla.org/listinfo/es-discuss
Allen Wirfs-Brock | 1 Feb 17:59
Favicon
Gravatar

Re: I18n - defining format() and compare() as getters to simplify usage


On Jan 31, 2012, at 4:23 PM, Nebojša Ćirić wrote:

31. јануар 2012. 15.50, Norbert Lindenberg <ecmascript <at> norbertlindenberg.com> је написао/ла:
I can imagine doing this for Collator.prototype.compare because Array.prototype.sort is such a common use case for it, but why for the format() methods?

I think there is a straightforward design rule to apply in deciding whether such a property should be a unbound method or a bound function.

If the value of the property is a function that is dependent upon the state of its access object and the function is likely to be routinely invoke as a standalone function then use a bound (or otherwise closed over the object) function as the property value. 
More simply,  if the property is routinely accessed with an expression like:
    obj.prop
then it should be a bound function.  If it is routinely accessed with an expression like:
   obj.prop()
then it can be a normal method.

We have a good use case for Collator.compare that strongly suggests it should be bound:
    array.sort(col.compare)

Do we have comparable use cases for Formatter.format?


I heard a couple of reasons for format methods to be bound:

1. Can be passed as functions, thus hiding the object details

would this be routinely done?  If so it is a strong use case for a bound function
    displayDate(dt,  mdyFmtr.format)

2. Makes it symmetrical to compare (in case we follow Allen's advice)
   symmetry is only important if the use cases of the two functions are similar.  I assume that booth Collator and Formatter have plenty of properties that are normally invoked as regular methods.

3. No binding gotchas for users
There are always gotchas if you try to dissociate a function that has (explicit or implicit,if built-in) this reference dependencies. That is the reason for the above design rule. Retrieving a bound function is a different logical operation than extracting a method implementation as an reflective operation.

 
We don't want to impose the overhead of creating a bound function on each call to format() unless there's a good reason...

Would caching first one resolve the overhead, like so (not sure about syntax):

Yes, you would definitely want to memoize the function on first access or perhaps even upon object creation. 


NumberFormat.prototype = {
  get format(date) {
     var that = this;
     if (that.__bound === undefined)
       that.__bound = function(a) { uses that; return a < b };
     return that.__bound;
  }
}

Yes, logically.  However a built-in implementation would use a private internal state variable [[CompareFunction]] instead of a regular property.  An ES6 implementation in ECMAScript would use a private name property.

Alternatively, you could simply create the bound function when you instantiate the  Format instancet object and make it the value of the format (in this example) own property of the new instance.  However, that technique would create issues if anybody ever wants to do prototypal inheritance from such an instance.  For that reason, I would stick with the accessor on the prototype pattern.


Of course, doing it for one and not the other is somewhat inconsistent. And since ES 5 has Function.prototype.bind (implemented in the leading browsers except Safari), it's not hard to bind compare() without library support:
myArray.sort(collator.compare.bind(collator));


Do you really want a naive HTML coder to have to remember this pattern?


Yes, we should probably pick one or the other - go jQuery route and force developers to .bind manually, or any other library where they either bind for the users or provide two versions of the same method (one bind the other one not).

For these cases,  I don't see why you would need the unbound method.  Such a unbound method is really only useful it you are going to move it to another object and this isn't any particular reason why that should be expected to work in this scenario.  Even though the function is bound you can still say:

  col.compare(a,b)

if you want to invoke it using a method invocation style

Allen
_______________________________________________
es-discuss mailing list
es-discuss@...
https://mail.mozilla.org/listinfo/es-discuss
Allen Wirfs-Brock | 1 Feb 18:07
Favicon
Gravatar

Re: Nested Quasis


On Jan 31, 2012, at 4:06 PM, Mike Samuel wrote:

I would think the solution to this is pretty straightforward.  Basically, a Quasi is not a single token.   the grammar in the proposal can almost be read that way right now.   It should only take a little cleanup to factor it into a pure lexical part and a syntactic part. A few [no whitespace here] tokens will probably be needed

I addressed this at
http://js-quasis-libraries-and-repl.googlecode.com/svn/trunk/tokenize.html


A more direct like to this from the Quasis ecmascript.org wiki page would be helpful.  The only current link does directly to the demo shell.

Allen
_______________________________________________
es-discuss mailing list
es-discuss@...
https://mail.mozilla.org/listinfo/es-discuss
Erik Arvidsson | 1 Feb 18:29
Picon

Re: Google indexing code patterns (Re: lexical for-in/for-of loose end)

I did a code search for "for (var ident =" before code search was shut down and the only code it found was from test suites.

On Jan 31, 2012 6:31 AM, "Nadav Shesek" <nadav-VicBCtVReIDiB9QmIjCX8w@public.gmane.org> wrote:

On Jan 31, 2012 3:38 PM, "Sam Tobin-Hochstadt" <samth-1vnkWVZi4QaVc3sceRu5cw@public.gmane.org> wrote:
>
> Google Code Search is no longer available, sadly.
>

Oh, I didn't know it was shutdown. Hopefully some Google internals can still use that data to give some stats when those questions arise...

_______________________________________________
es-discuss mailing list
es-discuss@...
https://mail.mozilla.org/listinfo/es-discuss

Gmane