Re: lexical for-in/for-of loose end
Grant Husbands wrote: Herby Vojčík wrote: It looks to me that all those schemes and desugaring are very complicated The full problem is complicated, so that's to be expected. I meant all that copying there and back and having two variables with the same name in two scopes and handling all combinations when to access which one. I wanted to take this away. What is bad with scenario of reusing the same variable and isolating it as local only for the async closures? Your proposal depends on being able to reassign variable pointers, but they don't necessarily exist. Though I haven't written a JS engine, I believe they are allowed to have variables directly in an activation record (or environment instance) without any (pointer) indirection, so they'd have no mechanism for performing the operation you describe. Well, references are all over the spec (or were in times of ES5). Yes, they are only virtual objects of the spec, they are not first-class and probably not even exist in the implementation; but I just reused them in my proposal. So that there will be loop-body-local variable _iter_record; 'i' inside body will be Ref(_iter_record, 'i'), and while the loop is running, _iter_record is _outer_shared_record, and when ending the iteration, _iter_record is assigned to _local_iter_record. Of course if there are no closures, all this can be optimized away, or if eval is not used in them, only those variables that needs to be localized should be; but that's beyond scope. (No, I am not proposing optimization, as Brendan said; I am proposing different approach with lazy fixing locals so that complications are not present while the loop is running, only when closures are run outside loop) Or, here's one that copies the other way (and is probably cleaner): 'Note' all closures (dynamically) created in (lexically, post-desugaring) the loop body. Each time you end an iteration, update all the loop variable activation record pointers to point at a new clone of that activation record. If I understood correctly, this is what I proposed. Or maybe it only looks like it? In each case, you require a list of not-necessarily-predictable size to note the closures in. That's not a big problem; it's just something you need to be aware of. This I did not understand. Regards, Grant. Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: lexical for-in/for-of loose end
Herby Vojčík wrote: I meant all that copying there and back and having two variables with the same name in two scopes and handling all combinations when to access which one. I wanted to take this away. Yes, at least my desugaring was indeed overcomplicated. Brendan's and Mark's desugarings aren't that complicated, though. Your proposal depends on being able to reassign variable pointers, but they don't necessarily exist. Well, references are all over the spec (or were in times of ES5). What I was calling activation records, the spec calls environment records and it does not, by my reading, imply that variables within them are reference-like in nature (read clause 10.2). However, we don't need to argue this point. Or, here's one that copies the other way (and is probably cleaner): 'Note' all closures (dynamically) created in (lexically, post-desugaring) the loop body. Each time you end an iteration, update all the loop variable activation record pointers to point at a new clone of that activation record. If I understood correctly, this is what I proposed. Or maybe it only looks like it? It has the same behaviour, but without needing variable pointers; that was the idea. I now propose it to the list as a variant of your idea that I think some may prefer. I'm merely trying to make sure your idea gets the attention it deserves. To be completely acceptable, the mechanics would need fleshing out, of course. Regards, Grant. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: lexical for-in/for-of loose end
Grant Husbands wrote: Herby Vojčík wrote: Your proposal depends on being able to reassign variable pointers, but they don't necessarily exist. Well, references are all over the spec (or were in times of ES5). What I was calling activation records, the spec calls environment records and it does not, by my reading, imply that variables within them are reference-like in nature (read clause 10.2). However, we don't need to argue this point. I feel like misunderstood. I _know_ there aren't ref variables in the spec. I never told that. I was just telling that 'i' inside the loop body may be compiled not as Ref(loop-body-record, 'i') whenever it is accessed/modified (and optimized when Ref is not really needed, but you can see at it as if it is always Ref to local i), but as Ref(the-record-to-use, 'i'), the-record-to-use being local variable in loop iteration which can change its value (it can be outer-record when loop runs, at it can be local-record when iteration ends and values are fixed in local 'i'). Or, here's one that copies the other way (and is probably cleaner): 'Note' all closures (dynamically) created in (lexically, post-desugaring) the loop body. Each time you end an iteration, update all the loop variable activation record pointers to point at a new clone of that activation record. If I understood correctly, this is what I proposed. Or maybe it only looks like it? It has the same behaviour, but without needing variable pointers; that was the idea. I now propose it to the list as a variant of your idea that I think some may prefer. I'm merely trying to make sure your idea gets the attention it deserves. Thanks. Yes it is the same behaviour, the active loop body always uses the same shared 'i', only async closures get the fixed copy. Nice. To be completely acceptable, the mechanics would need fleshing out, of course. Regards, Grant. Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: lexical for-in/for-of loose end
Grant Husbands wrote: For what you're talking about, I think this might be an equivalent proposal that's more spec-friendly: 'Note' all closures (dynamically) created in (lexically) the loop initializer. Only in the initializer? Why should closures formed there be dynamically scoped to the current iteration? That's something done nowhere in the language as extended by let/const, either in JS1.7+ in SpiderMonkey and Rhino, or in draft ES6 so far. I admit it's yet another non-throwing possibility beyond 0th-iteration scope and 1st-iteration scope. It is not the same as evaluating the initializer in each iteration's scope, though. Instead there's a dynamic scope for closures in the initializer (only those using the for(let-declared bindings?) not used for expressions or other closures, or something like that. Dynamic scope is a warning sign, almost always a mistake. Each time you start an iteration, update all the loop variable activation record pointers within those to point at the current iteration's activation record (which should, with care, have the same shape). Note that non-strict eval can affect the activation's shape. Or, here's one that copies the other way (and is probably cleaner): 'Note' all closures (dynamically) created in (lexically, post-desugaring) the loop body. Each time you end an iteration, update all the loop variable activation record pointers to point at a new clone of that activation record. This is a more complex spec than one that models each iteration having its own lexical scope. The spec needs only declarative environments, not hidden references and pointer updates. In each case, you require a list of not-necessarily-predictable size to note the closures in. That's not a big problem; it's just something you need to be aware of. As an implementation technique, Chez Scheme's heap boxing and assignment conversion could be even better. But this is all beyond the spec. Still trying to be sure you intended a unique and dynamic scope for the initializer (first part) of for(let;;). /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: I18n - defining format() and compare() as getters to simplify usage
I have updated the specification such that Collator.prototype.compare is now a getter that returns a bound function, which is cached by the first call to the getter: 1. If the [[boundCompare]] internal property of this Collator is undefined, then: a. Let that be this. b. Let bc be a function that takes the arguments x and y and performs the following steps: i. Return the result of calling the [[Compare]] internal method of that with arguments x and y. c. Set the [[boundCompare]] internal property of this Collator to bc. 2. Return the value of the [[boundCompare]] internal property of this Collator. [[Compare]] is what used to be Collator.prototype.compare in previous specification drafts. The [[Set]] attribute is undefined. I have no evidence that the format() methods are likely to be routinely invoked as a standalone function, so I haven't changed those functions. Norbert On Feb 1, 2012, at 8:59 , Allen Wirfs-Brock wrote: On Jan 31, 2012, at 4:23 PM, Nebojša Ćirić wrote: 31. јануар 2012. 15.50, Norbert Lindenberg ecmascr...@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
Re: Internationalization summary 1/19 (TC39 meeting)
Following up on Nebojša's summary, I'd like to - Rename the namespace object of the Globalization API from Globalization to Intl. - Then rename the API itself from Globalization API back to Internationalization API. I searched a bit and found indications that the global Globalization may have been used for some time by the library now known as jquery/globalize. I haven't found any evidence of intl or Intl being used in the global namespace (Intl is used in the YUI namespace). Within ECMAScript it seems there's a preference for capitalized namespace names: Math, JSON, hence Intl. Our API was conceived as the Internationalization API, then became the Globalization API to match the name of the namespace object. With Intl, Internationalization API again is the better match. Comments? Thanks, Norbert On Jan 20, 2012, at 14:38 , Nebojša Ćirić wrote: Going back to module vs. global object discussion. General agreement was that we should pick a global name and work with that, then use modules when they are ready, but that we should wait for Brendan to pitch in before making a final decision. Most of the group was for shorter name i.e. intl if it doesn't introduce conflicts. The reason for this discussion was the current state of the module spec, i.e. it's not clear yet where load/loaded will reside (not everybody agrees on Object.system). In order to produce an implementation by March and have draft accepted we do need to decide rather soon on this. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss