Re: function hoisting like var
Ingvar von Schoultz wrote: > Richard Cornford wrote: >> { >>1,2,3,4,5 >> } >> >> - is a valid ES 3 Program (even if a pointless one); A Block >> statement containing an Expression statement (with automatic >> semi-colon insertion making the Expression statement >> into - 1,2,3,4,5; -). >> >> eval('{1,2,3,4,5}') - results in the value 5, while - >> eval('[1,2,3,4,5]') - returns a 5 element array. > > Yes. And if the rules for "{" remain unchanged, and "[" starts > out assuming it's a literal, you get the same result with my rules. And if I wanted that block scope this - eval("{[\n eval('var a = 1'),eval('var b = 2'),eval('a + b')\n]}"); - will still give me an array (and side effects in the containing scope)? ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss
Re: function hoisting like var
Ingvar von Schoultz wrote: > Igor Bukanov wrote: >> 2008/7/28 Ingvar von Schoultz wrote: Any of this can be a valid ES3 code as [] always means an array literal. >>> I get the impression that disambiguation would be easy. >> >> eval('[]') is a valid and, in fact, useful ES3 code. Similarly >> eval('{[]}'). > > Yes, and by my rules they both create and return a new, empty > array, which is intuitively expected and compatible. Are you saying that a block then may never be empty as a syntax rule? ES 3 blocks are allowed to be empty and I bet there are examples where blocks contain nothing but an IE/JScript conditional comment and so are going to be interpreted as being empty by other ES 3 implementations. (Comments are allowed inside array literal definitions at present). > When I said that an array is a comma-separated list of values, > the fact that I left out the empty and the single-value cases > didn't mean that they should be seen as blocks! I just didn't > want to write a lengthy, exhaustive full grammar... { 1,2,3,4,5 } - is a valid ES 3 Program (even if a pointless one); A Block statement containing an Expression statement (with automatic semi-colon insertion making the Expression statement into - 1,2,3,4,5; -). eval('{1,2,3,4,5}') - results in the value 5, while - eval('[1,2,3,4,5]') - returns a 5 element array. ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss
Re: Newly revised Section 10 for ES3.1.
Brendan Eich wrote: > On Jul 10, 2008, at 4:02 PM, Richard Cornford wrote: >> Something like:- >> >> fucntion getSomething(arg){ >> if(caseOneTest){ >> getSomething = function(x){ >> //actions appropriate for case one >> }; >> }else if(caseTwoTest){ >> getSomething = function(x){ >> //actions appropriate for case two >> }; >> }else{ >> getSomething = function(x){ >> //actions appropriate for other cases >> }; >> } >> return getSomething(arg); >> } >> >> It is the ability to do this sort of thing that helps make >> javascript so well suited to browser scripting. > > Oliver Steele blogged about this kind of memoization a couple > of years ago: > > http://osteele.com/archives/2006/04/javascript-memoization > > although his examples did not show top-level function being > replaced. I was shown examples of doing this sort of thing back in 2002 shortly after I first started using javascript, so even if it has never become that common it certainly is not a new idea. > But it's a good point: strict mode wants to break useful (and > used) patterns that change the value of a property created by > a defining form. I spend yesterday's commute to work thinking about this and came to the conclusion that I am completely wrong. If "Illegal to assign to a top-level function name" is interpreted as meaning (or re-worded to effetely say) that it is illegal to assign to a top-level name (activation/environment object property, or however that is best expressed) that was created_as_the_result_of_a_function_declaration (as opposed to a possible interpretation where it is illegal to assign to a top-level name that happens to refer to a function object) then there isn't really a problem. There is no problem because if I want a self-reconfiguring function I can create one with a function expression. I.E.:- var getSomething = function(arg){ if(caseOneTest){ getSomething = function(x){ //actions appropriate for case one }; }else if(caseTwoTest){ getSomething = function(x){ //actions appropriate for case two }; }else{ getSomething = function(x){ //actions appropriate for other cases }; } return getSomething(arg); }; - and have the same facility for a negligible difference in effort. The minor change in execution, where a function declaration creates its function during variable instantiation and the above would create it at the execution of the assignment, isn't too problematic. It just means that the code that creates the function has to run before any code that attempts to use it (which is already true of much more common constructs such as the (so called) 'Crockford Module Pattern'). As this is "the cautious subset"/'strict' mode (or however it is to be known) we are talking about code that is yet to be written; so long as the facility remains the details of how it is achieved are not too important (at least so long as the useful existing possibilities don't become significantly more difficult to achieve). > From Allen's list: > >·Illegal for a function to have duplicately named formal > parameters >·Illegal for a function to contain a top level function > declaration with a function name that is the same as a formal > parameter. >·Illegal to have multiple top level function declarations > for the same function name >·Illegal to have a function declaration with the same name > as var declaration. >·Illegal for a function to contain a var declaration with > the same name as a formal parameter. I liked all of these from the outset. If I do any of these in the code I write then I have made a mistake, and being told as much ASP means that I can fix that mistake sooner rather than later. >·Illegal to assign to a top-level function name. And in retrospect that one is OK too. If I don't what a top-level function replaced I can use a function declaration, and if I do I can assign a function expression to a variable; a little externally imposed formal discipline (and no harm in that). > I could see banning duplicate formal parameter names (I still > have no memory of why Shon from Microsoft wanted these > standardized in ES1 -- possibly just because JScript already > allowed them). I could not think of anything useful that could be done with multiple like-named formal parameters. The nearest I could get is if you wanted an object with a read-only - length - property of varying magnitude you could do something like:- function makeFixedLengthObject(sizeOfLength){ function F(){} var
Re: Newly revised Section 10 for ES3.1.
> In the course of this, I noticed a number of conditions that plausibly > might be restricted in the cautious subset, but currently aren't > specified as such: > *Illegal to assign to a top-level function name. > Does anybody want to advocate for including these restrictions > in the cautious subset. This last would not be a good idea in a language intended for browser scripting. There are circumstances were code needs to test its environment in order to determine how it should act. In many cases the conditions being tested for will not change while the script is being executed (the nature of a browser's object model will not change while it is executing a script) so repeating the test on each execution of a function is inefficient as the results of the test will always be the same as the first. One strategy for dealing with that is to have the first call to a function perform the test and so decide which actions should be take in the given environment and, instead of taking those actions directly, assign a new function to replace itself where that new function only takes the chosen action and so avoids the overhead of testing on all subsequent calls to the function. Something like:- fucntion getSomething(arg){ if(caseOneTest){ getSomething = function(x){ //actions appropriate for case one }; }else if(caseTwoTest){ getSomething = function(x){ //actions appropriate for case two }; }else{ getSomething = function(x){ //actions appropriate for other cases }; } return getSomething(arg); } It is the ability to do this sort of thing that helps make javascript so well suited to browser scripting. ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss
Re: Newly revised Section 10 for ES3.1.
> 10.1.8 Arguments Object > For each non-negative integer, arg, less than the value of the > length property, a property is created with name ToString(arg) and > property attributes { [[Writable]]: true, [[Enumerable]]: false, > [[Flexible]]: false }. The initial value of this property is the > value of the corresponding actual parameter supplied by the caller. > The first actual parameter value corresponds to arg = 0, the second > to arg = 1, and so on. In the case when arg is less than the number > of formal parameters for the Function object, this property shares > its value with the corresponding property of the activation object. > This means that changing this property changes the corresponding > property of the activation object and vice versa. The provision "that changing this property changes the corresponding property of the activation object and vice versa" implies a potentially long-term linkage between some properties of activation objects corresponding arguments object properties. As functions forming closures can have ongoing access to activation objects and references to arguments objects can be assigned to object properties and variables (and so remain accessible after the function calls for which they were created have finished) this implied long-term linkage could have practical implications. For example:- function getToy(one, two, three){ var ar = arguments; ar[2] = 7; return ({ setOne:function(x){ // setting the '0' property of the arguments object should // change the value of the - one - formal parameter. ar[0] = x; }, getOne:function(){ return one; }, setTwo:function(x){ two = x; }, getTwo:function(){ return ar[1]; }, getThree:function(){ return three; } }); } var obj = getToy(1, 2, 3); obj.setOne(5); obj.setTwo(6); alert( obj.getOne()+'\n'+ obj.getTwo()+'\n'+ obj.getThree() ); - could be expected to alert 5, 6 and 7, and does in Windows Safari 3 and Opera 9. But IE 6 and Firefox 2, for example, it alerts 1, 2 and 7. There the linkage breaks down outside of the execution context of the initial function call. A new specification probably should pin down which of these is "correct". It should either reinforce the implication that the linkage is intended to be long term or state the lifespan of the linkage (possibly saying that it cannot be expected to hold past the lifespan of the execution context for which the arguments object was created (thus categorizing longer term linkage as a possible non-standard extension)). I would favour the latter as the inconsistency in existing implementations makes it unlikely that anyone is using this linkage outside of the functions whose calls create the arguments objects, and there is nothing that could be done with this linkage that could not be better (less obscurely) achieved using closures. ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss