Re: Destructuring object outside of var declaration
On 11/13/2016 12:33 PM, Isiah Meadows wrote: > Okay. Is it a spec bug then? Throwing a ReferenceError is surprising and odd > IMHO. I think so -- having different sorts of early errors makes it a little less clear what sort of error should be thrown when two early errors of different types are in the same script. Last I knew, the spec was basically just waiting on someone to experiment with pulling the trigger to make everything a SyntaxError. I've been meaning to do that for awhile, but it's not a high priority. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Proposal: Array.prototype.first() and Array.prototype.last()
On 09/27/2016 05:38 AM, Bob Myers wrote: > To my knowledge no-one has ever explained why the following is a bad idea: > > ``` > array.0 > array.-1 > ``` Consider this already-valid code: var first = array .0.toString(); This parses *right now* as var first = array; (0.0).toString(); So your proposal would break existing code. We could imagine inserting a [no LineTerminator here] inside MemberExpression to permit "." NumericLiteral and "." "-" NumericLiteral to appear here, to be sure. But that's extra complexity, extra ASI-handling (having worked on ASI handling recently, I assure you there's *nothing* simple about it, and further complicating ASI is a strong demerit in my book), all for IMO dubious value. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Should assigning to out-of-bounds elements of a typed array throw in strict mode code?
On 02/26/2015 09:54 AM, Mark S. Miller wrote: Jeff? To be completely honest, I can't answer this. My message was merely to pass along the sentiments of others, observed elsewhere, not previously communicated to this list. I personally don't understand what we're doing at a low level sufficient to intelligently discuss this. (In isolation of all other concerns, just purely on aesthetic grounds, the current semantics seem like the ones I'd want, tho.) Right now I'm hoping some of the people I CC'd (including the ones whose CC was dropt by mailman) on the initial email can chime in to elaborate at some point. Luke? Brian? You particularly were the ones whose comments were the most recent ones I was relying on in conveying the sentiments here. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Should assigning to out-of-bounds elements of a typed array throw in strict mode code?
And expanding scope slightly: IntegerIndexedElementGet -- get -- throws a TypeError if the relevant typed array is detached, rather than just returning |undefined| as the computed value. I understand there are also significant complaints about this, for similar reasons. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: typed array filling convenience AND performance
On 10/31/2014 08:40 AM, Katelyn Gadd wrote: In my testing, even best-case optimized memcpy/memset loops did not produce the kind of efficient code you want. There were always bounds checks and in some cases I saw other overhead. The set/copy definitely weren't vectorized. In the best case I saw bounds checks getting hoisted out of the loop body (great!) It's my impression, across many compilers and languages, that completely correct range analysis (a prerequisite to eliminating many bounds checks) is very, very hard. When people have used Csmith and similar on gcc and clang, they've found range analysis bugs (or issues in systems producing inputs to range analysis) with ease. These are seasoned compilers where one might think such issues had long since been eliminated. People find similar issues fuzzing SpiderMonkey. Range analysis has been in SpiderMonkey awhile now, yet the incoming stream of range analysis issues continues unabated. We trust range analysis information for DCE purposes and constant folding because a wrong value/behavior is not immediately exploitable. But we've been *very* hesitant to trust it to eliminate bounds checks. The consequences there are memory corruption and arbitrary code execution. When the range analysis information is known buggy, it'd be folly to trust it to remove bounds checks. I'd also note C/C++ and similar range analysis code usually has the advantage of working with stable, integer-xor-floating types. JS with its double type requires considerably more care to suss out an implicit integer subtype, when double operations can produce integers, integer operations can produce doubles, and negative zero constantly confounds. Range analysis for those languages is easier than it is for JS, and yet they're still buggy. I feel like at this point the claim that we don't need better copy/set APIs is the 'sufficiently smart compiler' trope all over again, though in this case perhaps it is wholly possible and it's just not happening because it isn't important enough to VM implementers. not important enough is true, but it requires a big-picture view. Your narrow focus is on typed arrays and native-equivalent code. There's practically a whole web of code dissimilar to that, that also needs optimizing. There are new standard features to implement. There are security issues to fix. There's low-level architecture to get right so that it's possible to build upon basic optimizations and eventually implement bigger ones (such as the vectorization ideas you mention here). We'll get to this eventually, but it has to compete with the other important concerns on the table. Jeff P.S. -- For what it's worth, I think we'll care a bit more about this soon. We may need to do bits of this to permit self-hosting of SpiderMonkey's typed array methods without losing performance, and we really want to make that change soon. Don't give up hope! ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Late shadowing of globals, esp. 'undefined'?
On 10/28/2014 09:10 AM, Andreas Rossberg wrote: If so, how do we fix this? Allowing shadowing after the fact is pretty bad, since it will probably make all accesses to builtin globals slower in ES6. But it is particularly bad for 'undefined', where the ability to rebind would break various assumptions and optimisations based on its immutability. This seems avoidable to me, even with the current spec language. Implementations would simply need to track syntactically-global accesses (accesses that are global only at runtime, due to dynamic scoping via with, eval, and similar are already slow, so effects on their perf seem ignorable). Then, if a new script's compilation would introduce a shadowing lexical declaration, invalidate the existing global-access code, such that when it next runs it takes account of the shadowing declaration. (Or appears to have that effect.) What am I missing? Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Are the TypedArray constructors missing [[CreateAction]] internal slots?
I was just tracing through typed array construction behavior, and it looks to me like |new Uint8Array()| creates an object via OrdinaryCreateFromConstructor, not by delegating to %TypedArray%.[[CreateAction]]. This creates an object with the right prototype chain but none of a typed array's internal slots. Error and NativeError seem to have [[CreateAction]] slots both; I'd have thought the typed array system would have similar structure. Or am I missing something here? I'm just off a cross-country flight following a weekend with very erratic sleep hours, so I don't have much confidence in my reading being fully on-target. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array.prototype.values is not web compat (even with unscopables)
On 10/17/2014 01:53 PM, Erik Arvidsson wrote: [1] Microsoft Outlook Calendar web app (part of Exchange Outlook Web Access) Microsoft could ship a fix in a point release, right? They surely already provide security patches that admins must install anyway, if they want to keep their users (and their data) safe. If the fix is small, is there any reason why it couldn't be part of such a patch? Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Object.prototype.toString.call(Uint8Array.prototype) throws a TypeError
Per latest draft, %TypedArray%.prototype[@@toStringTag] is a getter that throws a TypeError if |this| doesn't have the internal slots of a typed array. Neither %TypedArray%.prototype nor {{Ui,I}nt{8,16,32},Float{32,64}}.prototype have these internal slots. So the builtin Object toString method, called on any of these objects, will throw a TypeError. Is this wise? I suspect there's debugging code out there that expects that toString doesn't throw on at least the typed array prototypes (seeing as it doesn't throw in any engine I'm aware of right now, tho the returned string is inconsistent). Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: String(symbol)
On 08/12/2014 11:07 PM, Allen Wirfs-Brock wrote: sounds good to me, I'll update the spec. accordingly On Aug 12, 2014, at 7:39 PM, Erik Arvidsson wrote: I was suggesting that String(symbol) should not throw. This can be spec'ed as String( value ) checking the Type of the value and special case it in case of the value being a symbol. With this change, as far as I can tell there's no concise operation directly corresponding to the ToString abstract operation. The best that seems possible is some horribly indirect operation like (v) = Error.prototype.toString.call({ name: v, message: }). That seems undesirable to me. I'm not convinced that having String deviate from ToString is a good thing. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: String(symbol)
On 08/26/2014 08:48 AM, Domenic Denicola wrote: Why would it be useful, from a programmer's perspective, to expose ToString directly? People will always want to polyfill, or prototype in advance of proposal for standardization. No matter how internal the operation might be, it's heavily used by DOM specs and other similar sorts of things. And I have difficulty seeing why many such APIs would want to stringify incoming symbols, to switch away from using ToString. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: String(symbol)
On 08/26/2014 09:14 AM, Brendan Eich wrote: Claude Pache wrote: Personally, I use the following expression in order to coerce a variable to a string: var obj = this + '' and its in-place variant: x += '' I think it'll continue to work in ES6. Agreed, this is the correct-and-most-concise way to do it. It's not the most correct way to do it. |a + | performs ToPrimitive(a, hint = None), whereas ToString(a) performed ToPrimitive(a, hint = String). The former consults valueOf, then toString, the latter the reverse. using String(any) to invoke ToString is verbose and fragile, because String could be rebound :-P. Generally polyfills are fine with that limitation, and only us language pedants need worry/care about String being rebound. All the array-method polyfills we've provided on MDN depend on non-rebinding of some builtin function or other. It's not that big a deal. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Null iterable in for-of?
On 06/12/2014 03:05 PM, Allen Wirfs-Brock wrote: I believe this behavior for for-in was added in ES5. My recollection was that Doug Crockford pushed for it. I don't recall if it was because it matched web reality or simply because he thought it was a good idea. It was added for web compatibility, to track what was originally a SpiderMonkey implementation bug, I believe. I agree that treating null/undefined as an empty collection has a smell. However, in this case my I agree with who ever it was who reported this. that consistancy between for-in and for-of is what we should have for this condition. The spec regarding for-of read the other way, before the latest update, precisely because the web compatibility argument was poor justification for for-in working that way, and for-of was an opportunity to do the right thing. (SpiderMonkey implements the throw-on-null/undefined behavior now.) This was a deliberate inconsistency. I would have argued/responded in that bug with WONTFIX. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Null iterable in for-of?
On 06/12/2014 03:25 PM, Brendan Eich wrote: Actually, if memory serves, IE JScript tolerated null and undefined on right of for-in. SpiderMonkey and my ur-JS implementation, Mocha, did not. Someone with the jwz nostalgia Netscape 2/3 browsers, please test. Hmm. I'm reciting tribal knowledge that I'm probably misremembering at this point, so I bet you're right. I don't think bug-hiding precedent trumps bug-finding, personally. Allen? Agreed. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: new ES6 draft, rev 18
I dunno if this'd be useful to anyone else or not (mentioning here to see whether anyone else sees value in this). But would it be possible for drafts to include the draft date in page headers, or overall PDF title, or somewhere easily-viewable without scrolling too far from any position in the spec? I can't be the only one who usually has an out-of-date draft because I can't religiously follow es-discuss. It'd be nice to be able to guesstimate out-of-dateness quickly (1-1.5mo === fair odds for out-of-date), without having to lose my current position by going to the start page. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Is it really a good idea for octal numbers to allow capital-O, e.g. 0O755?
var n = 0O755; Is this something anyone wants to read? I certainly don't! Allowing only lowercase 'o' in octal literal syntax is inconsistent with 'x' and 'b', but on balance I think that's probably preferable to admitting this monstrosity. :-) (Which isn't to say I care strongly enough to spend a whole bunch of time arguing the point, only enough to raise it as a concern and see if others agree.) Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Why is .bind so slow?
On 07/12/2013 04:59 PM, Andrea Giammarchi wrote: one more thing ... I believe this will impact arrow function too since is basically bound callbacks all over the place (or at least this is how I believe it will be transpiled) Sadly, based on the arrow-function patches I've reviewed in SpiderMonkey, I don't believe this will be necessarily true. Arrow functions and bind-bound functions are two rather different beasts. Bind-bound functions are potentially constructible; arrow functions never are. |arguments.callee| inside a function that's been bound doesn't refer to the bound function -- it refers to the lexical entity. (That is, |function f() { return arguments.callee; } f.bind(null)()| is |f|, not |b|.) |arguments.callee| inside an arrow function -- at least, so long as arrow functions aren't automatically strict, which decision I would revisit -- refers to the arrow function. I expect there are other differences I'm not yet aware of, that would affect having a common implementation of the two concepts. It seems like a pretty bad idea to me for arrow functions to not be substantially semantically similar to bind-bound functions, but they are as it stands now. I wish I had the time to sit down and think through a solid unification of the two concepts. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Why is .bind so slow?
On 07/12/2013 02:54 PM, Allen Wirfs-Brock wrote: Looking at it another way, if implementation haven't found it straightforward to optimize ES5 bound functions why would you expect that would have an easier time with Proxys? I'm pretty sure no implementation has seriously tried to optimize bound functions, and that that's the major reason for any slowness. I don't think there's anything fundamentally difficult about optimizing bound functions. It's just never been a priority for engines, because it doesn't show up in benchmarks and because the perf bugs for it are less pressing than other perf work is, as bound functions remain underused on the web. Chicken and egg? Sure. In the meantime, while I wouldn't currently question (as a purely pragmatic choice) avoiding bind in highly intensive code where every bit of perf matters, I do think bound functions are fast enough for the vast majority of cases. The overhead of calling a bound function will rarely be the difference between adequate and inadequate performance. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Why is .bind so slow?
On 07/13/2013 12:56 PM, Allen Wirfs-Brock wrote: On Jul 13, 2013, at 12:39 PM, Mark S. Miller wrote: Arrow functions, whether strict or non-strict, are not supposed to have their own |arguments| Correct. Implementors should be aware that in the current ES6 draft this is stated in a margin note but not in the actual algorithm for function declaration instantiations (10.5.3) step 11. Good to know, thanks. Lack of arguments is sane; last I'd seen in bug commentary was that this wasn't the case. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Questions on clz and toInteger
On 07/12/2013 10:27 AM, Tab Atkins Jr. wrote: And, because of what we discussed in the recent thread... Number.isInteger(Math.pow(2,53)-1) == true Number.isInteger(Math.pow(2,53)) == false I need to comment in the other thread again and push back against what people have said there, but that thread's issues aside entirely, this is very very wrong. 2**53 is an integer. That there are multiple mathematical integer values that, when converted to IEEE-754 format, are equal to 2**53 is irrelevant. An integer value, that operations claim is not an integer, is very very wat. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: more numeric constants please (especially EPSILON)
On 07/09/2013 06:49 PM, Mark S. Miller wrote: Because Nat includes 2**53, this code actually fails to enforce conservation of currency!! The problem isn't that Nat includes 2**53. It's that you're performing an operation that may compute an inexact value, then you're treating that inexact value *as if it were exact*. You should be testing *before* performing any operation that might compute an inexact value. Or, you should be rejecting values which might be rounded from an inexact value. Which would mean your MAX_NAT test should instead be if (allegedNum = MAX_NAT) { throw new RangeError('too big'); } But really, Nat seems like the wrong concept to me. Even if you correct it as above, it's only correctly usable if it is applied after *every* floating point operation. If you have |a + b|, you can correctly apply a corrected Nat to that. But if you have |a + b + c| or |a + b - c| or any more floating-point operations than a single operation, Nat can't be correctly applied. Corrected Nat as-is gives a false sense of security, by implying that you can apply it to a calculation and it'll do the right thing, when really it'll only do so if the value you're passing in is the result of no more than a single computation. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Questions on clz and toInteger
On 07/12/2013 04:03 PM, Allen Wirfs-Brock wrote: are you suggesting that if we want such an function, it should be named something else, such as isExactInteger, isPreciseInteger, isUnambiguousInteger, etc? Possibly, but I don't think so. Whether a value is exact or precise is a function not of the value itself, but of how it was computed. Math.pow(2, 53) computed that way is an exact value. Math.pow(2, 53) - 1 + 2 is (in IEEE-754 terms) the same value. But it is not exact, because it derived from an inexact computation. It all depends how you got the value you're passing in. isUnambiguousInteger is in a different league from exact/precise. Assuming a definition like so, it might be reasonable: function isUnambiguousInteger(n) { if ((n % 1) !== 0) return false; return Math.abs(n) Math.pow(2, 53); } I'm not sure whether it would be useful enough to carry weight, tho, given it has fairly esoteric use cases. And anyone asking these sorts of questions really needs to know the IEEE-754 design well enough to understand how/why things go wrong, well enough that they could code it themselves. The existence of such a method doesn't make it any more likely that they will understand these details. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Questions on clz and toInteger
On 07/12/2013 04:13 PM, Tab Atkins Jr. wrote: If you don't agree with that reasoning, then I suppose you'd argue that *all* numbers 2^53 should return true, since they're all forced into being represented as integers? All numbers = 2**53 except Infinity, yes. I think isInteger implies the mathematical concept, with the only addition that it should pass -0. And while it would somewhat unfortunately diverge from the ToInteger spec operation, toInteger should imply the mathematical concept as well, and only produce values that are mathematical integers. (toInteger should probably convert -0 to -0 for consistency with isInteger on -0, but probably I could go either way here.) Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: more numeric constants please (especially EPSILON)
On 07/12/2013 04:09 PM, Tab Atkins Jr. wrote: Mark's Nat() function *does* throw if the input isn't an exactly-representable number. Yes. I'm arguing that's not helpful when you can compute an exactly-representable number, that is the result of an inexact calculation, like |Math.pow(2, 53) + 1 - 4|. The JS result of that calculation is an exactly-representable number. But the mathematical result of that computation is not the same number. Nat treats the number passed to it as if it were a calculation's exact result, when it may not be. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Questions on clz and toInteger
On 07/12/2013 04:32 PM, Allen Wirfs-Brock wrote: So the other thread was a discussion concerning the appropriate value of Number.MAX_INTEGER. Do you think it should be 2^53-1, or 2^53, or the same thing as Math..MAX_VALUE. Number.MAX_INTEGER should be 2**53. People who want 2**53 - 1 (and there are roughly reasonable uses for it as discussed in that thread, if enough care is taken) can use as the relevant operator when comparing. In contrast, if the value were 2**53 - 1, people who want the 2**53 value can't simply use a different operator. I haven't kept up enough with this list to know what Math.MAX_VALUE is, and it's not in the latest draft I have -- unless you meant Number.MAX_VALUE? If you meant that, Number.MAX_INTEGER should definitely be different from Number.MAX_VALUE. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Questions on clz and toInteger
On 07/12/2013 04:56 PM, Allen Wirfs-Brock wrote: So you seem to be saying that that Number.isInteger(MAX_VALUE) should be true, but that Number.MAX_VALUE Number.MAX_INTEGER is also true because for isInteger you using the mathematical definition of Integer but for MAX_INTEGER you are using some other definition of INTEGER. I think so. Although, I am not at all wedded to the MAX_INTEGER name, it's just what was proposed already. :-) Your implied point is well-taken that max integer is a misnomer. MAX_EXACT_INTEGER, perhaps? Maybe? I dunno. There surely must be some API with prior art for a name here, but I can't immediately find it in web searches right now. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: more numeric constants please (especially EPSILON)
On 07/12/2013 04:53 PM, Mark S. Miller wrote: I would like a better API -- both less likely to be used unsafely and no harder (or not much harder) to use safely. Suggestions? In C++ you'd want MS's SafeInt, or WTF's CheckedInt, with operator overloading and all that jazz. Without operator overloading the best I can think of are functions for every operation, that have to be used, and if you use the raw operators you take your life into your own hands. Definitely not as easy as just doing the math the normal-looking way. I don't see a super-nice way to do this. :-\ Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Questions on clz and toInteger
On 07/12/2013 06:17 PM, Tab Atkins Jr. wrote: On Fri, Jul 12, 2013 at 5:15 PM, Domenic Denicola dome...@domenicdenicola.com wrote: While I sympathize with the desire to make integer mean mathematical integer, I don't think it's going to work out very well. Nobody actually cares about such functions, and you of course have the WATs of ```js Number.isInteger(9007199254740992.5) === true ``` since the runtime couldn't distinguish this from `9007199254740992`. This is what I was trying to point out as a ridiculous possibility in Jeff's idea, except he claimed it's what he actually wanted. ;_; Roughly no one will type something like that. :-) And if the value were the result of an operation that lost precision, there's no way to tell that with an API that tells you if the value was an integer. Indeed, asking if the value is an integer seems a bit of a non sequitur to me, for that concern. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: more numeric constants please (especially EPSILON)
I'm only commenting on the proposals that seem to be in the current draft, because I'm reviewing a patch that adds only those particular constants. :-) Just to be clear why I'm saying nothing about the other constants, neither to praise nor to disparage. On 03/09/2012 08:00 PM, Roger Andrews wrote: Number.EPSILON == 2^-52 The difference between 1 and the smallest value 1 that is representable as a floating-point number. Why pick this particular epsilon? Why not, say, 2**-1074 instead, as the difference between 0 and the next largest number? Seeing only the name I'd have guessed 2**-1074. Number.MAX_INTEGER == 2^53 - 1 The maximum integer value that can be stored in a number without losing precision. (OK, so technically 2^53 can be stored, but that's an anomaly.) Why discount the anomaly? Looking at SpiderMonkey's source code, we have http://mxr.mozilla.org/mozilla-central/search?string=%3C%3C%2053 as vaguely representative of most of the places using a number like this, I think -- could be others not using the 53 string, but that's probably a fair sample. Ignore the RNG_DSCALE one, that's a red herring. But all the others use 2**53 as the pertinent value. (The dom/bindings/PrimitiveConversions.h hits using 2**53 -1 is a bug, I'm told, due to recent spec changes.) So if this constant is to exist, and I think it's a fair constant to add, why would it not be 2**53? Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: May 4 ES6 draft is available
On 05/07/2012 01:31 PM, Allen Wirfs-Brock wrote: added Number.EPSILON,MAX_INTEGER,parseInt, parseFloat,isNaN,isFinite, isInteger, toInt Modulo the semantic quirks in my last response, talking about the values and intended meanings of EPSILON and MAX_INTEGER, I think it would be better to write out these values not in decimal form in the spec: that is, as 2**53 or 2**-52 or 2**53 - 1 or similar. Just a stylistic nit. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: more numeric constants please (especially EPSILON)
On 07/09/2013 04:14 PM, Brendan Eich wrote: Why pick this particular epsilon? Why not, say, 2**-1074 instead, as the difference between 0 and the next largest number? Seeing only the name I'd have guessed 2**-1074. See http://en.wikipedia.org/wiki/Machine_epsilon. Hmm, my memory of the meaning of epsilon was obviously horribly wrong. :-) This is obviously sane then. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: B.3.1 The __proto__ pseudo property
On 05/09/2013 10:12 AM, Brendan Eich wrote: Adding an equivalent to the main spec does not cordon off the mis-performing (non-performant?) functionality. I may have misread, but I had thought there was argument to put Object.setPrototypeOf in Annex B as well. If it's added, that seems like the right place to me. There are somewhat orthogonal concerns here, for __proto__ and an Object.* method. Special-form badness is only in __proto__ the syntax. Prototype mutation after creation, with its erratic performance destabilization, and the impact upon proxies and [[SetInheritance]], is in __proto__ the property and an Object.*. Both aspects raise concerns of varying degree for developers. Not use Object.setPrototypeOf and do what instead? If people need to make ad-hoc inheritance relations and Object.create doesn't fit, then what? The non-mobile web is being eclipsed by mobile device growth. New content is written for smaller screens; old content lives on or dies, a flat to declining proposition. In the next ten years there'll be a lot of JS written for the web, AKA the mobile web. What should people use to make ad-hoc inheritance structures where Object.create does not suffice? Simply this: don't make ad-hoc inheritance relations where Object.create doesn't fit. Prototype mutation is extra expressiveness. But it is not *necessary* expressiveness, to write useful programs. There's an incredibly rich set of programs that can be written (have been written) without prototype mutation. I don't think it adds so much value to mandate it for every single embedding, considering its issues. Obviously you disagree to some degree. I suspect we'll have to leave it at that. It's worth reiterating that Annex B would be better for all of this not for mobile or non-mobile web (although I don't think there's anything different about mobile and non-mobile with respect to __proto__'s utility -- its utility on mobile is solely a matter of mobile being dominated by engines with __proto__). It's to not penalize embeddings working on a blank slate. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: B.3.1 The __proto__ pseudo property
On 05/08/2013 01:58 PM, Brendan Eich wrote: 1. Dumping stuff into Annex B to show disdain. This is pride, bad for the soul. Pride doesn't seem like a reason one way or the other, to me. The reason would be to cordon off functionality whose mis-performance developers will not intuitively understand, so that they're less likely to use it. Some will, even still, perhaps just out of obstinacy (pride, even, that they hacked their way to the tiniest solution :-) ). But some will take a second look, learn the reasons it's undesirable, and not use it. 2. More important: people port code from the web. In what future super-web will we start fresh? How much code gets ported from the web? Most libraries I can think of are pretty intricately tied to the event loop, the DOM, browser-isms like window.atob/btoa, and any number of other things. The true reason is that new environments may spin up that don't care about code ported from the web. SpiderMonkey even supports this with the __proto__ feature-disabling macro. Supposing v8 didn't have __proto__, would Node have been less successful? I can't see __proto__ as a dealbreaker for the success or failure of JS embeddings. Or Object.setPrototypeOf, either, for that matter. I'd Annex-B the whole lot of this, if I were putting it anywhere in the spec. (Probably even the object-literal and [[SetInheritance]] bits of it, too, although these would be somewhat awkward out of line like that.) Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: B.3.1 The __proto__ pseudo property
On 05/08/2013 04:10 PM, Brendan Eich wrote: Why would Object.setPrototypeOf have any better perf? It wouldn't. developers will not intuitively understand, so that they're less likely to use it. Some will, even still, perhaps just out of obstinacy (pride, I think you missed that that was directed at TC39ers, not developers. Some developers look at language specs, so spec position does provide meager influence that way. Documentation authors are the likelier target. They're going to look at specs to figure out what the methods do, to a much greater extent. Positioning in Annex B and not in main flow sends a small message that something's different. MDN documentation of octal syntax, for example, is only found in a deprecated/obsolete features page, for example. even, that they hacked their way to the tiniest solution :-) ). But some will take a second look, learn the reasons it's undesirable, and not use it. And not use Object.setPrototypeOf? Yup. Everyone writing for the public non-mobile web has to do it now, it's not so bad. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: B.3.1 The __proto__ pseudo property
To clarify, since I was perhaps somewhat terse here. :-) print(eval('[{__proto__: 17}]')[0].hasOwnProperty(__proto__)); print(eval('[{__proto__:0x17}]')[0].hasOwnProperty(__proto__)); SunSpider uses eval() on JSONish input, so engines have to make that fast. Most/all engines for potential JSON-looking input (wrapped in '()' or '[]') attempt to JSON-parse the string before doing a full parse. If the JSON-parse fails (probably quickly, if it does), fall back to a full parse. If it succeeds, yay, you probably saved a bunch of time, return the resulting value. (It's no longer that simple, of course. |use strict; eval('({x:2,x:4})');| must throw a SyntaxError for duplicate property, so the hack can't be used if the caller's strict. And then http://timelessrepo.com/json-isnt-a-javascript-subset observed that JSON allows U+2028 and U+2029 where JS doesn't. So at least SpiderMonkey does a linear search for them in the string [post-JSON-parse] and falls back to the main JS parser if either's found.) The weird behavior is because JSON-parsing treats __proto__ as a regular old property. (The second case isn't JSON: hex's forbidden.) If the engine hacks JSON parsing into eval, and implements JSON.parse('{__proto__:2}').hasOwnProperty(__proto__) correctly, you get this oddity. The obvious workaround is to search for __proto__ in the eval-string and not JSON-parse if it's found. I have my doubts the SunSpider-score hit for the strstr over the entire input string can be eaten, but I could be mistaken. Summary: horrible pile of hacks for a, er, venerable benchmark. The reason for mentioning this here/now is that if quotes-means-[[DefineOwnProperty]] were standard, using the JSON parser on eval input would be fine here, and all complexity of this quirk would disappear. Or we could just add yet more modes of JSON-looking parsing. Or something. Blargh. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: B.3.1 The __proto__ pseudo property
On 04/21/2013 03:27 PM, Mark S. Miller wrote: Warning: The following is a sickening idea. I would really hate to see us do it. But I feel obliged to post it as it may in fact be the right thing to do. This suggests that, in JS as well, the __proto__ in {, __proto__: , } not be treated as a special case. Quoting it turns off the special treatment. For the lulz, what do these print in engines? print(eval('[{__proto__: 17}]')[0].hasOwnProperty(__proto__)); print(eval('[{__proto__:0x17}]')[0].hasOwnProperty(__proto__)); And considering what motivated real-world engine behaviors here, what constraints might possibly SunSpider imply? (Conceivably none, to be sure, although I have my doubts a strstr could be eaten here. Or maybe just another mode for the parser. Ha, ha, ha. Lulz, I told you, lulz!) Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Is |delete [].length| supposed to evaluate to true in ES6 (deviating from ES5)?
The current steps call the [[Delete]] method on the array with property length and assign the result to deleteStatus, ReturnIfAbrupt(deleteStatus), throw if strict mode and !deleteStatus, then return true. Should that last return-true have been |return deleteStatus| instead? Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: preventExtensions trap and its true/false protocol
On 04/02/2013 12:13 AM, Tom Van Cutsem wrote: The true/false return protocol doesn't prevent exceptions to be thrown from the trap. It's perfectly fine for the dead object proxy's preventExtensions trap to throw an object is dead exception. In fact, that's precisely what would happen if one would call preventExtensions on a revoked revocable proxy. Ah, yes, that's exactly right. Never mind! Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: preventExtensions trap and its true/false protocol
On 04/01/2013 09:41 AM, Brandon Benvie wrote: That is, the error that will be thrown from Object.preventExtensions is only specified as a TypeError; different engines can (and often do) have different error messages, and different localizations will also have different messages. This is something a developer can't hope to mimic. Note that this could also be construed as a feature, in certain cases. The dead object proxy Mozilla has, previously mentioned here (can't find a link), has all its traps throw an error with a message saying Dead object. If the trap returns true/false, it's no longer possible for preventExtensions to say that the object in question is dead, not just can't be made non-extensible. Now, whether this use case, and other cases we could conjure up with a little thought, actually motivate reserving the throw to the trap -- that's another matter. I'm just saying there are some small tradeoffs both ways here. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: preventExtensions trap and its true/false protocol
On 03/31/2013 11:02 AM, David Bruant wrote: From the developer perspective, this doesn't really add anything since it's already possible to throw from within the trap (and that's probably more explicit and clearer than returning false). That puts the onus on the trap to throw the correct kind of error, right? Admittedly this should be easy enough to get right, but it is a slight bit of extra complexity, versus having the implementation throw the correct error in one central location. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Observability of NaN distinctions — is this a concern?
Negation on at least some x86-ish systems also produces another kind of NaN, because the trivial negation implementation is a sign-bit flip. This strikes me as similar to the endianness concerns of typed arrays, except probably far less harmful in practice. I don't see what can reasonably be done about it, without effectively mandating attempting NaN-substitution whenever the value to set might be NaN. But maybe someone smarter has ideas. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Throwing StopIteration in array extras to stop the iteration
On 03/03/2013 06:53 PM, Andrea Giammarchi wrote: I had to check msdn rather than MDN since latter does not mention it while mans shows an example: http://msdn.microsoft.com/en-us/library/ie/3k9c4a32(v=vs.94).aspx The RegExp statics aren't mentioned because they're a bad idea, imposing costs of some sort on pretty much all regular expression uses. Don't use them! And, um, this is quite possibly the most awful way to find a value in an array that I've ever seen. Even setting aside the statics usage! Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Throwing StopIteration in array extras to stop the iteration
On 03/03/2013 06:49 PM, Rick Waldron wrote: Is this +1 to findIndex? Not that I much care between the two, just making sure another reasonable name is considered, but I'm not sure why it wouldn't be named find rather than findIndex. The index seems like the only bit you'd reasonably be looking to find. (Well, maybe existence, but I'd expect a name like contains for that, or just indexOf !== -1.) Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Throwing StopIteration in array extras to stop the iteration
On 03/04/2013 08:38 AM, Andrea Giammarchi wrote: I believe creating a redundant array of matches for no reason since these are retrievable in any case through the RegExp constructor, considering exec and match points to those RegExp properties anyhow, ain't needed when re.test(value) is involved. You're saving on array-construction and element-creation, but you're losing (with many to most current engines) on having to re-run the regular expression a second time to compute the match components. You're almost certainly going to lose out overall when you take this extra cost into account. Array and string creation are fast in engines these days. Regular expression matching with the intent of constructing statics info is not. Your code's also fragile against introduction of any other regular expressions within the code being demonstrated there. If someone copies your code and tries to change the === to a function-based test, they might well change it to something that uses regular expressions. That person might even be you: what's obvious now may not be obvious in the future. If re.test(value) RegExp.$1; As easy as that: 1) is *not* a bad practice and 2) is less redundant than if (re.test(value)) match = re.exec(value)[1]; To clarify the above, it's better to do: var results = re.exec(value); if (results) results[1]; those properties I believe defined in the specs does not mean those properties are bad (as I have just explained) They are not defined in spec, partly because you're mistaken about them being a good idea. Also, that does not find a thing, that find an index ... It's a fair point. Although, given non-existence, it would seem to me you'd only want a method that returns an index, and then getting the element value is just arr[index] at that point. We are programmers, we find solutions/alternatives/optimizations ... right? I'd also suggest we have the humility to recognize when we're trying to be too clever by half, as your forgotten + demonstrates. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
[].push wrt properties along the [[Prototype]] chain
Consider: Object.defineProperty(Object.prototype, 0, { value: 17, writable: false, configurable: false }); [].push(42); Per ES5, I think this is supposed to throw a TypeError. The push should be setting property 0 with Throw = true, which means that when [[CanPut]] fails, a TypeError gets thrown. No engine I can test does this, I suspect because everyone's mis-implemented an optimization. On IRC it was pointed out that http://wiki.ecmascript.org/doku.php?id=strawman:fixing_override_mistake is supposed to fix this: you should be able to shadow a non-writable property on a prototype. Or something. But there's contention there about this not actually being a mistake. (I think that contention's probably right, for what it's worth, but I digress.) But suppose it isn't, for the moment. What then of this: Object.defineProperty(Object.prototype, 0, { set: function() { throw FAIL; } }); [].push(42) I think this should throw, again because it's *setting* property 0. But again, no engine I can test actually throws for this. My gut says this is a case where every engine attempted to optimize, and optimized wrongly such that incorrect semantics resulted. The question is, since no engine's following the spec, whether the spec should change, the engines should change, or what. Given that indexed properties on Array.prototype and Object.prototype are not something anyone sane does, I tend to think changing it to [[DefineOwnProperty]] would be good. But maybe the spec really should win, and everyone should change. I dunno. Please sort this out! :-) Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Comments on Meeting Notes
On 12/04/2012 03:57 PM, Brendan Eich wrote: Allen Wirfs-Brock wrote: The timing of copying is only an issue if the function actually assigns to a formal parameter. Such assignments should be pretty easy to (conservatively) statically check for. I'm telling you what engines do. Not what they might do. I did assignment analysis in SpiderMonkey for Firefox 3.6, it was helpful in its day. I think a bunch has been ripped out because modern JITs don't need it. [...]the point I made, cited above: engines don't do it currently and feel little pressure to do so. Chicken and egg. SpiderMonkey's implementation of the arguments object functions exactly as described here for functions with strict mode code -- actually for all functions, I think. Regarding the strict mode semantics specifically, it was fairly easy to make those optimizations when I was implementing the various strict mode arguments semantics, so I did them. There hasn't been a time where SpiderMonkey's had strict mode arguments semantics, without these optimizations. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Problems with strict-mode caller poisoning
On 11/16/2012 07:06 AM, Brendan Eich wrote: d8 function g() { Object.seal(g) } d8 function f() { use strict; g() } d8 f() (d8):1: TypeError: Illegal access to a strict mode caller function. (Interestingly, Firefox does not throw on that example, so I'm not sure what semantics it actually implements.) It looks like SpiderMonkey's Object.{seal,freeze,isSealed,isFrozen} implementations do not call [[GetOwnProperty]] on each property. Cc'ing Jeff Walden. They do, sort of, but .caller doesn't fit into the [[GetOwnProperty]] system well in SpiderMonkey because, on functions that are not themselves strict (or bound), it's neither a data property nor an accessor property. That this happens to not complain vociferously is nearly happenstance at best. (I suspect it did at one time, actually, and I bet I know the bug that changed it, but it doesn't really matter in the end.) So it seems to me premature to throw on [[GetOwnProperty]] of a strict function's 'caller'. It would be more precise, and avoid the problem you're hitting, to return a property descriptor with a censored .value, or a poisoned-pill throwing-accessor .value. premature to throw on [[GetOwnProperty]](caller) on a function whose caller is strict, I assume you meant. That seems right to me. Since caller is a time-variant characteristic, it seems right for the property to be an accessor, probably existing solely on Function.prototype, and to defer all the strictness checks to when the function provided as |this| is actually invoked. Such a property is no different from anything already in the language, so I can't see how it would at all interfere with Object.observe semantics or implementation. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Problems with strict-mode caller poisoning
On 11/16/2012 01:19 PM, Jeff Walden wrote: and to defer all the strictness checks to when the function provided as |this| is actually invoked. Er, that should be and to have the 'caller' [[Get]] function check the strictness of the |this| function provided to it when that [[Get]] function is called. Too many function referents in play in all this discussion. :-\ Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: no strict; directive
On 11/16/2012 01:42 PM, Andrea Giammarchi wrote: @Oliver, if you need to retrieve the caller in order to know if it's strict or not, then everything I've read in this thread becomes kinda pointless :-( Not quite. You could imagine a system where you simply have to know if your caller is strict or not. If it is, then you don't need to track any of that info. If it isn't, then you'd need some system to compute the caller. But it's certainly not the case that you always have to keep the caller around regardless. https://trac.webkit.org/browser/trunk/Source/JavaScriptCore/runtime/JSFunction.cpp#L184 It looks like there's no gain at all using strict and the goal here is simply to get rid of these calls exec-interpreter ()-retrieve*something*FromVMCode(exec, thisObj); Just to note, knowing that it's impossible to access the caller also benefits inlining -- you don't have to be able to recompute the caller function (or all the inlined function's stack modifications) at any moment when you're in function code that's been inlined in a caller. I would provide you a link to a blog post I wrote a year or so ago with more details on this, but it's currently down. :-( Maybe I should spend the time to bring it back up now so I can pass that link along. am I wrong? Can I ask when and if it's planned to get rid of this isStrictMode() method? This, as info, would be definitively valuable ( FF and Chrome guys welcome to answer to this as well, thanks ) I wouldn't speculate as to when any engine will take advantage of this -- SpiderMonkey that I work on, or any of the others. It's still somewhat early in the JS optimization race, so it's likely there's more low-hanging fruit to be picked in all the engines, that benefits all code and not just strict mode code, before this would happen. As regards SpiderMonkey particularly, I think we have enough things on our plates now that taking advantage of this particular optimization opportunity won't happen in the next year or so. Taking advantage of this also has some interesting interactions with other functionality like debuggers, Error.stack, error messages, and so on. The simple thing, that's been done forever, is to just always track it. But there's no reason not to specialize, and optimize harder, in the cases where these complications can be worked around or set aside. In the long run, however, something like this will happen. It would be short-sighted to take on the semantic nightmare mid-stream strict mode opt-out would present, simply because engines aren't immediately taking advantage of all the optimization opportunities strict mode presents. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: no strict; directive
On 11/16/2012 02:11 PM, Andrea Giammarchi wrote: but I don't see caller being any better/worse than arguments and I believe arguments will stick around forever in any case ... so will caller, unless there's not some specific personal reason but the code just looks basically the same: find the rabbit and ta-da The arguments keyword is statically detectable (or can be hedged against in the much-worse possible use of eval), which makes it far better. fun.arguments and fun.caller are about equally bad. And to the extent there are correct semantics for fun.arguments, engines break those daily whenever optimization opportunities present themselves. In the longer run the code will not look basically the same, so arguing from what the code looks like now, in any engine, is not especially convincing. but on the practical level we all know it's going to be like that, right? I don't understand what you're saying/implying here. Could you spell it out more clearly, please? Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: no strict; directive
On 11/16/2012 02:37 PM, Andrea Giammarchi wrote: what I am saying: arguments won't disappear in 5+ years, neither will caller ... is my crystal ball correct? It's not necessary for these things to disappear completely for us to derive value from these decisions. It's only necessary for good code, that wants to be performant, to not use them. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: __proto__ and accessor descriptors
On 10/26/2012 02:30 PM, David Bruant wrote: Le 26/10/2012 22:56, Asen Bozhilov a écrit : var obj = Object.defineProperty({}, '__proto__', { get : function () {return '__proto__ getter'}, set : function (){return '__proto__ setter'} }); console.log(obj.__proto__); //[object Object] console.log(obj.__proto__ = {}); //[object Object] On Firefox Aurora, I find: __proto__ getter [object Object] According to this strawman, the output should indeed be __proto__getter then __proto__setter. Given that the result of evaluating |obj.__proto__ = {}| is the right-hand side (the return value of calling the setter is ignored), to the extent there's some determined-correct behavior here, it definitely wouldn't be to log __proto__ setter. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array.prototype.contains
On 11/03/2012 11:06 PM, Mark S. Miller wrote: On Sat, Nov 3, 2012 at 10:13 PM, Axel Rauschmayer a...@rauschma.de mailto:a...@rauschma.de wrote: (I am still sad we did not fix indexOf, lastIndexOf, and switch when we arguably had the chance.) Can you elaborate? We don’t have the chance, any more? Would anything break (or did, in tests)? I am not aware of anyone gathering any evidence one way or the other about what breakage this might cause. So it is not necessarily too late. If someone does gather actual evidence that the breakage would be small enough, I could see us reconsider this. But I doubt we would revisit in the absence of such evidence. Just to note, there was a (at least this one) long thread on the topic (well, not including switch -- I don't remember a thread that considered changing switch) back in the day, if someone's invested enough in this to read it. https://mail.mozilla.org/pipermail/es5-discuss/2009-August/003006.html Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
On __proto__ as a magical data property
If __proto__ were a magical data property, what would happen if you did: Object.defineProperty(Object.prototype, __proto__, { writable: false }); and then later: ({}).__proto__ = Object.prototype; // non-mutating mutation or ({}).__proto__ = {}; // mutating mutation or for that matter Object.prototype.__proto__ = null; // non-mutating mutation or Object.prototype.__proto__ = Object.create(null); // mutating mutation I spent a little time experimenting implementing __proto__ as an accessor property to see how the issues previously raised -- proxies, cross-global objects, and so on -- actually played out. It required surprisingly few special-case behaviors. SpiderMonkey's existing wrapper/proxy mechanism addresses those issues (through the nativeCall trap, if you're curious) without special effort. More data's always helpful, and because Firefox is at the start of a development cycle, now is the ideal time to get it. There's no substitute for data. David Mandelin and I discussed this, and we agreed to push it to the Firefox tree to get that data. We can always back it out if necessary. Jeff 0. https://bugzilla.mozilla.org/show_bug.cgi?id=770344 Note that I didn't implement the restrictions of the wiki proposal, just a straight reimplementation. This is *only* to test the as-accessor proposition. If the wiki's restrictions are deemed desirable, they can be implemented atop this patch. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: On __proto__ as a magical data property
On 07/17/2012 11:37 AM, Brendan Eich wrote: I don't know what you mean by mutating mutation. In no case is the non-writable magic property's internal setter called. Right? According to the draft semantics, it seems no. Somehow I missed that semantics had made their way into any draft, and I thought the wiki (rather, discussion in meeting minutes from April sometime) was the closest thing to a spec there was. That's nice but it doesn't address the argument that ECMA-262, not a certain implementation, should not expose a usable setter at all (never mind wrapped and monitored). You'd be on stronger ground if you poisoned the reflection API so the setter could not be extracted. I can buy the argument the setter shouldn't be exposed, more or less. I don't think it presents intrinsic *danger* except in an ocap-y sense, but maybe I'm missing some concrete example. If other engines can get on board with it -- and right now JSC and Opera's implementations are not, from what I understand -- I'm happy to see that tweak in SpiderMonkey, and in the spec. One fewer magic data property in the language still leaves magic data properties in the language, notably Array length. One fewer magic data property is also not having to alter the fundamental [[Get]], [[Put]], and [[DefineOwnProperty]] algorithms. I think changing those algorithms presents more risk than will having a function that will change an object's prototype if it passes the right tests. (And certainly more risk than if the reflection API were poisoned and the function weren't even observable.) It's true there's an element of aesthetics here, but I think this is a matter of substance as well. I suspect we'll have to agree to disagree on that point. (Particularly as, somewhat regrettably timing-wise, I'll be on vacation for a bit over a month starting tomorrow.) Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Proto-walking proposal [[SetP]] comments
In the [[SetP]] implementation on this page: http://wiki.ecmascript.org/doku.php?id=harmony:proto_climbing_refactoring In step 2, the property lookup should stop when a data descriptor of any sort, writable or non-writable is uncovered. A property closer to the start of a lookup shadows one further along the prototype chain, and these semantics don't preserve that. Step 5c should return true after calling the setter. Step 5d(i) to recheck for extensibility is redundant with [[DefineOwnProperty]]'s check of the same. Technically, only step 2 needs to be changed in order to actually make the logic sane on the first point. And the second point could be fixed with a one-line addition, and the third with a one-line removal. But the algorithm's unwieldy enough with just adding more steps (particularly to step 2), I think you want a somewhat broader refactoring. I make this proposal: [[SetP]](Receiver, P, V) When the [[SetP]] internal method of O is called with initial receiver Receiver, property name P, and value V, the following steps are taken: 1. Let ownDesc be the result of calling the [[GetOwnProperty]] internal method of O with argument P. 2. If ownDesc is not undefined, then a. If IsAccessorDescriptor(ownDesc) is true, then i. Let setter be ownDesc.[[Set]]. ii. If setter is undefined, return false. iii. Call the [[Call]] internal method of setter providing Receiver as the this value and providing V as the sole argument. iv. Return true. b. Otherwise IsDataDescriptor(ownDesc) must be true. i. If ownDesc.[[Writable]] is false, return false. ii. If Receiver === O, then 1. Let updateDesc be the Property Descriptor { [[Value]]: V }. 2. Return the result of calling the [[DefineOwnProperty]] internal method of Receiver passing P, updateDesc, and false as arguments. iii. Else 1. Let newDesc be the Property Descriptor {[[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}. 2. Return the result of calling the [[DefineOwnProperty]] internal method of Receiver passing P, newDesc, and false as arguments. 3. Let proto be the value of the [[Prototype]] internal property of O. 4. If proto is null, then define the property on Receiver: a. Let newDesc be the Property Descriptor {[[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}. b. Return the result of calling the [[DefineOwnProperty]] internal method of Receiver passing P, newDesc, and false as arguments. 5. Return the result of calling the [[SetP]] internal method of proto with arguments Receiver, P, and V. Aside from fixing the noted bugs, this makes one further notable change. When the property lookup to determine whether there's a setting conflict bottoms out at the end of the prototype chain, without finding the property, this algorithm simple defines the property on the receiver as a fully mutable property. It doesn't reget the property on the receiver to determine if anything's changed, to set the property consistent with its attributes at that instant. First, this seems more efficient. Under the current algorithm any property miss must make an effort to reget the original property, even just in case. Second, I have difficulty imagining how changes would legitimately happen, in a way that we might consider good coding style. But perhaps I'm missing some reason why this reget is a design requirement; please let me know if I've missed it. Anyway, comments welcome on this -- I'm working on implementing it now, so feedback is particularly timely for me, and I'll be able to provide implementation feedback quickly. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
A fun little spec deviation in the major JS engines
At least, if you consider |with| and |eval| fun (and who doesn't?): js var x = outer; function f() { with({ x: 17 }) eval(var x); return x; } typeof f() undefined This seems to be the behavior in every engine out there. But according to the last ES5 errata for 10.5, and in the latest ES6 draft, since x has a binding in the object environment record created when executing the |with| statement's substatement, and the object supplied to the |with| isn't the global object, the |var x| should do nothing whatsoever. Presumably given this implementation unanimity the spec should change on this point. In a certain sense this was flagged in https://mail.mozilla.org/pipermail/es5-discuss/2011-January/003882.html in acknowledging the current language to be narrowly scoped to the exact problem at hand. I'm just pointing it out so it gets addressed in the likely future changes that happen to 10.5. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: A fun little spec deviation in the major JS engines
On 01/28/2012 08:20 PM, felix wrote: It seems to me the behavior you observe conforms to spec. Hmm, yes, on second look I think you're right. I guess I was reading overfast and missed the variable environment/lexical environment distinction there. That, or it's been too long since I looked at this stuff. Probably both. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: migrating `let' and `const'
On 11/15/2011 07:17 AM, Andy Wingo wrote: SpiderMonkey appears to allow them, as does V8 with --harmony, but V8 without --harmony and JSC both abort on `const' in strict mode. If you opt into a version supporting 'let', you get 'let' functionality. If you don't, 'let' is a strict reserved keyword, so use of it is a syntax error. Thus the name is reserved for future use in code that hasn't made an effort to use 'let' functionality; but if it has indicated it wants to use 'let', that use will keep working. (Although how it works might change at the margins after standardization, as Brendan notes. But relatively minor changes in semantics are much easier to do than wholesale disabling.) Likewise, none of the major engines abort on `const' in non-strict mode. 'const' is just old, far older than 'let', and has never been guarded behind a version check. Other engines probably have mostly JS on the web to target, but SpiderMonkey has Firefox code, extension code, and so on to deal with as well. It didn't seem practical to disable it given all those other users, some of whom definitely do want to use 'const' in strict mode code. And its semantics now are close enough, as Brendan notes, if you're just using it the natural way with straight-line, run-once-per-activation code. So it works unconditionally in SpiderMonkey. (It's perhaps worth noting you can compile SpiderMonkey without 'const' support at all, although that frob's likely under-tested.) Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Wanted: standard Array function to append an array's elements to another array
On 07/31/2011 03:57 AM, Andrea Giammarchi wrote: I agree mine is more a workaround while we need a solution but it's not about Array here, it's about number of arguments limit per function so once we have pushAll in place, all other methods will still suffer the apply problem True. It seems to me the fundamental problem is exposing n-ary functionality solely through a variadic interface, and not through an interface accepting an array. Such interfaces are moderately handy for quick hacking. Yet since they're not much handier than adding [] around the variadic arguments, I don't see that they provide much value. Which still leaves the problem of the existing variadic methods, of course... Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Wanted: standard Array function to append an array's
On 07/29/2011 05:01 AM, Andrea Giammarchi wrote: I may be late here, but what's wrong with firstArray = firstArray.concat(secondArray); ? If there are still problems I would say no magic method can solve them, isn't it? That creates a new array rather than mutate the array originally referred to by |firstArray| here, and I originally specified that only mutation was acceptable, because creating a new array requires extra space proportional to the length of |firstArray|. But I assume you're arguing that an engine could recognize that the copy could be transformed into a mutation. You'd have to prove that was the *only* reference to the original array in order to perform that optimization, or prove that it was observably correct to do that. Such analysis is tricky and costly time-wise. Relying on it would also be performance-fragile. If you were pushing incrementally onto an array (say, because you were appending arrays of bytes read from a network stream, saving them up to be processed all at once), the entire process is O(n) in bytes processed with push-through-mutation. But it's O(n**2) with push-by-copying. Thus you'd have to require the developer to understand when the optimization could be applied, in order to structure his code such that it would be applied. That level of understanding of compilers, and of the algorithms actually used to implement them (which won't be publicly available for some engines), seems way way beyond wh at can reasonably be expected of web developers. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Wanted: standard Array function to append an array's elements to another array
On 07/29/2011 05:22 AM, Andrea Giammarchi wrote: to avoid apply limits is actually trivial More or less, yes. But it requires the developer to anticipate the concern in advance that the elements being appended might consume all available stack space. I don't think most developers think at all about the size of the stack, or about its being limited, except when they write a recursive algorithm, intentionally or inadvertently, and neglect to correctly implement the base case. I certainly forgot about this concern when I wrote the buggy code which initially triggered this request, and I think it's reasonably apparent there's a problem when even a JS engine implementer makes this mistake. Past that, your MAX_LENGTH constant would have to be lower than the max length across all JS engines cared about. I find it concerning that something as simple as extending an array with the elements of another array would require an implementation-dependent workaround, when this operation is built-in functionality in other mainstream languages where mutation is common: C++: vectorT::insert http://www.cplusplus.com/reference/stl/vector/insert/ C#: ListT.AddRange http://msdn.microsoft.com/en-us/library/z883w3dc.aspx#Y570 Java: ListE.addAll http://download.oracle.com/javase/1.5.0/docs/api/java/util/List.html Perl: push http://perlmeme.org/howtos/perlfunc/push_function.html Python: list.extend http://docs.python.org/tutorial/datastructures.html Ruby: array.concat http://www.ruby-doc.org/core/classes/Array.html#M000224 Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Wanted: standard Array function to append an array's elements to another array
On 07/27/2011 10:12 PM, Mark S. Miller wrote: We could debate the pros and cons of this sort of chaining convention in general. However, in this case I think the more important issue is API consistency. I was thinking this might actually be more consistent, to return this. Consider Array.prototype.sort, for example. (Or maybe the new length would be more consistent with Array.prototype.push, on second thought.) It does seem a reasonable guideline to return something when something can be returned, and not to return nothing. Returning |undefined| was just my not having thought of an obviously meaningful and plausible value to return. But I'm fine with any of these return values -- the pushing-the-array-contents business is the only truly important part of the method to me. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Wanted: standard Array function to append an array's
On 07/27/2011 01:26 PM, John-David Dalton wrote: @Jeff In reply to https://mail.mozilla.org/pipermail/es-discuss/2011-July/016124.html, which engines have problems with `firstArray.push.apply(firstArray, secondArray)` ? Shouldn't a bug report be filed for the specific JS engine or the spec be clarified on the subject (String.fromCharCode too) instead of adding another method to Array.prototype? Here's a testcase: (function test() { var big = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf]; while (true) { try { var before = big.length; big.push.apply(big, big); if (big.length !== before + before) throw before; } catch (e) { return big.length + : + e; } } })() If the apply call throws an exception, a string consisting of the array length before the push failed, and the exception thrown, is returned. If the push call doesn't push all the elements it should have pushed,a string consisting of the array length after the push, and the array length before the faulty push, is returned. The testcase demonstrates failures with these engines: SpiderMonkey's max argument-count is currently something like 480k, so pushing an array of 512k elements onto another array will only push the first 480k-ish. (This is being changed so that an exception is thrown, shortly. It has caused at least two quite unexpected bugs. Probably someone else has stumbled across the problem before, but I don't know for sure.) In v8 an exception is thrown sometime between secondArray having length 128k and 256k. Nitro copied SpiderMonkey, although its max-arg-count isn't as high as SpiderMonkey's, so it will only push the first N elements of a really big array. IE10 throws an exception for a push of the elements of an array somewhere between 128k and 256k. IE9 throws similarly, except between 256k and 512k. Of the major engines, only Opera seems to have no problems here. I'm not sure why this is. But ignoring Opera, everyone fails this. And the reason, I believe, is not that it's a quality of implementation issue: it's that the general way to implement this butts up against ingrained implementation choices, and different engines will quite rationally behave in different ways in response. push.apply is simply not a reliable substitute for a built-in method to push the contents of an array into another array. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Wanted: standard Array function to append an array's elements to another array
If I have one array, and I want to append the contents of an arbitrary array to it, and I don't need the unmodified first array after appending the second array's elements to it, I have three options. First, I can use Array.prototype.concat to create a new array consisting of the first array, then the contents of the second. But this creates a new array rather than mutating the first array, so it potentially wastes memory proportional to the size of the first array, barring complicated heuristics to recognize and avoid the waste. Potentially worse, if any element of the second array is an Array, instead of that array being appended, its elements will be appended. Second, I can use Array.prototype.push: Array.prototype.push.apply(firstArray, secondArray); This avoids the memory-wastefulness concern, and it doesn't treat Array items specially. But it introduces a third concern: the JavaScript stack size limit, if the second array contains a particularly large number of elements. This might manifest itself as causing a stack overflow exception, or it might cause only some of the elements of the second array to be appended (an arguably buggy mitigation mechanism, but one some engines use, at least currently). Third, I can use Array.prototype.splice, passing in |start = length| and |deleteCount = 0|. But splice too encounters the stack size limit problem. Worse, because its arguments are (start, deleteCount, newElt1, newElt2, ...), constructing the array of arguments with which to apply the splice method seems to require complicated copy-on-write array-element-sharing to mutate the first array without consuming twice the first array's memory, or some other tricky scheme. For such schemes to be effective here, the programmer would have to structure his code pretty carefully, being sure to only use Array.prototype.unshift, say, to implement it. And there's a bootstrapping problem to creating the array of arguments to supply to splice in order to append the elements of an array to the first array. I see no problem-free way to append an array's elements to another array without doing it manually. That's not hard, but it's error-prone, and it's much trickier to recognize and correctly optimize. I think there should be a way to append elements of an arbitrarily sized array to another array, mutating that array in-place, without consuming excess memory. I'm not too concerned about its precise semantics or about what it's named. For a starting point I'll propose Array.prototype.pushAll (or extend, following Python, but again, I don't really care about the exact name right now): Object.defineProperty(Array.prototype, pushAll, { enumerable: false, configurable: true, writable: true, value: function pushAll(other) { use strict; var t = ToObject(this); var length = ToUint32(t.length); var otherLen = other.length; for (var i = 0, j = length; i otherLen; i++, j++) t[j] = other[i]; t.length = j; return void 0; }, }); Comments? Suggestions? Requests for changes? I also had the thought that it might be nice to be able to push a subrange of the elements of an array. You could do that by adding optional |start, length| or |start, end| arguments to the method, with corresponding implementation changes. I'm not sure whether this would be useful enough to warrant the complexity, but it would be easy to add if people thought it made sense. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Wanted: standard Array function to append an array's elements to another array
It's perhaps worth noting that this problem also occurs with String.fromCharCode. I suspect the need for a version of |String.fromCharCode.apply(null, codesArray)| that always works, even for super-big |codesArray|, is rather smaller than for the similar Array.prototype.push concern. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: JavaScript terminology: non-function-valued property
On 07/22/2011 03:16 PM, Mike Shaver wrote: Which primitives have own properties? I thought even str.length conceptually came from the prototype. Spec-wise, it comes from the boxed String object created when you attempt to look up a property on a primitive string. It's the same for str[0] and so on. (Serious implementations probably wouldn't actually box up the primitive in either case, of course, and would have fast-path logic.) Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: JavaScript terminology: non-function-valued property
On 07/22/2011 04:13 PM, Axel Rauschmayer wrote: In strict-mode, this isn’t boxed in, say, String.prototype.* methods. But I don’t know how/whether that reflects the spec. This is not quite precisely true. See the second algorithm in 8.7 GetValue(V). If you implement exactly the steps in the spec, the boxing occurs whenever you look up a property on a primitive (step 1 of that algorithm) -- be that a data property whose value is a method, a data property whose value isn't a method, or an accessor property. It happens, however, that that boxed object itself is never directly exposed to code in the program being executed. So it's possible for an implementation to never actually box |this| in step 1, so long as it appears to behave as if it did. Note that if you have an accessor property looked up this way, the |this| seen, if |this| is boxed because the accessor is a function whose code is non-strict, is not *by the exact spec algorithm* the same as the object created in step 1 in the spec. But again, because the object in step 1 is never exposed, an implementation might box up only one object for both uses. (Or none, even, if it can get away with such an optimization -- say, because the accessor function never evaluates |this|.) Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array.prototype.concat result length (ES5.1)
On 07/14/2011 10:04 AM, Allen Wirfs-Brock wrote: It is probably a bug, because array index based operations generally warp around to 0 at 2^32. Freudian slip? :-D Easiest fix is to just add the length-set to concat. For a quick ES5 erratum that seems best to me. Removing all the RangeError stuff, and making array indexes just non-negative integers, would be nice for ES6 or similar. I suspect changing that won't break anyone worth caring about, although I do know some people have taken the time to care about this in the past (mostly in a spec-nut way :-) ): http://hexmen.com/blog/2006/12/push-and-pop/ Without having thought too hard about exactly what would be involved, I suspect the amount of stuff you'd need to adjust, and the complexity of checking for sane behavior in all cases (including some of the 2**52 upper-bounding edge cases, depending on what new semantics you might want for array indexes or whatever), would make it unwise to try for ES5 errata. But I could well be wrong about this, so I wouldn't necessarily write off that possibility. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Should Decode accept U+FFFE or U+FFFF (and other Unicode non-characters)?
Reraising this issue... To briefly repeat: Decode, called by decodeURI{,Component}, says to reject %ab%cd%ef sequences whose octets [do] not contain a valid UTF-8 encoding of a Unicode code point. It appears browsers interpret this requirement as: reject overlong UTF-8 sequences, and otherwise reject only unpaired or mispaired surrogate code points. Is this exactly what ES5 requires? And if it is, should it be? Firefox has also treated otherwise-valid-looking encodings of U+FFFE and U+ as specifying that the replacement character U+FFFD be used. And the rationale for rejecting U+FFF{E,F} also seems to apply to the non-character range [U+FDD0, U+FDEF] and U+xyFF{E,F}. Table 21 seems to say only malformed encodings and bad surrogates should be rejected, but valid encoding of a code point is arguably unclear. At least one person interested in Firefox's decoding implementation argues that not rejecting or replacing U+FFF{E,F} is a potential security vulnerability because those code points (particularly U+FFFE) might confuse code into interpreting a sequence of code points with the wrong endianness. I find the argument unpersuasive and the potential harm too speculative (particularly as no other browser replaces or rejects U+FFF{E,F}). But the point's been raised, and it's at least somewhat plausible, so I'd like to see it conclusively addressed. A last note: two test262 tests directly exercise exercise the Decode algorithm and expect that these two characters decode to U+FFF{E,F}. (I think at a glance they might also allow throwing, tho it's not clear to me that's intentional.) http://hg.ecmascript.org/tests/test262/file/b4690e1408ee/test/suite/sputnik_converted/15_Native/15.1_The_Global_Object/15.1.3_URI_Handling_Function_Properties/15.1.3.1_decodeURI/S15.1.3.1_A2.4_T1.js http://hg.ecmascript.org/tests/test262/file/b4690e1408ee/test/suite/sputnik_converted/15_Native/15.1_The_Global_Object/15.1.3_URI_Handling_Function_Properties/15.1.3.2_decodeURIComponent/S15.1.3.2_A2.4_T1.js Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: prototype for operator proposal for review
On 05/17/2011 09:49 PM, Luke Hoban wrote: It seems the syntax is perhaps aiming to avoid needing to allocate an intermediate object – but I imagine engines could potentially do that for Object.make and friends as well if it was important for performance? It's probably possible to do that. But such hacks are rather fragile. I suspect this would take roughly the form of the way SpiderMonkey optimizes Function.prototype.apply, which is roughly to look for calls of properties named apply and do special-case behavior with a PIC in the case that that property is actually |Function.prototype.apply|. It takes some pretty gnarly code, duplicated two places (possibly a third, but that might not be necessary), to make it all happen. That sort of pattern certainly can be repeated if push comes to shove. But I believe doing so is far inferior to dedicated, first-class syntactical support to make the semantics absolutely unambiguous and un-confusable with anything else. In this particular case, I suspect implementing a PIC that way would be even gnarlier, because it wouldn't just be a PIC on the identity of the |Object.make| property, it'd have to also apply to computation of the arguments provided in the function call (or a not-call if you're using a PIC this way). That too can probably be done. But it'd be pretty tricky (thinking of things like the PIC only being applicable if the argument is an object literal, and of it being mostly inapplicable if it's anything else). And if you wanted to extend that to apply to more functions than just a single Object.make function, the hacks will be even more complex, possibly not even by a constant increment. And of course this would also make it harder for IDEs and such to give good first-class syntax highlighting here, because the syntax for this would be ambiguous with user-created stuff. Anyway, food for thought. And I know others here are more familiar with this than I am, so please chime in with more if you have it, or corrections if you have them. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Inner functions and outer 'this' (Re: That hash symbol)
This is an interesting idea, never heard of it before. That said, it seems a better start for brainstorming than as an end of it. The previously-mentioned concerns about numbering being fragile seem real to me. Further, how would this interact with eval introducing (or in some systems even removing) lexical bindings? (Or maybe eval doesn't matter if this only applies in a new language mode with no eval-like construct -- I'm not up-to-date on how eval interacts with the latest language proposals.) Nevertheless this 35-year-old idea seems fresh in the context of ECMAScript development, and worth thinking about, so thanks for bringing it up. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: That hash symbol
On 03/26/2011 07:44 PM, Brendan Eich wrote: Non leading-char solutions have the disadvantage of using some other kind of bracketing -- e.g. `a,b { return a + b; }` This is ambiguous too. A comma expression followed by a block (if in an outer function, the return is legal). I might be misreading, but I think Wes meant to have ` as a bracket-y character, such that on seeing it you switch to argument-parsing mode until you hit '{', or something like that, then end the entire thing with another ` (bracket-y character). There's no ambiguity there that I can see, although it has other issues, and wasn't seriously proposed anyway (as I read Wes). Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ECMAScript spec assertion fails when binding is deleted?
I think you've rediscovered the bug mentioned in the list thread titled Assigning to eval-introduced local bindings outside strict mode, and an ES5 spec bug, spanning 20101124-20101126. I don't know whether any followup happened to fix that or not in the spec, haven't been concerned enough to follow up and check. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: iteration order for Object
On 03/12/2011 12:02 AM, Brendan Eich wrote: Take it from me, JS objects are not hashmaps and any would-be implementor who tries that and tests on real code is quickly disabused of the notion. It's not going to change, for named properties or any kind of property name. This is true. It is also the view of people who are significantly closer to implementations than most web developers are. HashMap is still probably the better abstraction for most people's purposes. It's not best for all, certainly, as some people people either reverse-engineer the enumeration order or find one of the places that happens to document it. (MDN documents the behavior as an implementation extension at least one place if memory serves. The dime-a-dozen DHTML-espousing site from which I originally learned JS didn't document it.) Yet a substantial number of people never learn of the property ordering behaviors in web browsers. So while HashMap is far from what web-quality implementations do, it is generally (there are certainly exceptions) not far from how web developers use objects. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: iteration order for Object
On 03/11/2011 02:07 PM, Charles Kendrick wrote: Your perspective is common in a group like this - very spec and standard focused. Isn't it fun to bash those developers? Everyone's doing it.. I hope you realize it's irrelevant though? Insinuating bad faith (Isn't it fun and Everyone's doing it) may not be a successful strategy for swaying others to your point of view. Just saying. And I tend to agree with David Bruant about the makeup of the list being lightly-involved developers, true standardistas, implementers, spec writers, and more: a fairly mixed bunch with lots of different motivations and goals, to which few generalized sentiments can fairly be attributed. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: iteration order for Object
Another idea might be to introduce OrderedObject or somesuch with guaranteed enumeration order. You might lose object literal support (although that could be readded), but that's the only loss that comes to mind after brief thought. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: iteration order for Object
On 03/10/2011 06:11 PM, Boris Zbarsky wrote: You may want to read https://bugzilla.mozilla.org/show_bug.cgi?id=594655 and https://bugzilla.mozilla.org/show_bug.cgi?id=611423. People are running into performance issues due to lack of such special treatment today. Further to these points, it is possible that Firefox might change its property storage system to address bugs like these such that property enumeration order changes. This would be https://bugzilla.mozilla.org/show_bug.cgi?id=586842. I am not saying anything about how likely or unlikely this is. I haven't really started to research the problem or brainstorm about potential solution space yet. But we do see problems with arrays with non-index, non-length properties, and it's certainly possible that a fix which permits extra, non-indexed properties to be added to arrays without notably de-optimizing property storage, and subsequent property access, may affect property enumeration order. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Multiple globals and direct/indirect eval
A few months back I noticed an interesting interaction between how direct eval is defined and multiple globals. What happens if, in one global, you call an eval from another global as if it were a direct eval? var indirect = otherGlobal.eval; eval = indirect; print(eval(this) === this); print(indirect(this) === this); Standards currently don't say what should happen here because it's multiple globals, so what should this do? IE9 and Opera print false both times for this. Firefox prints true, then false -- but only if the global and otherGlobal are from the same origin (so on pages with the same scheme/host/port, more or less). If they're from different origins (but have set document.domain to the same value) Firefox too prints false. Chrome and Safari throw an EvalError calling another window's eval (for both direct and indirect calls) without that window as |this| for the call. The Chrome/Safari behavior would resurrect the vestigial EvalError, so I don't think it makes sense. It also contradicts the specification of the steps in the definition of the eval function. Firefox's behavior is inconsistent and seems not amenable to host-agnostic specification as ECMA would require. Thus we are left with the IE9/Opera behavior, which seems sensible and natural to me: an eval function should always act in the context of the global from which it came. What needs to be done to standardize this behavior? And more generally, what needs to be done to begin standardizing multiple globals in ECMAScript, including issues like this one? Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Multiple globals and direct/indirect eval
On 03/03/2011 04:41 PM, Allen Wirfs-Brock wrote: I think your real question reduces to this: //none strict mode code globalObj= function() {return this}(); print(otherGlobal.eval(this) === globalObj) //?? The two different calls and the indirect name in your example may make the question seen like it is about something else (direct/indirect eval). Not quite so. For the example I gave, yes -- but you could see the direct/indirect distinction by putting the code I provided inside a function (and a little more gussying to demonstrate behavior better): var global = this; function f() { var indirect = otherGlobal.eval; eval = indirect; print(eval(this) === this); print(eval(this) === global); print(eval(this) === otherGlobal); print(indirect(this) === this); print(indirect(this) === global); print(indirect(this) === otherGlobal); } new f(); IE9/Opera prints false/false/true and false/false/true. Chrome/Safari throws EvalError every time. Firefox prints true/false/false and false/false/true if otherGlobal is same-origin, false/false/true and false/false/true if otherGlobal is different-origin-but-same-document.domain. A more generally, do built-in functions capture their global environment at the time of their creation or do they they operate in the dynamic context of an ambient global environment. I hope it is the former. An example of the more general question would be: print((Object.getPrototypeOf(new otherGlobal.Array(0)) === Array.prototype) I believe the second example prints false for all browser implementations. This is an orthogonal issue, I believe, but I might as well respond since it's being discussed. There's a Firefox 4 bug that makes this not the case, ran out of time to fix it for release. It'll be fixed in 5.0, and I could imagine I might get a fix for it in a 4.0 point release, although with a fast release cycle that may not be necessary. If I recall correctly Nitro may be buggy this same way as well. I think Chrome/IE9/Opera did not demonstrate the bug in my testing. But in any case, printing false there is in my opinion the correct behavior. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Question regarding ES5
On 02/16/2011 05:32 PM, Irakli Gozalishvili wrote: I was under the impression that inherited properties can be overridden, regardless of their write-ability on the __proto__. Here's another take on this -- same idea, just another statement of it. You can override any inherited property. You just have to be explicit that you *are* overriding. As you'd do if the inherited property were an accessor get/set pair, so you do if the inherited property is not writable. If you want to override, don't set the property by =, *define* it with Object.defineProperty. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: String.prototype.repeat
On 01/09/2011 06:02 AM, Jorge wrote: Or perhaps to overload * ? 'a' * 5 - a ? Probably a bridge too far. Operator overloading this way results in all those weird implicit conversion behaviors we all know and love (not), true. But at this point there's the matter of compatibility: '3' * 5 - better produce 15 That sort of conversion isn't an entirely unreasonable thing to do, in all honesty, given that implicit conversion is here to stay at this point. I'm not opposed to making it easier to get a repeated string. Yet I admit I'm not so concerned about it that adding to the language itself seems warranted, when (as demonstrated) it's easy for the developer to do so himself. Aside from possibly a very small increase in performance if the repetition factor is large (depending on the implementation), and the functionality being built-in and thus more convenient, I'm not sure what a repeat method in the specification buys you over what you can do for yourself. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: 15.3.4.3 Function.prototype.apply (thisArg, argArray)
Check out the ES5 erratum -- steps 5 and 7 have been removed. http://wiki.ecmascript.org/doku.php Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ES5 errata submission
On 10/27/2010 07:24 PM, Michael Dyck wrote: If I find bugs in the ECMAScript Language spec (bugs that aren't already reflected in the July 31st Errata doc), what should I do? Post 'em here, that's what everyone else has done. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: No more modes?
On 10/14/2010 08:29 AM, Brendan Eich wrote: Thus there is already one bit of opt-in versioning state in ES5, which must be carried from direct eval's caller to callee. SpiderMonkey currently does this, but fairly shortly (I have patches) it will not. The eval *function*'s implementation will always perform indirect eval, and only the eval opcode will perform direct eval. (We could statically distinguish strict+direct from non-strict+direct, too, with a separate opcode, but since it's trivial to query the currently executing script's strictness, runtime detection seems better than burning an opcode.) That's only SpiderMonkey, of course, but as far as I can tell the concepts are applicable to any ECMAScript implementation. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Reserved word property access and line breaks
On 08/29/2010 03:28 PM, Douglas Crockford wrote: For what it's worth, JSLint does not tolerate any whitespace between . and a property name. Tangential, but does JSLint then require either long sequences of property accesses and method calls to occur all on a single line or to always be broken with . and subsequent property name starting new lines? For example, if this example must include a line break, at that dot-location, is this the only way JSLint would permit it to be broken? var b; var a = b.c.d.e.f.g().h().i() .j().fdsfadsfdasfasdafds().basd(); (I actually prefer this to ending the line with ., but the argument for dot-at-end seems reasonable enough to me that I'm surprised JSLint would mandate the other way.) Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Property Iteration in JSON serialization
On 10/13/2009 10:54 PM, Luke Smith wrote: Currently FF3.5.4 doesn't properly apply replacer functions, but Safari 4, WebKit, IE8, and Chrome 3 work fine for this task. How precisely are replacer functions not properly applied in Firefox? I remember reporting at least one bug on the replacer-function implementation that was fixed for 3.5 or a beta of it, and to the best of my knowledge they work fine, outside of a few cases such as for circular data structures (and the semantic difference there, if you're not looking for it, probably won't matter much anyway). Have you reported a bug for this at bugzilla.mozilla.org? Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Typo in Decode, step 4.d(vii)(8)
If Octects does not contain a valid UTF-8 encoding of a Unicode code point throw a URIError exception. s/Octects/Octets/ Maybe too late for ES5 (except in errata?), but certainly for ES6. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Should Decode accept U+FFFE or U+FFFF (and other Unicode non-characters)?
I was looking at how SpiderMonkey decodes URI-encoded strings, specifically to update it to reject overlong UTF-8 sequences per ES5 (breaking change from ES3 that should generally be agreed to have been necessary, not to mention that existing implementations were loose and strict inconsistently). After SpiderMonkey made that change I noticed some non-standard extra behavior: U+FFFE and U+ decode to the replacement character. ES5 doesn't say to do this -- the decode table categorizes only [0xD800, 0xDFFF] as invalid (when not in a surrogate pair) and resulting in a URIError. (Prose in Decode says If Octects does not contain a valid UTF-8 encoding of a Unicode code point, which might be interpretable as saying that the UTF-8 encoding of U+FFFE isn't valid and therefore a URIError must be thrown if you squinted.) U+ is not a valid Unicode code point, and U+FFFE conceivably could confuse Unicode decoders into decoding with the wrong endianness under the right circumstances. Theoretically, at least. Might it make sense to throw a URIError upon encountering them (and perhaps also the non-code points [U+FDD0, U+FDEF], and maybe even the code points which are = FFFE mod 0x1 as well)? Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Clear bug in 15.10.6.2 step 17
17. Call the [[DefineOwnProperty]] internal method of A with arguments length, Property Descriptor {[[Value]]: n + 1, [[Writable]: true, [[Enumerable]]: true, [[Configurable]]: true}, and true. This is attempting to define an enumerable, configurable length property on an array, which will throw an exception trying to change the configurability of a non-configurable property. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: [[DefineOwnProperty]] wording nit
On 17.9.09 12:15 , Jason Orendorff wrote: The difference shows up in step 7b, whose wording is: Reject, if the [[Enumerable]] fields of current and Desc are the Boolean negation of each other. Under the first interpretation, if there is no [[Enumerable]] field in Desc, then never Reject. Under the second interpretation, if there is no [[Enumerable]] field in Desc, *and* if current.[[Enumerable]] is true, then Reject. I think you have the two interpretations reversed here; under the second interpretation (the one that doesn't seem reasonable to me), if [[Enumerable]] is missing, we never Reject. Er, yes, I did. Past email to this list makes clear the first interpretation was the desired one. (assuming you mean the second interpretation) The one I meant was the result of any comparison which evaluates desc.[[Something]] must be false. I'm not going to try to number this, given the mixup in the email. :-) Yow. This is very unintuitive. To me, the spec seems to say the opposite of what's intended here. I don't disagree! Perhaps modifying step 7b to explicitly say Reject, if [[Enumerable]] is present in Desc and..., is a less arcane approach to fixing this. (That might not be the only change needed though.) This isn't what I'd thought we meant, but it seems to be the newly-adopted change in errata, and indeed I prefer it to the one I thought we meant -- much more intuitive. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Array comprehension syntax
On 13.9.09 11:56 , Olav Kjær wrote: While experimenting with code-completion for ECMAScript I noticed a limitation with array comprehension syntax. The syntax as proposed (and implemented in Mozilla) has the output expression before the loop and filter: [i.toString() for each (i in [1,2,3]) if (i != 2)] The problem is that the variable i in the output expression is defined by code to the right of it. How do you address the following function? function foo() { i = 3; var i; return i; } Or this one? function foo() { try { var i = 2; throw i; } catch (e) { return i; } } Name before declaration is a problem already posed by the existing language syntax, isn't it? Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
[[DefineOwnProperty]] wording nit
If a field is absent then the result of any test of its value is logically false. I believe there are two plausible ways to interpret this: any evaluation of desc.[[Something]] when there is no [[Something]] field returns the value false, or the result of any comparison which evaluates desc.[[Something]] must be false. The difference shows up in step 7b, whose wording is: Reject, if the [[Enumerable]] fields of current and Desc are the Boolean negation of each other. Under the first interpretation, if there is no [[Enumerable]] field in Desc, then never Reject. Under the second interpretation, if there is no [[Enumerable]] field in Desc, *and* if current.[[Enumerable]] is true, then Reject. Past email to this list makes clear the first interpretation was the desired one. Here's a wording proposal which, I think, admits only the first interpretation: If a field is absent, then the result of any test which uses that field's value is logically false. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
15.2.3.4 Object.getOwnPropertyNames misformatting
The steps are numbered 1-8, but 5-7 are clearly intended to be a substep of 4. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Another ES5 harness bug
http://es5conform.codeplex.com/sourcecontrol/changeset/view/55693?projectName=ES5conform#816017 A number of tests include comments noting that the test function must be executed such that this is the global object. As the harness is currently implemented, this isn't the case -- this is the test harness object itself. This breaks a number of tests, of which the example following this email is representative. Here's a patch to address this problem in the harness and to fix a few tests (only the ones I was immediately examining) to work correctly with it: http://web.mit.edu/jwalden/www/es5-harness.diff What needs to happen for this to be fixed upstream? Jeff -- Test 15.2.3.3-4-10 Description Object.getOwnPropertyDescriptor returns data desc for functions on built-ins (Global.decodeURIComponent) Testcase function testcase() { var desc = Object.getOwnPropertyDescriptor(this, decodeURIComponent); if (desc.value === this.decodeURIComponent desc.writable === true desc.enumerable === false desc.configurable === true) { return true; } } Precondition function prereq() { return fnExists(Object.getOwnPropertyDescriptor); } Path ../TestCases/chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-10.js ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Annex C bullet two tpyo
to an accessor property with the attribute value {[[Put]]:undefined} s/Put/Set/ (I'm guessing the setter field used to be [[Put]] until someone realized how awesomely confusing it would be for both objects and property descriptors to have a field with the same name, one of which might call the other?) Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Annex C bullet two tpyo
On 4.9.09 03:02 , Jeff Walden wrote: to an accessor property with the attribute value {[[Put]]:undefined} s/Put/Set/ Also in the note in 11.13.1. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
(function foo(){}).propertyIsEnumerable(prototype): true or false?
ES3, 15.3.5.2, says the prototype property of function instances is enumerable. ES5, 13.2 step 17, says the prototype property of function instances is not enumerable. Was this change intentional, and if so, can someone point me to discussion of the change? I don't care one way or the other, but given past paranoia over incompatible changes, this change seems somewhat gratuitous. Was this done to ease enumeration of properties on function instances, perhaps? Maybe that's enough motivation, but I don't see natural use cases for doing so. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Initial ECMA formated ES5 draft available
On 22.8.09 14:00 , Allen Wirfs-Brock wrote: 15.2.3.7 Object.defineProperties “atomic†processing clarified. This still needs further clarification on how to address definition of properties on objects with custom [[DefineOwnProperty]] hooks, as earlier alluded to by David-Sarah Hopwood. I think a restriction on what custom definitions of [[DefineOwnProperty]] may do is in order, so that atomicity can actually be implemented; I'm not sure what that restriction should be, precisely. Simply saying [[DefineOwnProperty]] must not have side effects would directly contradict the JSClass.addProperty hook in SpiderMonkey by which property definitions may be censored, such that the value that was set can be changed by the hook. I don't know whether this is a problem inherent to any DOM properties, but I would be surprised if it isn't. On the other hand, this hook supports arbitrary actions, which seem entirely out of the question as supportable. (I'm considering an ex post facto restriction that the only immediately observable side effect must be a modification of the property's value as an immediate stopgap. This would allow observable side effects after Object.defineProperties returns, but I care about this only insofar as it makes partial rollback impossible to implement, and this invalidates as little previously-permissible hook behavior as possible.) In any case, featureful implementations which in one form or another support modification of the effective behavior of [[DefineOwnProperty]] can't really implement Object.defineProperties as currently written, not without violating the atomicity requirement or making assumptions about potential custom behaviors. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: The precise meaning of For each named own enumerable property name P of O
On 12.8.09 14:33 , Allen Wirfs-Brock wrote: ES5 section 12.6 (for-in statement) says: That's specifically for the for-in statement in the language, not for a term of art used in other locations in the specification. If we want to adopt the definition, I think this should either be noted in 5.2 or described in some sort of prefatory statement in 15.2.3. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss