Array extras functionality for iterators
ES5's existing array extras make working with arrays a joy. However, sometimes arrays are not the right tool for the job. Perhaps you want lazy evaluation semantics (generators). Or perhaps you want to communicate that the list is immutable (compare .NET's `IEnumerableT` or Java's `IterableT`). ES Harmony seems to have the answer: iterators! Like `IEnumerableT` or `IterableT`, they are the most basic primitive of iteration. Yay! But, if my `fetchAllProducts()` method returns an iterator, I don't get my array extras. Sad. --- This may be solvable in library-space, but the iterator proposal doesn't seem to have an Iterator.prototype I could extend. So we end up with unfortunate underscore-style wrappers: _(iterator).chain().map(mapper).some(predicate).value() _.some(_.map(iterator, mapper), predicate) I propose adding the array extras to any iterator (in some way), such that we can have syntax similar to the following: iterator.map(mapper).some(predicate) // returns an iterator The methods I would like to see are: * every, filter, forEach, map, reduce, reduceRight, some * Optionally: join, toString * Controversially: sorted, reversed (non-mutating versions of sort and reverse) What do you think? -Domenic ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Array extras functionality for iterators
I'd say every and other methods like that should take another argument that specifies the number if times to test. This seems reasonable. Preferably that parameter would be optional, since the majority of the time my iterators will not be derived from infinite generators (and I know this). Otherwise I'd just keep passing `Infinity` as the third argument to my methods. Is it possible to detect infinite generators ahead of time? My intuition says no. map and filter clearly would be very useful. I'm not sure about the others. Losing the others would be a shame. As I mentioned, much of the time I want to expose something with the semantics of an iterator, even if internally to my module or class I am storing the data as an array. So even if infinite generators cause problems for implementing `every` et al., the vast majority of real-world iterators would not be derived from infinite generators. Thus my above desire for the extra argument being optional. Currently in our codebase, we have a number of these methods (like `fetchAllProducts()`) that return `slice()`ed copies of internal arrays, since we don't want to expose the arrays directly. (Iterators would of course be the best solution here.) Over the course of 77K LOC, the only methods we don't use on the products collection are `join`, `reduceRight`, `reverse`, and `toString`. And we do use `join` on some of the simpler collections (`fetchProductTags()`). So they're all useful! -Domenic On Sat, Feb 4, 2012 at 10:06 PM, Michael A. Smith mich...@smith-li.com wrote: Sorry for the resend. Meant to include the list. I like this idea a lot! However, what would be the correct behavior of a method like 'every' on an infinite generator? -Michael A. Smith On Fri, Feb 3, 2012 at 3:54 PM, Domenic Denicola dome...@domenicdenicola.com wrote: ES5's existing array extras make working with arrays a joy. However, sometimes arrays are not the right tool for the job. Perhaps you want lazy evaluation semantics (generators). Or perhaps you want to communicate that the list is immutable (compare .NET's `IEnumerableT` or Java's `IterableT`). ES Harmony seems to have the answer: iterators! Like `IEnumerableT` or `IterableT`, they are the most basic primitive of iteration. Yay! But, if my `fetchAllProducts()` method returns an iterator, I don't get my array extras. Sad. --- This may be solvable in library-space, but the iterator proposal doesn't seem to have an Iterator.prototype I could extend. So we end up with unfortunate underscore-style wrappers: _(iterator).chain().map(mapper).some(predicate).value() _.some(_.map(iterator, mapper), predicate) I propose adding the array extras to any iterator (in some way), such that we can have syntax similar to the following: iterator.map(mapper).some(predicate) // returns an iterator The methods I would like to see are: * every, filter, forEach, map, reduce, reduceRight, some * Optionally: join, toString * Controversially: sorted, reversed (non-mutating versions of sort and reverse) What do you think? -Domenic ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Array extras functionality for iterators
someVeryLargeArray.iMap(someFunction); // Lazy, guaranteed only to be iterable How about `someVeryLargeArray.asIterator().map(someFunction)`? -Domenic ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: lexical for-in/for-of loose end
This seems like a highly compelling argument. I hope I'm not the only one who thinks the existing behavior of `for(;;)` makes sense. Granted, that comes from understanding the detail that closures close over variables and not values, which most users will not. But in general, `for(;;)` makes it very clear that there's a single mutating variable, which the desugarings proposed here seem to overcomplicate and contradict. As exemplified by the comments to Eric's blog post, the current behavior is not very astonishing to many developers, and once it's explained once, becomes intuitive. (Yes, sampling bias, but still.) The question is whether saving that pedagogic burden is worthwhile. I argue that it isn't. `for(;;)` is a low-level construct even in ES5, where `Array.prototype.forEach` supplants it for the most part. It doesn't have to do what I mean; it should do what I say. Introducing an extra set of curly braces around the loop so that my `let` loop variables don't get hoisted to the outer scope is the most work that makes sense to me. -Domenic -Original Message- From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Andy Wingo Sent: Tuesday, February 07, 2012 5:15 To: es-discuss@mozilla.org Subject: Re: lexical for-in/for-of loose end Hi Allen, On Mon, 2012-02-06 at 11:08 -0800, Allen Wirfs-Brock wrote: We're putting a lot of energy into trying to figure out how to fix for(let;;) when it probably shouldn't even be the preferred form of numeric looping going forward. If we can make for-in/for-of attractive enough then it is less clear why we need to fix for(;;) [...] Maybe don't even add let/const forms to for(;;). Just as food for thought, here's a C# designer on why they decided to leave for (int i=0; iN; i++) alone, when they decided to make for (int i in L) bind a fresh i: We have this same problem in for blocks, but for blocks are much looser about what the loop variable is; there can be more than one variable declared in the for loop header, it can be incremented in odd ways, and it seems implausible that people would consider each iteration of the for loop to contain a fresh crop of variables. When you say for(int i; i 10; i += 1) it seems dead obvious that the i += 1 means increment the loop variable and that there is one loop variable for the whole loop, not a new fresh variable i every time through! We certainly would not make this proposed change apply to for loops. http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx Regards, Andy ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: __proto__ security
I am generally with Brendan that specifying __proto__ is not very necessary. But, one thing I would like enshrined in the spec is that `__proto__ in Object.create(null) === false`. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Set iterators
As a starting point, would it make sense to provide an API that matches Array.prototype methods (where applicable)? I think this ties in to my earlier desire to make Array.prototype methods work with iterators in general [1]. That is, I think the correct way to do this would be: 1) To specify that set is an iterator that, when iterated over, returns its values. 2) To specify that all iterators get (at least): every, filter, forEach, map, reduce, reduceRight, some One potential sticking point is that we might want filter and map to return sets themselves. [1]: https://mail.mozilla.org/pipermail/es-discuss/2012-February/020356.html ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Array.prototype.contains
Perhaps using indexOfIdentical from http://wiki.ecmascript.org/doku.php?id=harmony:simple_maps_and_sets From: es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org] on behalf of Erik Arvidsson [erik.arvids...@gmail.com] Sent: Thursday, February 23, 2012 15:15 To: es-discuss@mozilla.org Subject: Array.prototype.contains DOM4 added a new interface called DOMStringList for the sole reason that Array does not have contains. Before this the return type was an Array of Strings so we could use indexOf, map, forEach etc. Now that it is using a non Array we lost all of that. Proposal: Add Array.prototype.contains, implemented as: Object.defineProperty(Array.prototype, 'contains', { value: function(value) { return this.indexOf(value) !== -1; }, enumerable: false, configurable: true, writable: true }{); This is trivial enough to do in user code but since DOM4 depends on it we should just put it in the right place; In ES6. -- erik ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: set.delete method name
I appreciate the feedback, but I do not understand the rationale. The rationale I found compelling from upthread was that remove is a more apt antonym to add. To compare, delete's natural counterpart would be put. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Typeof this in getters (was: eval on non-strings)
Both IE10 Developer Preview (10.0.8102.0) and IE10 Platform Preview 4 (10.0.8103.0) output number object objectobject We'll see if tomorrow's drop does any better. Sounds like I should file test262 bugs as well. From: Mark S. Miller [mailto:erig...@google.com] Sent: Tuesday, February 28, 2012 14:38 To: Domenic Denicola Cc: Allen Wirfs-Brock; Brendan Eich; es-discuss@mozilla.org Subject: Re: Typeof this in getters (was: eval on non-strings) I like the output display on http://jsfiddle.net/CxdMs/16/ a bit better. I just tried it on very recent versions of 4 or the 5 major browsers. I was shocked to see that all of them were wrong. Correct would be number number object object Chrome 19 gave number number object number Opera 12, Safari WebKit 5.1.3 (7534.53.10, r109097), and Mozilla FF Nightly 13 all gave number object object object What does the latest IE10 preview do? Domenic, as you post bugs against the browsers, please send me the URLs. Thanks. On Tue, Feb 28, 2012 at 10:03 AM, Domenic Denicola dome...@domenicdenicola.com wrote: Specifically regarding ToObject. It's use is important in minimizing the semantic differences between primitive values and Objects. In ES5 we eliminated the automatic wrapping of primitive values used as this values in method invocations. That means that in most cases 42 and (new Number(42)) can be used interchangeably. If we start leaving out ToObject calls in random places the distinction between a primitive value and a wrapped primitive values will start tripping people up. This actually is apropos of something I'd been meaning to ask about. Consider the following JSFiddle: http://jsfiddle.net/CxdMs/15/ It seems reasonably clear that the result for functions should be object (non-strict)/number (strict), according to section 10.4.3. But for getters, the major browsers disagree, and my spec-fu can't find anything besides the abovementioned section. Firefox and IE9 say object/object, while V8 says number/number. And at least one version of JavaScriptCore we have lying around says number/object. If someone could walk me through the spec correctly, I'd be happy to file appropriate browser bugs. Note that this is a real-world issue. The Chai.js assertion library is trying to break free of V8 and become useful in browsers, but is encountering problems due to this behavior: https://github.com/logicalparadox/chai/issues/32 Thanks all, Domenic ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Typeof this in getters (was: eval on non-strings)
To clarify, the expected results here are: Non-strict Typeof this inside a function when called on a number: object Typeof this inside an Object.prototype getter when used on a number: object Strict Typeof this inside a function when called on a number: number Typeof this inside an Object.prototype getter when used on a number: number right? Yes. There’s over a hundred test cases that have already been created, and will be contributed ‘soon’ to cover https://bugs.ecmascript.org/show_bug.cgi?id=180. One such test case is: function foo() { 'use strict'; return typeof(this); } function bar() { return typeof(this); } return foo.call(1) === 'number' bar.call(1) === 'object'; Chrome fails this one with `bar.call(1)==='number'`, but everyone else passes. Another that seem relevant here is: function testcase() { var o = {}; Object.defineProperty(o, foo, { get: function() { use strict; return this; } }); return o.foo===o; } This is irrelevant because it is not testing primitives and boxing. (More formally, it is not testing the relevant part of 10.4.3 that we are discussing.) On that note, is there anything that’s particularly interesting spec-wise in defining foo on Object.prototype instead of a generic object and validating there? It's relevant because it allows use on numbers, i.e. `(0).getMe`. The same results happen if you define on `Number.prototype`. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: How about replacing | with -
If we’re taking votes: -1. I would actively avoid using this in my own ES6 code, because of the unnecessary confusion it would cause to those coming from CoffeeScript. From: Carlos Prado García Sent: Saturday, March 03, 2012 17:58:38 To: es-discuss Subject: Re: How about replacing | with - +1 for - syntax. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: optional function keyword
This wins on so many levels: * Short but C-like myList.map((x) x*x) syntax for the most common cases, where TCP doesn't matter. * Full TCP support via an entirely new, but still pretty C-like, syntax with myList.map((x) do { … }). * The two are sufficiently close to each other and to the existing syntax to be recognizable as functions, but sufficiently different to convey new semantics. The earlier Prototype 1.6 example: inGroupsOf(number, fillWith) { fillWith = Object.isUndefined(fillWith) ? null : fillWith; return this.eachSlice(number, (slice) do { while(slice.length number) slice.push(fillWith); slice; }); }, inject(memo, iterator, context) { iterator = iterator.bind(context); this.each((value, index) do { memo = iterator(memo, value, index); }); return memo; }, invoke(method) { var args = $A(arguments).slice(1); return this.map((value) value[method](...args)); }, From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] On Behalf Of David Herman Sent: Tuesday, March 06, 2012 17:58 To: Brendan Eich Cc: es-discuss Subject: Re: optional function keyword On Mar 6, 2012, at 2:56 PM, Brendan Eich wrote: David Herman wrote: Moreover, if you wanted to do some control along with an expression, you could use do-expressions: myList.map((x) do { for (...) { ... } f(x) }) Note that combination (expression closures + do-expressions) brings back the exact same expressiveness of block-lambda. Not so, because no TCP. Only block-lambdas preserve TCP fully. Says you! :) To be clear: what I'm suggesting is that expression closures would *not* be syntactic sugar for statement bodies, but rather would be TCP-respecting. Most of the time this wouldn't even be noticeable, until you use do-expressions. Dave ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Using Object Literals as Classes
Just to contribute to this... er... fun-thread... My team uses the closure pattern for our classes (i.e. no prototype methods at all), since we value encapsulation. I can't imagine we're alone. So any class solution that doesn't fully incorporate private names (e.g. by making them awkward via manual Name.create(), etc.) will leave that audience behind, still using closures and ignoring any new class sugar. From: es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org] on behalf of Russell Leggett [russell.legg...@gmail.com] Sent: Friday, March 16, 2012 17:07 To: Kevin Smith Cc: es-discuss Subject: Re: Using Object Literals as Classes On Fri, Mar 16, 2012 at 4:26 PM, Kevin Smith khs4...@gmail.commailto:khs4...@gmail.com wrote: Thanks, David. First, I'd like to point out that in the blog post I'm putting on the hat of a library author (I happen to be one, but that's beside the point). One of the first conclusions that I come to (as a library author) is that the idiom described here: http://wiki.ecmascript.org/doku.php?id=harmony:object_extension_literal_class_pattern provides a worse user experience than what I already have. The goal post for any class syntax or idiom is not this: function Blah() Blah.prototype = Object.create(BaseClass.prototype); Blah.prototype.a = function() {}; Blah.prototype.b = function() {}; It is rather this: var MyClass = new Class({ extends: BaseClass, a: function() {}, b: function() {} }); And in the post I conclude fairly early on that the object extension literal class pattern described above does not meet or exceed this goal post, not by a long shot. +1, agreed, not by a long shot Now, if object literal extensions were such that I could use them in a class library (any class library), then that would be fine. But as indicated in the post, they cannot. The full advantages to be derived from object literal extensions with respect to class construction are *unbreakably bound* to the | operator. As such | does not fill in missing low-level pieces of the puzzle, so much as dictate how higher level abstractions must be built. I cannot build a higher level class abstraction from fundamentals without leaking the implementation of that abstraction. The answer cannot be that I ought not build higher level abstractions. If the answer is that we'll have a class syntax, then great. But then we have to ask the related question, should super et. all defined on the object literal level? And do we even need special | or .{} syntax, then? Again, thanks David for reading and replying. I have great respect for everyone's ideas, and I'm just trying to fully explore this one. I am also a library author, and *yes* I've also created yet another class abstraction (seemed like a good idea at the time, 5 years ago) and I have to say, I totally agree. As much as I want to take advantage of |, its just not good enough at the high or the low level. Because it has to take a literal on the RHS, it can't be used inside a class abstraction library, and because its still so imperative, its not very good at the high level. I think the people that will really be able to take advantage of this will be language designers that target JS. CoffeeScript could probably put this to good use. - Russ kevin ___ es-discuss mailing list es-discuss@mozilla.orgmailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: usable enough private names (was: Re: Using Object Literals as Classes)
Yes, this looks pretty solid, although I can't remember seeing it anywhere. (Sorry for the top-posting; my webmail doesn't want to add the 's for me so I figured this is better than the alternative.) From: Herby Vojčík [he...@mailbox.sk] Sent: Friday, March 16, 2012 17:20 To: Domenic Denicola Cc: Russell Leggett; Kevin Smith; es-discuss Subject: usable enough private names (was: Re: Using Object Literals as Classes) Domenic Denicola wrote: Just to contribute to this... er... fun-thread... My team uses the closure pattern for our classes (i.e. no prototype methods at all), since we value encapsulation. I can't imagine we're alone. So any class solution that doesn't fully incorporate private names (e.g. by making them awkward via manual Name.create(), etc.) will leave that audience behind, still using closures and ignoring any new class sugar. Is the current (the last winning alternative afaicr) state good enough for you? In a few words: private x,y; will be desugared to const x = Name.create(), y = Name.create(); So you would need to write your code as: module ... { ... private foo, bar; ... class Alpha { ... uses names foo, bar in constructor and methods } ... maybe use the same name in subsequent classes and functions } Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Using Object Literals as Classes
On Mar 16, 2012, at 18:05, David Bruant bruan...@gmail.commailto:bruan...@gmail.com wrote: Le 16/03/2012 23:00, Rick Waldron a écrit : On Fri, Mar 16, 2012 at 5:12 PM, Domenic Denicola dome...@domenicdenicola.commailto:dome...@domenicdenicola.com wrote: Just to contribute to this... er... fun-thread... My team uses the closure pattern for our classes (i.e. no prototype methods at all), since we value encapsulation. I can't imagine we're alone. For my own curiosity, can you point me to some examples where you are strategically avoiding the use of the prototype pattern? When he needs actual encapsulation. Unfortunately, methods on prototype require to have properties that are public. If you avoid prototype methods, all your attributes and private methods can be shared by public method scopes. David Exactly. I am away from computer right now, so I cannot dig up examples from our codebase at work, but essentially we use the pattern described by Crockford in http://www.crockford.com/javascript/private.html And we use only privileged methods (on the instance), not public ones (on the prototype). This also neatly avoids binding problems via a single `var that = this` at the top of the constructor. Here is an example from some of my own open-source code: https://github.com/domenic/pubit/blob/master/lib/Publisher.js (The `var that = this` in that particular example is unnecessary since no public methods call each other; it's just there as part of the boilerplate encapsulated-class pattern I always use.) Hope this helps, despite being cobbled together on an iPhone. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Using Object Literals as Classes
On Mar 16, 2012, at 18:12, Rick Waldron waldron.r...@gmail.commailto:waldron.r...@gmail.com wrote: On Fri, Mar 16, 2012 at 6:04 PM, David Bruant bruan...@gmail.commailto:bruan...@gmail.com wrote: Le 16/03/2012 23:00, Rick Waldron a écrit : On Fri, Mar 16, 2012 at 5:12 PM, Domenic Denicola dome...@domenicdenicola.commailto:dome...@domenicdenicola.com wrote: Just to contribute to this... er... fun-thread... My team uses the closure pattern for our classes (i.e. no prototype methods at all), since we value encapsulation. I can't imagine we're alone. For my own curiosity, can you point me to some examples where you are strategically avoiding the use of the prototype pattern? When he needs actual encapsulation. Unfortunately, methods on prototype require to have properties that are public. If you avoid prototype methods, all your attributes and private methods can be shared by public method scopes. Sorry, I don't subscribe to this as an adequate argument against prototypes. jQuery has a whole lot of hidden, private functions and data - using an IIFE. Ultimately, the developer makes the decision to write well encapsulated code - prototype or closure pattern should have no bearing. Rick David That only works for singleton modules, not multi-instance classes. WeakMaps and private names both provide solutions for associating private data to an instance, without abandoning prototypes, but that brings me back to my original point: class sugar must make such association easier than manual `Name.create()` usage, on par with the ease of the closure pattern. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Using Object Literals as Classes
From: Rick Waldron [mailto:waldron.r...@gmail.com] Sent: Friday, March 16, 2012 18:40 To: Domenic Denicola Cc: David Bruant; es-discuss Subject: Re: Using Object Literals as Classes On Fri, Mar 16, 2012 at 6:20 PM, Domenic Denicola dome...@domenicdenicola.commailto:dome...@domenicdenicola.com wrote: On Mar 16, 2012, at 18:12, Rick Waldron waldron.r...@gmail.commailto:waldron.r...@gmail.com wrote: On Fri, Mar 16, 2012 at 6:04 PM, David Bruant bruan...@gmail.commailto:bruan...@gmail.com wrote: Le 16/03/2012 23:00, Rick Waldron a écrit : On Fri, Mar 16, 2012 at 5:12 PM, Domenic Denicola dome...@domenicdenicola.commailto:dome...@domenicdenicola.com wrote: Just to contribute to this... er... fun-thread... My team uses the closure pattern for our classes (i.e. no prototype methods at all), since we value encapsulation. I can't imagine we're alone. For my own curiosity, can you point me to some examples where you are strategically avoiding the use of the prototype pattern? When he needs actual encapsulation. Unfortunately, methods on prototype require to have properties that are public. If you avoid prototype methods, all your attributes and private methods can be shared by public method scopes. Sorry, I don't subscribe to this as an adequate argument against prototypes. jQuery has a whole lot of hidden, private functions and data - using an IIFE. Ultimately, the developer makes the decision to write well encapsulated code - prototype or closure pattern should have no bearing. Rick David That only works for singleton modules, not multi-instance classes. Multi-instance as in many instances created from a class? Every call to jQuery or its alias $ actually produces a new, unique object instance from a real constructor. The example you gave produces a constructor that wraps a handful of instance method definitions along with several function declarations - which I'm arguing could just as easily be outside of that function declaration, but inside of an IIFE. There are two issues here: 1) “Private methods” could be moved outside to the module level (IIFE level if you wish). This is true, but would necessitate passing the private state into these methods: `callListener` would need `options`, which then propagates to an extra parameter on `callListenersForSync` and `callListenersForAsync`. Obviously this problem multiplies as you add more private state to the object, eventually ending up passing around a “secrets” object containing all your private state, which is a bundle of joy to program against. /sarcasm 2) “Public methods” cannot be moved outside to the prototype level. If instead of `that.publish = function () { ... }` inside the constructor, I had `Publisher.prototype.publish = function () { ... }` outside the constructor, then the function body could not access the “private instance variables” `normalListeners` and `oneTimeListeners`, or the constructor parameter `options`. The only way to allow a `Publisher.prototype.publish` method to access this per-instance state would be to un-encapsulate it, making it public so that they could be accessed as e.g. `this._normalListeners`. This is what I mean when I say I eschew the prototypal pattern in favor of the closure pattern. All of my methods are instance methods, because they need access to private, encapsulated state. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Using Object Literals as Classes
From: Axel Rauschmayer [mailto:a...@rauschma.de] Sent: Friday, March 16, 2012 18:35 To: Domenic Denicola Cc: Russell Leggett; Kevin Smith; es-discuss Subject: Re: Using Object Literals as Classes Just to contribute to this... er... fun-thread... My team uses the closure pattern for our classes (i.e. no prototype methods at all), since we value encapsulation. I can't imagine we're alone. Do you see privacy via closures and prototypes as mutually exclusive? In my experience, they work well in combination. Do you add all of your methods to the instance? That would have the advantage of making it easier to access private data from public methods, but would consume more memory. In theory I see them as complementary, but in practice I have never been able to integrate prototypes. Consider: a method can only be attached to a prototype if it needs access to an instance’s public state only, and not to its private state. These cases are extremely rare. And when they do occur, I usually ask myself—is this really an instance-level method? Why not make it a module-level method that operates on instances of my class? We have so far made the trade-off of sacrificing memory for encapsulation. (Although, I still find it strange that modern JITers don’t pull out of the code of the method to reuse in each instance, and instead duplicate it every time. Cf. the “Joining” section of [1].) It hasn’t bitten us yet. [1]: http://wiki.ecmascript.org/doku.php?id=strawman:const_functions So any class solution that doesn't fully incorporate private names (e.g. by making them awkward via manual Name.create(), etc.) will leave that audience behind, still using closures and ignoring any new class sugar. True. Something along the lines of: class C { private { age, strength } /* syntactic sugar for module name from @name; var age = name.create(); var strength = name.create(); */ // private method @incAge() { this.@agemailto:this.@age++; } } This does look familiar, and quite useful. But it’s certainly outside the scope of “object literals as classes,” which I think ties to my original point in supporting the OP that object literals alone are not sufficient. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Using Object Literals as Classes
From: Rick Waldron [mailto:waldron.r...@gmail.com] Sent: Friday, March 16, 2012 19:28 To: Domenic Denicola Cc: David Bruant; es-discuss Subject: Re: Using Object Literals as Classes On Mar 16, 2012, at 7:11 PM, Domenic Denicola dome...@domenicdenicola.commailto:dome...@domenicdenicola.com wrote: From: Rick Waldron [mailto:waldron.r...@gmail.com]mailto:[mailto:waldron.r...@gmail.com] Sent: Friday, March 16, 2012 18:40 To: Domenic Denicola Cc: David Bruant; es-discuss Subject: Re: Using Object Literals as Classes On Fri, Mar 16, 2012 at 6:20 PM, Domenic Denicola dome...@domenicdenicola.commailto:dome...@domenicdenicola.com wrote: On Mar 16, 2012, at 18:12, Rick Waldron waldron.r...@gmail.commailto:waldron.r...@gmail.com wrote: On Fri, Mar 16, 2012 at 6:04 PM, David Bruant bruan...@gmail.commailto:bruan...@gmail.com wrote: Le 16/03/2012 23:00, Rick Waldron a écrit : On Fri, Mar 16, 2012 at 5:12 PM, Domenic Denicola dome...@domenicdenicola.commailto:dome...@domenicdenicola.com wrote: Just to contribute to this... er... fun-thread... My team uses the closure pattern for our classes (i.e. no prototype methods at all), since we value encapsulation. I can't imagine we're alone. For my own curiosity, can you point me to some examples where you are strategically avoiding the use of the prototype pattern? When he needs actual encapsulation. Unfortunately, methods on prototype require to have properties that are public. If you avoid prototype methods, all your attributes and private methods can be shared by public method scopes. Sorry, I don't subscribe to this as an adequate argument against prototypes. jQuery has a whole lot of hidden, private functions and data - using an IIFE. Ultimately, the developer makes the decision to write well encapsulated code - prototype or closure pattern should have no bearing. Rick David That only works for singleton modules, not multi-instance classes. Multi-instance as in many instances created from a class? Every call to jQuery or its alias $ actually produces a new, unique object instance from a real constructor. The example you gave produces a constructor that wraps a handful of instance method definitions along with several function declarations - which I'm arguing could just as easily be outside of that function declaration, but inside of an IIFE. There are two issues here: 1) “Private methods” could be moved outside to the module level (IIFE level if you wish). This is true, but would necessitate passing the private state into these methods: `callListener` would need `options`, which then propagates to an extra parameter on `callListenersForSync` and `callListenersForAsync`. Obviously this problem multiplies as you add more private state to the object, eventually ending up passing around a “secrets” object containing all your private state, which is a bundle of joy to program against. /sarcasm There is more then one way to skin a goose... 2) “Public methods” cannot be moved outside to the prototype level. I should've used a period, or perhaps a whole new paragraph, because I never meant to imply that they could or should. If instead of `that.publish = function () { ... }` inside the constructor, I had `Publisher.prototype.publish = function () { ... }` outside the constructor, then the function body could not access the “private instance variables” `normalListeners` and `oneTimeListeners`, or the constructor parameter `options`. Inside the IIFE, WeakMap (or shimmed equivalent) with instance as key, pointing to an object with all of those goodies stored in it. The only way to allow a `Publisher.prototype.publish` method to access this per-instance state would be to un-encapsulate it, making it public so that they could be accessed as e.g. `this._normalListeners`. See WeakMap strategy above This is what I mean when I say I eschew the prototypal pattern in favor of the closure pattern. All of my methods are instance methods, because they need access to private, encapsulated state. I still say that this can all be accomplished with prototypes and IIFEs. I agree, it can all be done with WeakMaps or private names combined with modules and IIFEs, as I pointed out a few emails back and as Tab points out in another reply. But at that point (especially with WeakMaps, but also with unsugared private names) I am jumping through enough hoops that I’d rather just go the closure route. In my opinion, if ES6 delivers no sugar for private names, very few closure-pattern-using developers will jump through the necessary hoops to convert from closures to prototypes. (They’d also have to deal with losing the guaranteed `that = this` binding, but that’s another story.) That’s really the only point I wanted to make in this thread; I think we got sidetracked talking past each other about implementation patterns in current ES5/ES5-plus-WeakMaps environments. ___ es
RE: simpler, sweeter syntax for modules
Callable modules are a hugely important use case. jQuery and Underscore spring to mind. I’ve made one myself [1]. Also important: what about construct-able modules? Or to put it another way, what about exporting a module that is a class? Examples from Node [2] [3] and Node-land [4] [5] are abundant. It makes me think a more generic mechanism would be required to export any arbitrary object as the module itself. Perhaps export module as function jQuery(selector, context) { … } // or function jQuery(selector, context) { … } export module as jQuery; export module as class Runnable { … } // or class Runnable { … } export module as Runnable; [1]: https://github.com/domenic/dict/blob/master/dict.js [2]: https://github.com/joyent/node/blob/master/lib/stream.js [3]: https://github.com/joyent/node/blob/master/lib/module.js [4]: https://github.com/visionmedia/mocha/blob/master/lib/runnable.js [5]: https://github.com/visionmedia/mocha/blob/master/lib/suite.js From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Andreas Rossberg Sent: Thursday, March 22, 2012 07:55 To: es-discuss Subject: Re: simpler, sweeter syntax for modules One point that I haven't seen mentioned yet (and it is unrelated to syntax): export call makes me cringe -- making modules callable is not just weird, it seems completely future-hostile to the possibility of having parameterized modules. I don't think it is worth bending the notion of module like that if all that is gained is minor convenience. /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: RegExps in array functions
Does passing /foo/i.test not work? (Away from computer.) Perhaps it should, if it doesn't? On Mar 23, 2012, at 16:28, Felix Böhm esdisc...@feedic.commailto:esdisc...@feedic.com wrote: Hi guys, just a first try for a proposal: Array.prototype.[filter/some/every] currently require a function as an argument. Most of the time, everything I want to do is check if they match a certain pattern. So what I end up writing is a RegExp that matches the pattern, and calling its test() method for every member of the array. My proposal is to allow people to use a regular expression as an argument for the three methods. Current implementations throw an error when they don't get a function as an argument, so this won't break any (working) code. An example: [fOo,bAr].filter(function(elem){ return /foo/i.test(elem); }); should be replaceable with [fOo,bAr].filter(/foo/i); For non-string members of the array, the current behavior of the RegExp.prototype.test method (ie. converting the value to a string) applies. Any reasons why this is a bad idea? (Or is it just my bad attitude? :D ) ___ es-discuss mailing list es-discuss@mozilla.orgmailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: RegExps in array functions
Would it be a reasonable language upgrade to pre-bind test? I imagine there would be philosophical objections, but would be interested in hearing them enunciated. (Are there other pre-bound methods in ES5's standard library?) On Mar 23, 2012, at 21:48, Russell Leggett russell.legg...@gmail.commailto:russell.legg...@gmail.com wrote: On Mar 23, 2012, at 9:05 PM, John Tamplin j...@google.commailto:j...@google.com wrote: On Fri, Mar 23, 2012 at 8:21 PM, Domenic Denicola dome...@domenicdenicola.commailto:dome...@domenicdenicola.com wrote: Does passing /foo/i.test not work? (Away from computer.) Perhaps it should, if it doesn't? It does, if you bind it to the regex first. Ie: var re = /foo/i; var filtered = array.filter(re.test.bind(re)); So that doesn't look better than just passing an anonymous function wrapper (though you probably want to build the regex once). Yeah, gotta watch your receiver. If you find yourself doing this a lot, just make a function. You can either add a method to RegExp that returns a bound version of test, or make a function that takes a regex and returns a bound version of test like function predicate(regex){ return regex.test.bind(regex); } var filtered = array.filter(predicate(/foo/i)); - Russ -- John A. Tamplin Software Engineer (GWT), Google ___ es-discuss mailing list es-discuss@mozilla.orgmailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Finding a safety syntax for classes
On Mar 27, 2012, at 13:10, David Herman dher...@mozilla.com wrote: I recognize the C.prototype.constructor idiom already exists, but it's a weak idiom. I'm not crazy about the idea of strengthening a problematic but currently unreliable and rarely used idiom. Dave Speaking as a dev, I would like this idiom to be stronger (i.e. be there by default in a classy world). One use case that immediately springs to mind is try { } catch (e) { switch(e.constructor) { } }, which we've used a couple times in the absence of Mozilla-style exception guards. Your concern about possibly not wanting to expose the constructor makes a lot of sense, but perhaps we could leave .prototype.constructor configurable and let people in such a situation explicitly delete it. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: March 28 meeting notes
Great to gain consensus indeed. This looks just about as nice as it can be. Minor question: There are no examples of very empty arrow functions, e.g. `=` or `= 5`. And from what I can tell reading the grammar , they are not allowed. Is this necessary? CoffeeScript's allowance of `- (expr)` gives some nice-looking code, for example see [1]. Bigger question: It sounds like TCP was sacrificed in favor of maximal minimalism, which makes sense. But, is this strawman friendly toward future TCP endeavors, perhaps in ES.next.next? For example, if `do` expressions were specced in the way discussed previously, could putting one to the right of the = result in TCP semantics? [1]: https://github.com/domenic/sinon-chai/blob/master/test/callOrder.coffee -Original Message- From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Brendan Eich Sent: Thursday, March 29, 2012 02:30 To: Waldemar Horwat Cc: es-discuss Subject: Re: March 28 meeting notes Waldemar Horwat wrote: Consensus on: - Have only one arrow, namely = - this is always static. No provision for dynamic this. - Other than the treatment of this, the function behaves like a normal function. return, break, etc. behave as though the function body were in a function(...){...}. To be discussed later: The thing that comes after the arrow: 1. Always an expression (possibly a do expression)? 2. A block if it starts with {, otherwise an expression. See http://wiki.ecmascript.org/doku.php?id=strawman:arrow_function_syntax -- I'm a bit tired from travel so may have made a mistake or two, and I know some of the examples should be better. Comments welcome. Great to gain consensus on this today! /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Do Maximally Minimal classes carry their weight?
As a quick follow-up: Perhaps adding non-arcane-incantation private name declarations would be enough to push maximally-minimal classes from “nice, but are they worth it?” to “this gives us something we can’t get anywhere else.” To wit: class Set extends Collection { private setContents, setTally constructor(initialSize = 2) { this.{ @setContents: new Array(initialSize), @setTally: 0 } } // ... } ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Extra functions on Arrays, Maps, etc..
On Apr 7, 2012, at 20:37, Rick Waldron waldron.r...@gmail.commailto:waldron.r...@gmail.com wrote: On Sat, Apr 7, 2012 at 8:31 PM, Erik Arvidsson erik.arvids...@gmail.commailto:erik.arvids...@gmail.com wrote: On Sat, Apr 7, 2012 at 17:28, Rick Waldron waldron.r...@gmail.commailto:waldron.r...@gmail.com wrote: As in, its [[Class]] is Array and Array.isArray( nodes ) would evaluate to true? No, it means that Object.getPrototypeOf(NodeList.prototype) === Array.prototype. Yes, this part was clear in the links you sent. The question I had was about two things that were not addressed in the links (that I could see, please correct if I missed them) There will be much confusion on the web if Array.isArray(nodes) returns false, while nodes.push( node ), nodes.slice( 0, 2 ) just work, especially during periods of transition from DOMx to DOM4. Rick Fortunately all the Array.prototype methods are generic so it all just works. -- erik I think the benefits are so great I'm happy to deal with any confusion. Although, it sounds like I'll be wanting to go back to `instanceof Array`, which is kind of funny. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Terminology: “non-method function”
We use `Function.prototype.partial` in our codebase. We consider `Function.prototype.papply` but thought that would be too confusing with `Function.prototype.apply`. From: es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org] on behalf of Axel Rauschmayer [a...@rauschma.de] Sent: Wednesday, April 11, 2012 12:54 To: Allen Wirfs-Brock Cc: es-discuss Subject: Re: Terminology: “non-method function” Great idea. Do we need similar this-less variants for call and apply? Probably not, the former is just a normal function call. The latter can by handled by the spread operator. IIRC, what one actually does here is not currying, but partial application. However, I don’t see any good method name being derived from “partial application”. On Apr 11, 2012, at 18:44 , Allen Wirfs-Brock wrote: On Apr 11, 2012, at 7:12 AM, Peter van der Zee wrote: On Wed, Apr 11, 2012 at 1:01 AM, Axel Rauschmayer a...@rauschma.demailto:a...@rauschma.de wrote: What is a good term for functions that don’t have/use dynamic `this`? A bound function? I'm leaning in that direction. A bound function has an unbound (dynamic) this while a bound function has a bound (fixed) this. To further clarify this it might be useful to better differentiate binding this from currying the arguments. We might do this by adding a new Function.prototype.curry function that doesn't have a this value as its first argument. You would then fn.curry(1,2) If you want to create a curried function from fn with 1 and 2 as the first two fn arguments. and: fn.bind(foo) if you want to created a bound version of fn where this is bound to the value of foo. The semantics of fn.bind(foo,1,2) could then be explained as being equivalent to fn.bind(foo).curry(1,2) Allen -- Dr. Axel Rauschmayer a...@rauschma.demailto:a...@rauschma.de home: rauschma.dehttp://rauschma.de twitter: twitter.com/rauschmahttp://twitter.com/rauschma blog: 2ality.comhttp://2ality.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Fun impossible Firefox JS challenge
The real question is, are there test-262's for this behavior? Or for the original nonconforming `function true() { }`? From: es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org] on behalf of Mathias Bynens [math...@qiwi.be] Sent: Thursday, April 12, 2012 11:06 To: Lasse Reichstein Cc: es-discuss Steen Subject: Re: Fun impossible Firefox JS challenge For those interested, Spidermonkey doesn’t handle the following correctly: function \u0074rue() { alert('PASS'); } \u0074rue(); function \u0074rue() { alert('PASS'); } tru\u0065(); Both these examples should alert 'PASS' in web browsers. I filed this as bug 744784: https://bugzilla.mozilla.org/show_bug.cgi?id=744784 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Fun impossible Firefox JS challenge
var tru\u0065; = Expected identifier error in IE9. console.log(fals\u0065) = Syntax error in IE9. Can test IE10 when I get home from work. From: es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org] on behalf of Brendan Eich [bren...@mozilla.org] Sent: Thursday, April 12, 2012 13:38 To: Allen Wirfs-Brock Cc: es-discuss Steen Subject: Re: Fun impossible Firefox JS challenge Allen Wirfs-Brock wrote: 1) Understand the actual browser interop situation. For example, do all major browsers accept: var tru\u0065; SpiderMonkey shell: js var tru\u0065; typein:1: SyntaxError: missing variable name: typein:1: var tru\u0065; typein:1: ^ It looks like Carakan (Opera), JSC and V8 allow this. I can't test IE. 2) Within the constraints of 1) decide what we actually want to specify. Do we want console.log(fals\u0065) to print false or undefined? Carakan, JSC and V8 alert undefined. Anyone have IE results? Looks like SpiderMonkey implemented ES5 not ES3, probably accidentally and ahead of time. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Fun impossible Firefox JS challenge
IE10 (Windows 8 Consumer Preview edition): var tru\u0065; = The use of a keyword for an identifier is invalid console.log(fals\u0065) = Syntax error So same thing but better error message for the former case. -Original Message- From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Domenic Denicola Sent: Thursday, April 12, 2012 13:49 To: Brendan Eich; Allen Wirfs-Brock Cc: es-discuss Steen Subject: RE: Fun impossible Firefox JS challenge var tru\u0065; = Expected identifier error in IE9. console.log(fals\u0065) = Syntax error in IE9. Can test IE10 when I get home from work. From: es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org] on behalf of Brendan Eich [bren...@mozilla.org] Sent: Thursday, April 12, 2012 13:38 To: Allen Wirfs-Brock Cc: es-discuss Steen Subject: Re: Fun impossible Firefox JS challenge Allen Wirfs-Brock wrote: 1) Understand the actual browser interop situation. For example, do all major browsers accept: var tru\u0065; SpiderMonkey shell: js var tru\u0065; typein:1: SyntaxError: missing variable name: typein:1: var tru\u0065; typein:1: ^ It looks like Carakan (Opera), JSC and V8 allow this. I can't test IE. 2) Within the constraints of 1) decide what we actually want to specify. Do we want console.log(fals\u0065) to print false or undefined? Carakan, JSC and V8 alert undefined. Anyone have IE results? Looks like SpiderMonkey implemented ES5 not ES3, probably accidentally and ahead of time. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: undefined being treated as a missing optional argument
I'm sympathetic toward `undefined` as a sentinel for no value of the expected type, whereas `null` means we have a value of the expected type, but that value represents 'nothing.' Not sure if anyone else sees it that way, though, and admittedly it's based on vague hand-wavey arguments. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: try without catch or finally
Tangentially related: https://github.com/kriskowal/q/wiki/On-Exceptions From: es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org] on behalf of Nebojša Ćirić [c...@google.com] Sent: Tuesday, April 17, 2012 16:39 To: Jussi Kalliokoski Cc: es-discuss Subject: Re: try without catch or finally It's easy to forget to catch in cases you wanted to. Maybe adding a new keyword: try { ... } drop; 17. април 2012. 13.35, Jussi Kalliokoski jussi.kallioko...@gmail.commailto:jussi.kallioko...@gmail.com је написао/ла: I'm not sure if this has been discussed before, but is it a terribly bad idea to make catch/finally optional for a try block? There's a lot of code like this out there: try { /* something here */ } catch (e) { /* nothing here */ } Cheers, Jussi ___ es-discuss mailing list es-discuss@mozilla.orgmailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Nebojša Ćirić ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: callable objects ?
It seems rather non-intention-revealing. From: es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org] on behalf of Mark S. Miller [erig...@google.com] Sent: Tuesday, April 17, 2012 17:20 To: Brendan Eich Cc: Tom Van Cutsem; Mark Miller; es-discuss Subject: Re: callable objects ? +1 for simple enough. It's also shorter (12 vs 20) On Tue, Apr 17, 2012 at 2:02 PM, Brendan Eich bren...@mozilla.orgmailto:bren...@mozilla.org wrote: Brendan Eich wrote: This last point is important: we do not want an object's typeof-type to change by giving it a @call property. But we do want to enable call and construct protocols to be built by users, by giving objects @call and @construct properties. I did not include an Object.isCallable(v) API that returns true if (@call in v), but we could add that. Testing (@call in v) seems simple enough. /be ___ es-discuss mailing list es-discuss@mozilla.orgmailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: A few arrow function specification issues
-Original Message- From: es-discuss-boun...@mozilla.org [mailto:es-discuss- boun...@mozilla.org] On Behalf Of Angus Croll Sent: Saturday, April 21, 2012 16:03 To: Allen Wirfs-Brock Cc: es-discuss Subject: Re: A few arrow function specification issues 4) Should it be a dynamic error to try to use apply/call to set the this binding of an arrow function. Cons To much existing code speculatively binding the this value when invoking a function. I propose that call/apply simply ignore the this value when invoked on an arrow function. What is the pro of ignoring explicit |this| binding instructions in call/apply on arrow functions? What is the con of continuing to allow legacy code to speculatively bind the |this| value when invoking any function? Why is it so important that fat arrows do a hard |this| binding? It's important, as someone who hands off an arrow function to another part of the system, to ensure that `this` means what it meant while I was originally writing the code. This guarantee is vital for predictability of behavior. Consider let mapped = array.map((el) = el * this.x) If I cannot guarantee a lexical `this`, I am back to programming with `let that = this`, which is part of what arrow functions are trying to avoid. The only alternative is reading the source code and/or spec for every system that I hand off an arrow function to, since I need to know if they will clobber the lexical `this` I was trying to program against. Note that this isn't a security issue---I'm not worried about malicious code messing me up. I'm simply trying to juggle the minimum number of factors on my precious brainstack, and when I'm trying to get a mapped array, I really don't want to think about whether `map` is going to mess with my `this`. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: caller poison pills, revisited (Was: A few arrow function specification issues)
I'm becoming increasing convinced that the poison pill approach to securing the caller chain is a poor approach. We keep finding leaks in and it does nothing to prevent implementation from inventing new ways to expose the stating they are trying to hide. I now think we would be better off with a general,non-algorithmic restriction on conforming implementation that forbid them from exposing elements of the caller chain in the situations that the poison pills were intended to address. This sounds a bit drastic—wouldn't it preclude V8's Error.captureStackTrace? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: A few arrow function specification issues
As a day-to-day user who was not using strict until recently (stubborn other team member for the loss), I can say that moving to strict was much more a cleanup experience than a mode experience, with only a few small exceptions: 1) Poison-pilling arguments.callee: some code on the internet (notably [1], but elsewhere too) uses this property. 2) Throw on `delete`ing non-configurables: unlike the other throw-on-doing-something-bad, `delete`ing non-configurable properties was something we actually did on purpose. E.g. using it to clear an entry in a map, whether or not that entry was ever filled. (Cf. [2].) We never tried writing to a non-writable property, because that would cause bugs, but `delete`ing a property that doesn't exist was a common pattern. [1]: http://www.devthought.com/2011/12/22/a-string-is-not-an-error/ [2]: https://github.com/cjohansen/Sinon.JS/commit/80c38bd3e4b8813ab74ef27a4db3646e4778e31c --- Otherwise, it was just cleanup: we got to get rid of our global detector (`setInterval(compareWindowPropertiesToLastTimeYouChecked(), 1000)`), never missed `with` or evil-`eval`, and due to a V8 bug never had boxed `this` in the first place. We're using it transparently throughout the codebase, in fact, due to using an XHR+`eval` module loader that can insert the `use strict` pragma before `eval`ing. -Original Message- From: es-discuss-boun...@mozilla.org [mailto:es-discuss- boun...@mozilla.org] On Behalf Of David Herman Sent: Monday, April 23, 2012 19:11 To: Brendan Eich Cc: es-discuss Subject: Re: A few arrow function specification issues On Apr 23, 2012, at 2:44 PM, Brendan Eich wrote: Brendan Eich wrote: Without arguments runtime semantic shifts, and with |this| lexical, there aren't many strict mode changes left IIRC, and they are pretty edgy edge cases. True enough, but I hang tough on wanting arrows to imply strictness. I may be wrong but the edge cases cited so far (global variable creation by assignment, 'with', direct eval injecting 'var' into its dynamic scope) along with this |this|-boxing one are underwhelming. IMO, this decision hangs on whether we think strict mode can be thought of as a cleaning up that will mostly just catch bugs, resulting in failing faster but otherwise not changing program behavior significantly. POSITION CLEANUP: If it's just a cleanup, then it makes sense to introduce strict mode in a bunch of places in the language. It'll catch bugs, and for the most part people won't have to think to themselves is this strict code? POSITION MODE: If it's something that is likely to change behavior in meaningful ways other than failing faster, then it's something programmers will have to be mindful of. In that case, having multiple constructs that implicitly introduce strict mode imposes a burden on programmers: they have to know which features are strict and which ones aren't. Every fiber of my being screams MODE. Brendan argues CLEANUP based on the rationale that the non-error semantic changes of strict mode are unlikely edge cases. This is the strongest argument against MODE. I can't prove it wrong, but it's a risky bet. If it turns out to be the case that in practice you need to keep track of whether you're in strict mode, then weak programmers who don't know better will end up with a confusing mess, and strong programmers will prophylactically make sure to put their entire programs in strict mode rather than memorize which subset of syntaxes opt in. Since strong programmers have the option to do that anyway even without multiple implicit opt-ins, why take the risk? Pascal^H^H^H^H^H^H Dave ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re-throwing errors
Consider: try { doStuff(); } catch (e) { console.log(uh oh, got an e, e); throw e; } In Node and in all browsers I've tested with, this currently loses the stack trace for `e`, and more importantly loses debugger step-back-ability in tools like Firebug and Web Inspector. One solution would be to hope V8 and the browser vendors simply don't throw away this stack trace, like they do currently. This seems like a win to me, but the fact that it hasn't happened implies there must be something wrong with the idea, e.g. maybe it breaks down in less-than-trivial cases. Is that true? If so, then in C++ and C# they solve this by saying that an empty `throw` is an explicit re-propagation [1]. Would this be a possible feature to introduce into Harmony? [1]: http://winterdom.com/2002/09/rethrowingexceptionsinc ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Re-throwing errors
Eeek, how embarrassing. This seems to have been fixed while I wasn't looking, and/or my testing wasn't as complete as I thought. I should have re-tested before emailing. My apologies for wasting everyone's time. The debugger step-back-ability isn't there in Chrome, at least, but that's a much smaller problem. From: Rick Waldron [waldron.r...@gmail.com] Sent: Friday, May 11, 2012 16:10 To: Brendan Eich Cc: Domenic Denicola; es-discuss@mozilla.org Subject: Re: Re-throwing errors On Fri, May 11, 2012 at 2:43 PM, Brendan Eich bren...@mozilla.commailto:bren...@mozilla.com wrote: Domenic Denicola wrote: Consider: try { doStuff(); } catch (e) { console.log(uh oh, got an e, e); throw e; } In Node and in all browsers I've tested with, this currently loses the stack trace for `e`, and more importantly loses debugger step-back-ability in tools like Firebug and Web Inspector. One solution would be to hope V8 and the browser vendors simply don't throw away this stack trace, like they do currently. This seems like a win to me, but the fact that it hasn't happened implies there must be something wrong with the idea, e.g. maybe it breaks down in less-than-trivial cases. Is that true? This is fascinating, but I can't reproduce - can you confirm: https://gist.github.com/2662158 Rick So V8 overwrites e.stack on the re-throw? SpiderMonkey does not: js function f() { try { doStuff(); } catch (e) { console.log(uh oh, got an e, e); throw e; } } js function g() {f()} js function h() {g()} js function doStuff() {uh.oh} js console = {log: print} ({log:function print() {[native code]}}) js try {h()}catch (e){E=e} uh oh, got an e ReferenceError: uh is not defined (new ReferenceError(uh is not defined, typein, 11)) js e.stack typein:15: ReferenceError: e is not defined js E.stack doStuff@typein:11\nf@typein:3\ng@typein:9\nh@typein:10\n@typein:14\n Since the explicit re-throw is not creating the exception object, it should not be mutating it to clobber the original .stack value. /be If so, then in C++ and C# they solve this by saying that an empty `throw` is an explicit re-propagation [1]. Would this be a possible feature to introduce into Harmony? [1]: http://winterdom.com/2002/09/rethrowingexceptionsinc ___ es-discuss mailing list es-discuss@mozilla.orgmailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.orgmailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
ToNumber(0b1001)
I was going over the latest draft and noticed that, while binary and octal literals have been introduced in 7.8.3, they weren’t added to 9.1.3.1 (“ToNumber applied to the String type”). Should they be? Pros: symmetry. Cons: breaks backward compatibility (currently ToNumber(0b1001) returns NaN). ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: minutes, TC39 meeting Tues 5/22/2012
The prototyping efforts are appreciated, but can rarely be used in a comfortable way. (Compared to, say, HTML5.) I've thought a lot about how to feasibly use Harmony features in real-world code, but have fallen down every time. Here are some of the stumbling blocks I've encountered: * Node.js with --harmony flag gets you collections, old proxies, and (significantly) block scoping. But Node does not make it easy to indicate this file needs to be run with --harmony, or e.g. to require harmony-using files from non-harmony-using libraries. So this ends up being a nonstarter for library authors, leaving it only usable by application writers. Besides, the proxies are still old, which is really unfortunate. And the iteration rate is slowww: stuff like destructuring has been harmonized for a long time, but shows no sign of making it into V8. * The same problems apply to desktop apps written with Chromium Embedded Framework. These will probably have more app code, but then if you want to factor any of it out into smaller redistributable modules, you limit your audience. * SpiderMonkey has a lot of stuff that we would love to use, and a fairly fast iteration time. (Direct proxies are almost landed, according to my bugmail!) The spec is tracked pretty well, too. But SpiderMonkey has very little uptake outside of Firefox, and most code written for Firefox must be web-compatible, so nobody except Firefox extension authors gets to use its many features. * Traceur seems to be coming along nicely, but its alignment with the spec leaves a lot to be desired. Destructuring just got fixed a few days ago, and they have a class syntax you have to avoid to write ES6-as-it-is--compatible code. They have features like private names that are not (really) in the spec yet, using speculative syntax (`new Name` was never harmonized, was it?). Monocle-mustache is in, somehow. Etc. It's ES6-like, but doesn't reflect TC39's actual progress, instead reflecting the Traceur team's interpretation of where TC39 might eventually, hopefully, end up. Subsetting might be a solution, assuming the semantics of the subsetted features are aligned with the spec, but determining that would require further investigation. * And of course there's the usual elephant in the room, viz. Internet Explorer. We (Barnes Noble.com) reached out to Microsoft about including some basic, already-harmonized features in IE10 for use in writing desktop apps in HTML5/JS as per their new Windows Runtime framework. (This was desired since we are using some of them in our existing Chromium-based desktop app, namely block scoping and weak maps.) But even as a first class partner (or something), they were unable to grant us this request. The attitude that I personally inferred was that ES6 won't make it into IE before a finalized spec is available. This not only stalls web progress, but also that of anything that embeds Chakra (a fairly common operation on Windows, about to become much more common with Windows 8). -Original Message- From: es-discuss-boun...@mozilla.org [mailto:es-discuss- boun...@mozilla.org] On Behalf Of Brendan Eich Sent: Wednesday, May 23, 2012 22:20 To: Brandon Benvie Cc: es-discuss@mozilla.org Steen Subject: Re: minutes, TC39 meeting Tues 5/22/2012 Play fair now. SpiderMonkey in Firefox prototyped let, const, generators, iterators (an earlier form), destructuring (close to final ES6), comprehensions, generator expressions, and more recently proxies, weak maps, maps, and sets. V8 joined in the proxies, weak maps, maps, and sets fun. The for-of loop from ES6 is in SpiderMonkey now. Most significantly, modules are under way in SpiderMonkey and V8. We prototype as we go. V8 has kept stuff under a flag and that's fair -- we may do likewise, certainly with new stuff likely to change, in SpiderMonkey. But saying nothing is coming out of TC39 is inaccurate. If you mean classes are not being prototyped because 'const class' or equivalent is not part of the almost-at-consensus maximally minimal classes strawman, you're right. If we must have a way to fix the properties of a class instance as Waldemar wishes, then I predict classes won't be in ES6 and it will be hard to justify prototyping less than the full required (as yet unwritten) proposal that satisfies everyones' wants. That is a shame, and a stain on TC39's escutcheon. But you should be accurate about the many other things we have done, which are coming along. /be Brandon Benvie wrote: The last discussion point there is really important I think. I get a strong sense of the general JS developer world feeling no connection at all to this process, and much can be put directly on the sheer timescale. We've seen 2 month browser version cycles come in force, the living standard that is HTML5 and the as of recent rapid movement of new APIs coming out to JS from not-TC39. People don't feel connected to the
RE: minutes, TC39 meeting Tues 5/22/2012
You are of course right, Brendan, and thanks for addressing my points. Certainly part of this was fueled more by frustration than informed knowledge (see below). -Original Message- From: Brendan Eich [mailto:bren...@mozilla.com] The prototyping efforts are appreciated, but can rarely be used in a comfortable way. (Compared to, say, HTML5.) Remember, HTML5 started in 2004 (WHATWG founding) and still isn't done. Eight years ago. Fair point. I think I and others would be reassured if we had some analogies drawn with the HTML5 timescale: e.g. how long from article, section etc. until they got included in default browser stylesheets, or how long from input type=date to browser UIs. (That last one is actually a pretty good example of slow implementation progress; I feel a lot better about ES6's progress when I think about how we are just now getting a UI for input type=date in Chrome.) * Node.js with --harmony flag gets you collections, old proxies, and (significantly) block scoping. But Node does not make it easy to indicate this file needs to be run with --harmony, or e.g. to require harmony- using files from non-harmony-using libraries. So this ends up being a nonstarter for library authors, leaving it only usable by application writers. Besides, the proxies are still old, which is really unfortunate. That'll be fixed this year, soon I'm told. The proxies, or Node.js? In either case, great news! And in either case, how did you learn about this? I try to stay up to date on all relevant blogs, Twitter feeds, mailing lists, etc., but certainly could have missed one. If it was private communication, perhaps in the interest of helping developers see ES6 progress (as per Brandon's original point) such things could be more publicized in the future? I imagine that's complicated though. And the iteration rate is slowww: stuff like destructuring has been harmonized for a long time, but shows no sign of making it into V8. How would you see the signs? Just asking. I know the Munich team is going strong and they have skills. I don't know detailed schedule, but there is no need to presume inaction or action. Let's ask. I guess I can't really expect to see all the signs through public channels, as above. Still, I think opening such channels would be a valuable thing for the community. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: minutes, TC39 meeting Tues 5/22/2012
From: Rick Waldron [mailto:waldron.r...@gmail.com] Etc. It's ES6-like, but doesn't reflect TC39's actual progress, instead reflecting the Traceur team's interpretation of where TC39 might eventually, hopefully, end up. I don't think this is a fair claim to make, considering Traceur had no real attention for quite some time and Erik Arvidsson really stepped it up to get a nice cross section of features prototyped in a short amount of time. I think what you meant to say was thank you. Indeed you're right, that is what I meant to say. Apologies to Erik, and thanks to JJB for pointing out Traceur is much better suited for my purposes than I thought. I will definitely give it another try. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Subclassing built-in constructors
-Original Message- From: es-discuss-boun...@mozilla.org [mailto:es-discuss- boun...@mozilla.org] On Behalf Of Brendan Eich Sent: Saturday, May 26, 2012 15:08 New syntax may some day clean all this up but the short path wins and it'll be hard to displace. Let's be realistic. I agree we should, assuming classes make it, support DOM subclassing. That is good but it won't relieve DOM implementors from supporting __proto__. Is there a parallel to be drawn with __(define|lookup)(Getter|Setter)__, or is __proto__ different? I quite liked Allen's blog post about why IE decided to never support them [1]. Following that reasoning seems to lead to specifying Object.setPrototypeOf as a __proto__ replacement, and hoping library authors follow suit in switching to that from __proto__, just like they did for the property API. http://blogs.msdn.com/b/ie/archive/2010/08/25/chakra-interoperability-means-more-than-just-standards.aspx ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: arrows and a proposed softCall
-Original Message- From: es-discuss-boun...@mozilla.org [mailto:es-discuss- boun...@mozilla.org] On Behalf Of Mark S. Miller Sent: Thursday, May 31, 2012 22:24 Non-strict mode is so bizzarre that I wouldn't be surprised, but I can't think of an example. Is my proposed rule unsound as stated, since it doesn't distinguish strict and non-strict functions? Is there some way for a non-strict function that doesn't mention this and does not contain a direct eval operator to nevertheless be this-sensitive? I can't quite find the answer: would setTimeout/setInterval/setImmediate have the capabilities necessary? I would assume they all behave as indirect eval, but since they are outside the language spec, it seems possibly implementation-dependent. Other candidates are window.execScript in IE or vm.runInNewContext in Node, but I think both of those are explicitly global scoped, and thus could not reference this. Nevertheless, the idea of implementations providing specific methods with the same abilities as direct eval seems possible. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: super, methods, constructors Co.
-Original Message- From: es-discuss-boun...@mozilla.org [mailto:es-discuss- boun...@mozilla.org] On Behalf Of Allen Wirfs-Brock Sent: Friday, June 01, 2012 04:05 We haven't eliminated the ability to define object literals that inherit from objects other than Object.prototype. We have just changed the syntax for specifying them from: proto | {} to {__proto__: proto} For anyone who (like me) was confused by this in light of all the talk that colons in object literals always do a [[DefineOwnProperty]], there is an exemption made for __proto__ in section B.3.1.3 of the latest spec. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Error stack
Machine-parsability might be reaching too far, especially if you lose the benefits of nice function/method name inference. Instead, perhaps a separate strawman to standardize something like the V8 stack trace API [1]? It is used in Node for providing long stack traces [2], [3], [4]. It's a bit cumbersome, e.g. maybe a separate error.stackFrames getter would be nicer and the Java-style getFileName() methods could become simple properties. But the fact that it exists is extremely useful. [1]: http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi [2]: https://github.com/tlrobinson/long-stack-traces [3]: https://github.com/kriskowal/q/blob/0c1ffdc50a6ea77c3e97075fab35ab9f7b2d/q.js#L261-405, https://github.com/kriskowal/q/blob/0c1ffdc50a6ea77c3e97075fab35ab9f7b2d/q.js#L1307-1321 [4]: https://github.com/NobleJS/WinningJS-todo/commit/2d4ca10c4f672dac9f021b697c4c72bbff321ed9 From: es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org] on behalf of Erik Arvidsson [erik.arvids...@gmail.com] Sent: Thursday, June 07, 2012 16:39 To: Jason Orendorff Cc: es-discuss@mozilla.org Subject: Re: Error stack On Thu, Jun 7, 2012 at 1:12 PM, Jason Orendorff jason.orendo...@gmail.com wrote: This isn't machine parseable in all cases, since the .message may contain newlines and can end with something like \n at ... That is a good point. This also applies to the name of a function (and object when included). It is trivial to create a function name that breaks the V8 style formatting. SpiderMonkey gets away with this by using the name of the function expression and it does not try to deduce a name based on the code.. window['\n@'] = function() { alert(new Error().stack); }; When I first set out to write the proposal I was set on the SpiderMonkey formatting but as I researched this I drifted closer and closer to the V8 formatting. The thing that convinced me was eval. I also don't think that providing ErrorName: ErrorMessage is a hard requirement. The same information is already available using errorObject.name and errorObject.message. If we remove the first line and require that non identifiers are quoted I think we can guarantee that the value is machine parseable again. Changing this in Firefox would affect any Firefox addons that use Error.stack, but maybe we can take that hit. For web apps we already have to parse two different versions so I'm not too concerned about that case. The WebKit mobile web does not depend on either format (Safari doesn't have it in any shipping version yet) so the two problematic big eco systems are Firefox and Chrome extensions (and Node.js?) -- erik ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Default operator strawman - ||| rather than ??
In our experience writing large apps, the distinction is useful. Undefined means I forgot to do something (e.g. set a property or pass an argument); null means I tried to get something but it didn't exist. Very roughly, it becomes undefined = caller error outside of my control, null = my error and I should use the API more correctly. On Jun 14, 2012, at 11:27, John Lenz concavel...@gmail.commailto:concavel...@gmail.com wrote: My two sense. In my experience (large applications, rather than tight libraries), distinguishing between null and undefined is the exception, not the rule. When it is distinguished, as often as not the author would be more correct in either including null or making an property existence check (foo in bar) rather than an explicit check for undefined. On Wed, Jun 13, 2012 at 11:18 AM, Brendan Eich bren...@mozilla.orgmailto:bren...@mozilla.org wrote: Tab Atkins Jr. wrote: Okay, further testing shows that my knowledge was incomplete. Null and undefined compare as double-equal, but neither are double-equal to other falsey values. This is intentional, believe it or don't :-P. In ancient days, void 0 was the only way to spell undefined, and users immediately tested o.p != null to existing-check. There was even some confusion where missing array elements in primordial JS evaluated to null not undefined. Argh, I had made myself forget that, now I remember. However, my argument stands - being undefined-specific is not arbitrary, because that's what is actually returned by such things. Both args without values and properties that don't exist give the value undefined when you try to reference them. Agree still. I do not see use-cases for including null. Maybe they exist, though -- someone please cite some github-hosted JS. Even the Node workaround/premature-optimization of storing null rather than using delete doesn't argue for defaulting based on LHS value in {null, undefined}. Using a double-equal check against null to test for whether something is undefined only works because double-equal is pretty screwed up. It is screwed up but for reasons. Bad reasons, kind of like history or biology. Not just Homer Simpson Life is just a bunch of things that happen randomness, mind you! :-P The most principled reason I've heard, IIRC from @jashkenas, is that null and undefined are confusingly similar, in part due to being ==. This is true, but I still do not see actual use-cases where null is passed into code that uses || to select a default value. Would love to see such real-world code. /be ___ es-discuss mailing list es-discuss@mozilla.orgmailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.orgmailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Default operator strawman - ||| rather than ??
On Jun 14, 2012, at 14:03, Rick Waldron waldron.r...@gmail.commailto:waldron.r...@gmail.com wrote: On Thu, Jun 14, 2012 at 11:58 AM, Domenic Denicola dome...@domenicdenicola.commailto:dome...@domenicdenicola.com wrote: In our experience writing large apps, the distinction is useful. Undefined means I forgot to do something (e.g. set a property or pass an argument); null means I tried to get something but it didn't exist. null is intentional, its presence is explicit -- doesn't this imply that something _does_ exist? (...and its value is null) eg. https://gist.github.com/2926029 Rick Right, I wasn't exactly clear—I meant more the case of e.g. nothing exists in the database, so I gave you back a null or even there wasn't any error, so I called you back with a null as the first param. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Existential operator (was: ||= is much needed?)
What struck me from Jeremy's explanation was the uniformity of CoffeeScript's ? operator (modulo the small issue he mentioned for function calls). It seems to combine the currently-strawman'ed ??/??= and ?. into one very simple semantic. What about adopting ?? as CoffeeScript's ? operator? Would this solve the lookahead problems? So you could do object.property??.other.properties.go.here object.method??(args) This would unfortunately imply, for uniformity, that object ?? other object ??= other become null + undefined tests instead of just undefined. But that might be worth paying. For the record that leaves object?? as the only unimplemented CoffeeScript counterpart. From: es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org] on behalf of Brendan Eich [bren...@mozilla.org] Sent: Tuesday, June 19, 2012 14:08 To: Jeremy Ashkenas Cc: es-discuss Subject: Re: Existential operator (was: ||= is much needed?) Jeremy Ashkenas wrote: Everywhere else in the language, `?` means existence (not null or undefined) -- but when used to call a function, the check ensures that the value is callable as well. In a DWIM sense, this makes sense, because the only things you'd ever want to try to call in JavaScript must be callable ... but I think it's strange that the meaning of existence alters itself just for this use case. I opened a ticket talking about rolling it back to null or undefined semantics here: https://github.com/jashkenas/coffee-script/issues/2315 Apart from people misreading the proposal in this issue, it does seem to be removing a bit of utility, but perhaps that's not actually used? Do CS users try to ?(-invoke a maybe-function that is sometimes neither null nor undefined nor typeof-type function, but rather something that coerces to object? The way to get ?( into JS is by a longer spelling: options.success?.(response) Pretty ugly, but it puts the ? magic right where the maybe-test belongs. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
On Jun 21, 2012, at 3:22, Herby Vojčík he...@mailbox.sk wrote: Brendan Eich wrote: Herby Vojčík wrote: I feel there is objection to introduce magical [[NullPatternObject]] into language, but all of CS-style soft-accesses could be solved very cleanly and consistently. No, because (a) the overhead of a new object is too high; (b) with any kind of suffix-? or suffix-.? as you proposed it would be observable that you get a new object instead of short-circuiting to undefined -- the new object is exposed in the language. What's wrong with it per se? Let it be exposed, let people use it. Some of uses will be wrong, they will eventually die, some of them will be fine, they survive (no need to add keyword or API for it, null.? yields it and it is usably short). And BTW, if foo.? is too long and abuse of dot, you can use for example postfix tilde to get foo~.bar, foo.bar~(), bar in foo~ etc. /be Herby Language-level support for the null object pattern would be pretty excellent! I think, given the CoffeeScript grep stats (not to mention common `options = options || {}` code), people are definitely using ? in that capacity. The possibility of introducing something elegant like this seems like exactly why getting in only property-access ?. would be a mistake. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: The Name of the Name
Why is there concern about uniqueness at all? Won’t this be inside a module? import Symbol from @symbols From: François REMY Sent: Wednesday, August 1, 2012 17:07:02 To: Rick Waldron, Mark S. Miller CC: es-discuss Subject: RE: The Name of the Name Symbol could already be used by parsers and compilers. What about UniqueName? De : Rick Waldron Envoyé : 01/08/2012 22:34 À : Mark S. Miller Cc : es-discuss Objet : Re: The Name of the Name On Wednesday, August 1, 2012 at 4:26 PM, Mark S. Miller wrote: I like it. +1. Symbol was on my short list but worried it was too similar to Name. It seems less likely to conflict with extant code, but not by much. +1 (but we can get weirder if we wanted to) Rick On Wed, Aug 1, 2012 at 1:22 PM, Kevin Reid kpr...@google.com wrote: Lisp precedent: Objects which are used to name things (that is, they are used as keys by identity), and may be not globally-named themselves, are called symbols. On Wed, Aug 1, 2012 at 12:47 PM, Mark S. Miller erig...@google.com wrote: Now that we have both private Names and unique Names, the general category covering both is simply Names. Properties can therefore be indexed by strings or Names. Strings are the ones consisting of a sequence of characters that can typically be pronounced. Names are anonymous identities. In the real world, names and identities are distinct concepts, and names are the one corresponding to a unique sequence of characters that can be pronounced. Is Name exactly the wrong name for a opaque unique identity typically used to index a property? Is there a better term? -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: var declarations shadowing properties from Window.prototype
-Original Message- From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Brendan Eich Sent: Saturday, August 11, 2012 22:57 As noted, they started out that way 17 years ago. I think WebIDL and interface-based method definition made onload, e.g., predefined on window objects, or more recently on Window.prototype. Was this useful? Was it intended specifically (for window, not just intended generally due to WebIDL's uniform rules for binding its definitions in JS)? As a developer, the fact that the properties already exist and are set to null is useful for feature-detection. E.g. any of the following will test for the presence of cross-document messaging: onmessage in window window.onmessage !== undefined window.onmessage === null // assuming no badly-behaved third-party scripts It is also useful strictly from a development POV, because typing `window.on` in the Firefox or Chrome console gives a list of supported events. FWIW, my mental model is probably closest to these being non-magical own data properties, pre-initialized to null, that the browser will read from and use when it fires the corresponding event. They don't make much sense as accessors to me. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: About Array.of()
Array.fromElements is solid, especially considering how rarely this will be used, especially given that it competes in ES6 code with `...x = [...x]` On Aug 27, 2012, at 23:42, 程劭非 csf...@gmail.com wrote: Yes, as a developer (but not English native speaker), I really feel uncomfortable with the name “of”. Considering we already have Object.create String.fromCharCode To keep align with them, I belive “create” or “fromElements” might be better choices. 2012/8/27 Shijun He hax@gmail.com: See the screenshots for the array of search suggestion in search engine. As a non-English native speaker, I'd like to say the search suggestion of array of in non-english languages seems most come from the programmers' input, so it shows how worldwide programmers think what array of means ;) On Mon, Aug 27, 2012 at 10:55 AM, Matthew Robb matthewwr...@gmail.com wrote: I agree with Rick on the general feeling with Array.of If arguing ambiguity I would argue a better method name for type guarded arrays would be Array.ofType On Sun, Aug 26, 2012 at 8:56 PM, Rick Waldron waldron.r...@gmail.com wrote: On Sunday, August 26, 2012 at 7:30 PM, Brendan Eich wrote: Rick Waldron wrote: But Array.of is not. Maybe Array.new is a good name. Array.of is unambiguous with the current ES specification Array.new is ok too, though -- no problem with a reserved identifier as a property name. It's darn nice for Rubyists. OTOH Array.of matches the preposition pattern used in Array.from. But I don't think this trumps Array.new. Nor do I, but I think it poses a problem for polyfilling (which is not a silver bullet). +1 Array.new, but I still think Array.of sounds, feels and looks nicer Rick Cc'ing Dave for his thoughts. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: i18n API - resolvedOptions
For comparison, quite a lot of ECMAScript function names are nouns, e.g. Date.now, String.prototype.{substring, indexOf}, etc. From: Norbert Lindenberg Sent: August 31, 2012 12:16 To: Marcos Caceres CC: es-discuss Subject: Re: i18n API - resolvedOptions Actually, all options have to be resolved in the constructors, because the functions returned by the compare and format getters also depend on the results of the resolution process. resolvedOptions() just packages up the results in a new object and returns that. A correct description in verb form would be getResolvedOptions, but that's yet longer. Norbert On Aug 31, 2012, at 5:31 , Marcos Caceres wrote: Hi, This is a bit of bike shedding Currently, the spec defines resolvedOptions - which is using a noun for a function name. Generally speaking, nouns should not be used as function names, only for attributes/getters. I would urge the function be renamed to resolveOptions(). Dropping the d makes it a verb and gives the operation a sense of active-voice immediacy. I think that more accurately reflects what the method call does (it resolves the options on call and returns you an object) VS returning a set of options that were resolved in the past. Kind regards, Marcos ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Generator issue: exceptions while initializing arguments
On Sep 11, 2012, at 4:39, Brendan Eich bren...@mozilla.com wrote: Brendan Eich wrote: Dmitry Soshnikov wrote: var FOO = 42; function bar(x, y = FOO + z) { var z = 10; } // Error .. ? Translating to JS as it is: var FOO = 42; function bar(x, y) { if (y === void 0) y = FOO + z; var z = 10; } Another benefit of the simple semantics: existing JITs can optimize easily, no new semantics to special-case. This is not a dominant concern but it is a selling point from my experience dealing with (and playing one on TV ;-)) implementors. /be And, if one replaced all `var`s in the above example with `let`s, one would get the desired error, right? To me the most important use cases to consider are those in an idiomatic ES6 let-is-the-new-var world. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Performance concern with let/const
2. The stated goal of 'let' is to replace 'var' in common usage (and if this is not the goal, we should not be adding 'let'). There is actually some disagreement about that statement of the goal. The goal of let is to provide variable that are scoped to the block level. That is the significant new semantics that is being added. The slogan-ism isn't the goal. This strikes at a critical piece of the discussion around 'let'. Adding a new fundamental block scoped binding form ('let') has a very significant conceptual cost to the language. If it is not the expectation of the committee that new code will nearly universally adopt 'let' instead of 'var', and that books will be able to state 'use let instead of var', then I think that brings into question whether 'let' is still passing the cost/value tradeoff. This tradeoff gets increasingly weaker as additional performance overheads are entered into the cost bucket. To provide a (admittedly single) developer perspective: let/const are attractive because they bring us closer to eliminating the confusion inherent in hoisting and achieving the same semantics as C-family languages. Although it seems that disallowing use before declaration is not possible, hoisting to block-level plus TDZ checks for the intermediate code gives a reasonable approximation, at least assuming I've understood the proposals and email threads correctly. There are also a number of auxiliary benefits like the fresh per-loop binding and of course const optimizations/safeguards (which eliminate the need for a dummy object with non-writable properties to store one's constants). Personally in the grand scheme of things even a 5% loss of speed is unimportant to our code when weighed against the value of the saner semantics proposed. We would immediately replace all vars with let/const if we were able to program toward this Chakra prototype (e.g. for our Windows 8 app). I am almost hesitant to bring up such an obvious argument but worrying about this level of optimization seems foolhardy in the face of expensive DOM manipulation or async operations. Nobody worries that their raw JS code will run 5% slower because people are using Chrome N-1 instead of Chrome N. Such small performance fluctuations are a fact of life even with ES5 coding patterns (e.g. arguments access, getters/setters, try/catch, creating a closure without manually hoisting it to the outermost applicable level, using array extras instead of for loops, …). If developers actually need to optimize at a 5% level solely on their JS they should probably consider LLJS or similar. That said I do understand that a slowdown could make the marketing story harder as not everyone subscribes to my views on the speed/clarity tradeoff. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Early error vs. error on first call to function vs. runtime error
As a user, not implementer, I really want early errors. Perf costs of startup are negligible especially long-term. By the time ES6 is in browsers computers and phones should be faster by enough of a factor to mitigate any costs, whereas omitting early errors hurts developers indefinitely into the future. On Sep 28, 2012, at 4:02, Brendan Eich bren...@mozilla.org wrote: Brendan Eich wrote: We have not discussed error-on-first-call in this thread at all! This needs a separate thread. The idea from last week's TC39 meeting was to have not only * Early error, thrown before any code in the Program (grammar goal symbol) containing the error, required by specific language in Clause 16. * Runtime error, all the other kinds. and now * Error on first call to a function, where the function contains what would be an early error but for the supposed cost of early error analysis. The last case is really just a runtime error: a function with what should be a static error becomes a booby trap: if your tests happen to miss calling it, you'll feel ok, but a user who tickles the uncovered path will get a runtime error. TC39 heard from some implementors who wanted to avoid more early error requirements in ES6, or at least any that require analysis, e.g. reaching definitions. That's fair as input to the committee, but implementation concerns are not the only ones we weigh. And we were far from agreed on adding the Error on first call category. The example you imply here would be function f(a, b = c, a = d) { } and the duplicate formal a would be illegal because of the novel default-parameter syntax. Making f into a proximity-fused bomb does not see either good or necessary. The analysis requires to notice duplicate formals is trivial, and as I keep pointing out, ES5 already requires it: function g(a, a) { use strict; } This must be an early error per ES5 clause 16. Given the ES5-strict sunk cost, there's no added implementation tax beyond the logic conjoining duplicate detection with novel-syntax detection, which is trivial. It'd be good to hear from Luke on this. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Early error vs. error on first call to function vs. runtime error
On Sep 28, 2012, at 20:58, Brendan Eich bren...@mozilla.org wrote: John Lenz wrote: The best thing I see for the future is if the Browser vendors didn't reparse JavaScript when loading from cache, this would help the best case scenarios, but doesn't help the worse case where it harder to find wins. Yes, why hasn't this happened? We had a Mozilla intern working on it, but I'm not sure where that went. It seems no major browser caches post-parsed tree serializations or other intermediate forms. Anyone know differently? /be A pretty niche example, but: Windows 8 Store apps written in HTML5/JS are “bytecode cached” at package time, i.e. downloading an app from the store gives you bytecode instead of (or, in addition to?) pure JS. Details at http://msdn.microsoft.com/en-us/library/windows/apps/hh849088.aspx ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: typeof symbol (Was: Sept 19 TC39 Meeting Notes)
From: es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org] on behalf of David Bruant [bruan...@gmail.com] Sent: Monday, October 01, 2012 16:23 To: Brendan Eich Cc: es-discuss Subject: Re: typeof symbol (Was: Sept 19 TC39 Meeting Notes) Try typeof document.createElement('div').offsetParent on IE6-8. I can't verify because I'm not Ubuntu right now, but if I recall it will give you unknown. If it works, credit where it's due, John-David Dalton shared this to me a while ago. If it doesn't work, sorry for the noise. If I had to guess, I'd say it's been fixed in IE9, but I'm interested if someone can test. Yeah, according to IE10 and its compatibility modes at least, IE7 and IE8 give unknown while IE9 and IE10 give object. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Must built-in prototypes also be valid instances? (Was: Why DataView.prototype object's [[Class]] is Object?)
On Oct 1, 2012, at 18:58, Brendan Eich bren...@mozilla.org wrote: I am warming up to the way CoffeeScript does things -- not the translation scheme, __extends, __super__ -- rather, the plain Object instance created as C.prototype that has B.prototype as its [[Prototype]] but has shadowing 'constructor' set to C. If I'm understanding correctly, this would be the same as C.prototype = Object.create(B.prototype); C.prototype.constructor = C; which I thought was the recommended approach (although by who or where, I admit I can't quite pinpoint). Am I on the right track? And can anyone else comment on the commonality or recommendedness of this pattern, to see if we're paving the right cow paths? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Suggestions for Set
-Original Message- From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Brendan Eich Sent: Monday, October 1, 2012 21:43 To: Nicholas C. Zakas I would really like to see a *Set.prototype.toArray* method to easily change the Set back into an array. A simple use case would be de-duping an array: function dedupe(array) { return (new Set(array)).toArray(); } Array.from is the way we hope to avoid burdening many iterables with toArray methods, as Rick pointed out. Ok? Also: function dedupe(array) { return [...new Set(array)]; } This works in Firefox Aurora, for the record :) ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Suggestions for Set
From: Rick Waldron [waldron.r...@gmail.com] Sent: Tuesday, October 02, 2012 16:52 No iteration for spread, per July 24 resolution https://mail.mozilla.org/pipermail/es-discuss/2012-July/024207.html Oh, thanks for catching me on that. Silly Firefox... This seems like an unfortunate decision, and I couldn't discern the motivation in the minutes. When would I want to use a syntax that fails for iterables? Does [...x] throw for an iterable, or result in something else? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Suggestions for Set
From: Rick Waldron [mailto:waldron.r...@gmail.com] Sent: Tuesday, October 2, 2012 17:18 On Tue, Oct 2, 2012 at 5:11 PM, Domenic Denicola dome...@domenicdenicola.com wrote: From: Rick Waldron [waldron.r...@gmail.com] Sent: Tuesday, October 02, 2012 16:52 No iteration for spread, per July 24 resolution https://mail.mozilla.org/pipermail/es-discuss/2012-July/024207.html Oh, thanks for catching me on that. Silly Firefox... This seems like an unfortunate decision, and I couldn't discern the motivation in the minutes. When would I want to use a syntax that fails for iterables? Does [...x] throw for an iterable, or result in something else? The direct reasoning for the resolution was: Cannot be both iterable and array-like I can't really understand what this is trying to say. It must be because I don't understand iterable. Doesn't it just mean responds to for-of? I would imagine arrays, NodeLists, arguments, and other array-likes all respond to for-of; if they don't, that seriously decreases the utility of for-of! It's possible that this could be added to the agenda for november, if Brendan wants to discuss SpiderMonkey's experience implementing it. It seems to me that if they're not having issues then it's at least worth a mention. Yay! ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Symbols, Protocols, Frames, and Versioning
Would it suffice to allow cross-frame sharing of symbols via postMessage and its structured clone algorithm? They're immutable, right? On Oct 3, 2012, at 15:01, Brendan Eich bren...@mozilla.org wrote: Thanks for pointing this out. Python's dunder-prefixing or anything like it in JS has that advantage: you can spell the magic property name with a string that works in any frame or global object. Of course strings can collide. Symbols are useful in spite of this, but it is telling that we want @iterator to be a singleton across all potentially connected frames. So should there be a way in the language to create singleton symbols? If so, how? /be Kevin Smith wrote: One of the main use cases for symbols is for defining object protocols that don't suffer from property name conflicts. The recently discussed `iterator` and `toStringTag` method names fall into this category. The idea is that we can implement the protocol by defining methods using symbols, and thus avoid namespacing considerations. Designing and maintaining a global namespace is, well, no fun. But consider the multiple-global case in which we have scripts running in more than one frame. It seems like protocols should be transferrable across frames. For built-in protocols like `iterator`, this has to work: function f(iterable) { for (x of iterable) { // This must work regardless of which frame `iterable` comes from } } But what about user-defined protocols? Let's say we have a Persistable protocol: export var persistName = new Symbol; // unique, not private And a function which makes use of this protocol: import persistName from Persistable.js; function usePersistable(obj) { if (obj[persistName]) obj[persistName](); } It seems like `usePersistable` should be able to work as expected even if `obj` comes from a different frame (in which Persistable.js was separately loaded). Another expression of the same problem occurs with versioning. Suppose that in a fairly complex module dependency graph, Persistable-0.1.js and Persistable-0.2.js are simultaneously loaded. (Persistable is on github and therefore in perpetual version-zero purgatory.) It seems reasonable to expect that objects implementing the protocol defined by Persistable-0.2.js should be able to work with functions consuming the Persistable-0.1.js protocol. But that is not possible with unique symbols. In summary, I don't think that we can really avoid global namespacing issues using system-generated unique symbols as we currently conceive of them. Built-in protocols like `iterator` are a special cheating case, but we need to have an equally consistent story for user-defined protocols. Kevin ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Symbols, Protocols, Frames, and Versioning
-Original Message- From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Andreas Rossberg Sent: Friday, October 5, 2012 14:46 On 5 October 2012 14:26, Sam Tobin-Hochstadt sa...@ccs.neu.edu wrote: On Fri, Oct 5, 2012 at 8:21 AM, Kevin Smith khs4...@gmail.com wrote: Sounds good. As an aside, does the symbol in this case provide any function other than wrapping the string itself? Does the symbol carry any information that the string does not, from the point of view of the script? No, in this case the results of `Symbol.for` are just a duplicate of the space of strings (just the way interned symbols are in Lisp). Indeed, which is why I'm not sure I understand what this idea is trying to achieve. Is it more than just an ad hoc way to introduce a second namespace? Yes, is this noticeably better than just saying use '__space_of_strings_string'? What does this new API accomplish that can't already be done with a conventional prefix in the normal space of strings? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Function.length and Default Parameters
From: es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org] on behalf of Kevin Smith [khs4...@gmail.com] Sent: Friday, October 12, 2012 12:30 Again: function f(a = 1, b, c) {} f.length === 0; // Huh? You seem to be under the mistaken impression that ES6 allows non-defaulted arguments after default ones. This is not the case. See https://mail.mozilla.org/pipermail/es-discuss/2012-October/025704.html for a (very) recent discussion of this. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Function.length and Default Parameters
On Oct 12, 2012, at 13:03, Kevin Smith khs4...@gmail.commailto:khs4...@gmail.com wrote: You seem to be under the mistaken impression that ES6 allows non-defaulted arguments after default ones. This is not the case. See https://mail.mozilla.org/pipermail/es-discuss/2012-October/025704.html for a (very) recent discussion of this. I don't think that is true. See Allen's response here: https://mail.mozilla.org/pipermail/es-discuss/2012-October/025709.html Oh, wow, thanks for correction. Sorry for the noise everyone X_x. I got the opposite impression from other responses in the thread. Will be sure to update the @esdiscuss Twitter account. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Request for feedback on a talk on I'm giving on ES6
(Attempting to send again with fewer URLs to avoid being spam-filtered? Apologies if this shows up twice.) On Monday I'll be giving a talk about ES6 at EmpireJS. I just finished up my slides, and would love some feedback and critique from the es-discuss crew: https://jh2kcg.sn2.livefilestore.com/y1pLp4Fh3CL9rp5A__EenS-TzdbQJMwG8IeIzQ_aRUbd6GakGmTcdBxx9Ec5SpKyfdHrDF0lFXr9sGfQJJVswnNAw/ES6%20is%20Nigh.pdf The slides consist primarily of code examples of almost every new feature, so accuracy checks and ES6-idiomaticness-improvements would be very helpful. It has way too many slides for 30 minutes, so I'll be cutting large swathes of it to focus on those I classify as least-known but most-powerful. Nevertheless, feedback on all the slides would be lovely, given that I'll be using the rest of them in longer-form talks elsewhere. I also plan on submitting the code examples for inclusion in Dave's new wiki, or using them in other educational outreach efforts (e.g. blog posts), or even in a mini test suite so we can see how Chrome and Firefox's current implementations compare to the specced behavior. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Request for feedback on a talk on I'm giving on ES6
Thanks so much for the feedback! -Original Message- From: Brendan Eich [mailto:bren...@mozilla.org] Sent: Sunday, October 21, 2012 14:17 Slide 15 has a comment at the bottom: // error! used a `let` before declaration but this error is about the most-indented log call, the one in the block whose last child is 'let log = Math.log'. Perhaps you are going to talk around it, but it seems to me a comment about an error should go right where the error is. My intention here was to show that it's a runtime error that doesn't occur until you actually use the function, instead of a static error. You're right though that the stack trace will point to that line instead of the one I have marked. I'll try to come up with a better approach. Slide 31 ends with a question: // what about `module.exports= aFunction`? Cc'ing dherman. Yeah, since there will be lots of Node-ers there, and this is their #1 feature, I thought it was important to point out there's no solution for that yet. In general my impression is that modules are undergoing some rethinking and revision, especially about syntax. It's tricky, since even if I cut those slides, I want to e.g. import iterator, but am not sure what syntax to use :-/. Slide 33 has a recursive call not in tail position: Damn, OK, I thought my example met the definition at http://wiki.ecmascript.org/doku.php?id=proposals:proper_tail_calls (in particular the only thing the caller can do when the call terminates is return the value of the call to its own caller). It sounds like I don't quite understand tail recursion still, so thanks for the link---I'll brush up. Slides 34-35: do you want to show a multiline regexp with insignificant whitespace a la Perl's /x regex flag? Nice, I hadn't heard about that use case but it makes perfect sense. I also like http://wiki.ecmascript.org/doku.php?id=harmony:quasis#flexible_literal_syntax now that I'm looking through the wiki. Slide 44 is good, a WeakMap beats a Map so you get automatic deletion when a given httpResponse dies. Could you show entries whose values might be keys (or parts of keys) of other entries? That would show the double-whammy. This is a good idea, especially since it helps distinguish from slide 45 (wherein I replicate the WeakMap example with symbols, albeit with breakage for extension-prevented objects). Looks great, more slides under construction? Need a rousing conclusion ;-). Haha yeah, the real work is turning this from a meetup talk (primarily didactic) into a conference talk (inspirational and engaging). Still figuring that out, although I am very happy with the current intro (derived from your Hacker News replies). I might steal always bet on JS, or maybe I'll emphasize the way we can use these features today (SpiderMonkey, Chrome Embedded Frame or Node.js apps with flags, Traceur and other transpilers for the non-magic...). Still thinking on it, and of course toeing the sleep-dep/productivity line. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Request for feedback on a talk on I'm giving on ES6
Thanks for your help Rick! I've corrected a few, but wasn't sure about some others. Let me know if I'm missing something in the following: From: Rick Waldron [mailto:waldron.r...@gmail.com] Sent: Sunday, October 21, 2012 17:07 nit: The comment itself says // error! used a `let` before declaration., might be nice to highlight that the error will occur until the let is assigned, ie. I can initialize it, but reads will throw until it's assigned. If I'm understanding you correctly, you're saying that this should throw? let x; assert(x === undefined); // error! Use of `x` before it is assigned. I was under the impression the temporal dead zone was about use-before-definition, not use-before-assignment. (For const they are the same, since the Static Semantics: Early Errors note on page 125 of the spec gives a Syntax Error if the Initialiser is omitted from the LexicalBinding.) That is: A let and const declarations define variables that are scoped to the running execution context’s LexicalEnvironment. The variables are created when their containing Lexical Environment is instantiated but may not be accessed in any way until the variable’s LexicalBinding is evaluated. A variable defined by a LexicalBinding with an Initialiser is assigned the value of its Initialiser’s AssignmentExpression when the LexicalBinding is evaluated, not when the variable is created. If a LexicalBinding in a let declaration does not have an an Initialiser the variable is assigned the value undefined when the LexicalBinding is evaluated. This implies to me that the first line above evaluates the LexicalBinding, assigning the variable the value undefined; since the LexicalBinding is evaluated, the may not be accessed clause no longer applies, and no error should occur. Not sure of the number, but there is a slide titled Block Scoping with this: if (Math.random() 0.5) { function go() { console.log(gone!); } ... } assert(typeof go === undefined); I'm not sure I get what this one is trying to illustrate, because go will always be initialized, regardless of the condition I believe this is not true. The current semantics for block-scoped functions bind them to the block, not to the surrounding function. (That is, a FunctionDeclaration creates an entry into LexicallyDeclaredNames, not into VarDeclaredNames.) Even in ES5, this behavior is unspecified: see the NOTE under the Semantics heading under section 12 of ES5.1, where it notes that even though Statement does not include FunctionDeclaration, implementations often allow it, with significant and irreconcilable variations. (So, I don't think go will always be initialized in all browsers. For example, in IE10 strict mode the above code is a SyntaxError.) It also says that Future editions of ECMAScript may define alternative portable means for declaring functions in a Statement context. And indeed, in ES6 the Declaration grammar production is introduced as a sibling to Statement under Block. It includes LexicalDeclaration and FunctionDeclaration; VariableStatements are left under Statement. And the Block Declaration Instantiation algorithm (10.5.4) includes both LexicalDeclarations and FunctionDeclarations, i.e. FunctionDeclarations are added to the block's Declarative Environment Record instead of to the environment record of the containing function. new Set(...document.body.children); is a Syntax Error, use: new Set([ ...document.body.children ]); Same for: new Set(...array) Math.max(...array); Math.max(0, ...array, 5, ...array2); new Date(...dateFields); array.push(...array2); I don't think any of these is a syntax error, since spread works for function calls/constructs too. See http://tc39wiki.calculist.org/es6/spread/ or section 11.2.5 of the draft spec wherein the expanded runtime semantics for ArgumentListEvaluation are given (in particular ArgumentList: ...AssignmentExpression and ArgumentList: ArgumentList, ...AssignmentExpression). However, you are right that the sets should be constructed that way, since the Set constructor accepts an iterable and not varargs. Much appreciated! Also, I just realized that in rearranging my slides I used spread before discussing it -_-. Will need to fix. Maybe rest and spread are more comfort than cowpath-paving... Weak Sets aren't specified yet. Might be wise to omit that? Yeah, probably a good place to trim the fat. They are harmonious though, right? Since they're necessary for revocable proxies. One of WeakMap's best use cases is private data... ... This way any number of methods, both on C's prototype or class-side functions, as long as they are defined in the same scope that priv is bound to, can access the private cache in priv. This beats leaky plain object abstractions for a serious win :) The problem I've always had with this is that using weak maps for objects you control is silly, when you could just use symbols. Indeed I illustrate
RE: Request for feedback on a talk on I'm giving on ES6
Thanks to all for the feedback. I incorporated as much as I could into the presentation, and I think got all the accuracy issues straightened out, pending potential misunderstandings of Rick's points. I posted both the unabridged version and the EmpireJS 30-minute version at http://es6isnigh.com/ (or, if the DNS isn't working yet, http://domenic.github.com/es6isnigh/). Still much to do before I'd consider the full version done: e.g. incorporate Brendan's template string regexes and weakly-held values examples, convert to HTML instead of PowerPoint/PDF, and so on. But it's a start! Now all I have left to do is actually get up on stage and present, heh. I'll update the 30-minute slides throughout the day if anyone has remaining corrections or suggestions. -Original Message- From: es-discuss-boun...@mozilla.org [mailto:es-discuss- boun...@mozilla.org] On Behalf Of Domenic Denicola Sent: Sunday, October 21, 2012 13:46 To: 'es-discuss@mozilla.org' Subject: Request for feedback on a talk on I'm giving on ES6 (Attempting to send again with fewer URLs to avoid being spam-filtered? Apologies if this shows up twice.) On Monday I'll be giving a talk about ES6 at EmpireJS. I just finished up my slides, and would love some feedback and critique from the es-discuss crew: https://jh2kcg.sn2.livefilestore.com/y1pLp4Fh3CL9rp5A__EenS- TzdbQJMwG8IeIzQ_aRUbd6GakGmTcdBxx9Ec5SpKyfdHrDF0lFXr9sGfQJJVswn NAw/ES6%20is%20Nigh.pdf The slides consist primarily of code examples of almost every new feature, so accuracy checks and ES6-idiomaticness-improvements would be very helpful. It has way too many slides for 30 minutes, so I'll be cutting large swathes of it to focus on those I classify as least-known but most-powerful. Nevertheless, feedback on all the slides would be lovely, given that I'll be using the rest of them in longer-form talks elsewhere. I also plan on submitting the code examples for inclusion in Dave's new wiki, or using them in other educational outreach efforts (e.g. blog posts), or even in a mini test suite so we can see how Chrome and Firefox's current implementations compare to the specced behavior. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Map.prototype.clear method
On Oct 22, 2012, at 14:28, Yehuda Katz wyc...@gmail.commailto:wyc...@gmail.com wrote: On Mon, Oct 22, 2012 at 11:11 AM, Axel Rauschmayer a...@rauschma.demailto:a...@rauschma.de wrote: What about copying of these new data structures? It should be possible to initialize a collection via another collection (right?). I prefer copy-constructors to clone() methods. That would be fine with me, if supported. Isn't it already specced to work, for Set at least, since it accepts any iterable? let copy = new Set(original); I don't recall offhand if Map accepts an iterable of [key, val] pairs, but if it doesn't yet, maybe this provides an argument that it should. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: `free` operator
I do think that including this as a debugging tool is where the most value is. Whether through an engine-provided API (like V8's gc()/--expose-gc) or through something more standardized, like the existing `debugger` statement, is the real question. On Oct 25, 2012, at 21:04, Alex Russell slightly...@google.commailto:slightly...@google.com wrote: This use-case is usually what weak refs get pressed into service for. But I think that answering your question, why is my RSS continually increasing? is something for a tool (debugger, profiler, etc.) to help answer. Some sort of assertion version of free() seems like the right thing: it can communicate your intent there be no refs at that point to a tool. E.g. console.assertFree(obj); Regards On Oct 25, 2012 7:58 PM, Isaac Schlueter i...@izs.memailto:i...@izs.me wrote: On Fri, Oct 26, 2012 at 1:35 AM, Shawn Steele shawn.ste...@microsoft.commailto:shawn.ste...@microsoft.com wrote: I sort of have a fundamental problem with the solution. Eg: If it were actually unused, it'd be GC'd. Since it isn't GC'd, something must be holding a reference to it. So if you force it to be gone, or clear all the properties, or whatever, seems to me that then you'd just start throwing random errors in the code that tried to use the freed object? That might be even harder to track down. On the contrary, TypeError: Cannot read property 'prop' of undefined, with a stack trace, is WAY easier to track down than The RSS on my server gradually rises, until the operating system kills it, which happens about every 4 hours. Fast failure is not as good as success, but it's better than anything else. On Thu, Oct 25, 2012 at 4:16 PM, Isaac Schlueter i...@izs.memailto:i...@izs.me wrote: It'd be really nice if JS had a way to explicitly delete an object. I guess you mean ... a way to set all the refs to a object to undefined. Yes, exactly. On Fri, Oct 26, 2012 at 1:20 AM, John J Barton johnjbar...@johnjbarton.commailto:johnjbar...@johnjbarton.com wrote: var obj = {} var foo = { ref: obj } I assume that in your real life, you don't know 'foo' but somehow you know that foo.ref is never used? Well, you know that IF foo.ref is used, it's an error, and ought to throw. Also, it's quite easy to check if the property exists, and set it to a new object if so. It's common to have things like: if (!this._parser) { this._parser = new ParserThingie(); } In this example, imagine that parsers are expensive to create. So, we try to reuse them (danger!), and over time, our program grows until we have some code paths where the parsers are not getting all of their data removed properly. If the parser has a ref to an object that has a reference to some other thing, etc., then you've got a memory leak. This exact situation happened in Node's HTTP library a few months ago, and was very tedious to fix. We quite easily identified one of the things in the chain, and that it must have been linked in some way to an HTTP parser (or else it would have been GC'ed). It would have been much easier to just find the point where we know that the HTTP response object should be finished, and forcibly remove any references to it. Since you know obj can you set it to be a getter that returns undefined? Yeah, but the purpose of this is to take *away* the ref that you already *have*. What good is a getter that returns undefined, once you've already gotten it? Closing the barn door after the horse has left. Deleting all of the properties of obj would solve the problem as well I assume. But that is a bit more whack-a-mole, and expensive. Ultimately, what we did was move all of the addon properties on parsers to a single object, and delete that object when we re-use the http parser. ___ es-discuss mailing list es-discuss@mozilla.orgmailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.orgmailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: `free` operator
On Oct 25, 2012, at 23:13, Andrew Paprocki and...@ishiboo.com wrote: On Thu, Oct 25, 2012 at 10:14 PM, Shawn Steele shawn.ste...@microsoft.com wrote: On the contrary, TypeError: Cannot read property 'prop' of undefined, with a stack trace, is WAY easier to track down than The RSS on my server gradually rises, until the operating system kills it, which happens about every 4 hours. I'm not so sure. Now you know where you're using it that you didn't think you were, but you've now got something freeing it that's not supposed to. So you might have to check each of those frees to see where they weren't supposed to free, possibly without much context at the other end. You've traded one problem for a different one. I can offer that we do this pretty commonly with certain native objects wrapped into JS and that it is useful, albeit trading problems, as you say. My personal observation is that it is much easier for a large body of JS programmers to grasp this use-after-free class of bugs than tracking down GC related issues such as a closure capturing a scope to which someone unknowingly added a variable keeping a whole tree of things alive. I would love it if tools could to a better job at illustrating why objects are kept alive, though. There is no desire to standardize JS bytecode or anything of that nature, but perhaps there is room to standardize some kind of serialized GC heap view akin to a 'core' file for debugging purposes so that tool writers have an easier job? There are already some pretty good debugging tools for inspecting the JS heap, both in Web Inspector and (for IE/Windows 8 users) in Visual Studio 2012 Update 1. Standardizing them seems not that useful; they're already working well. The new thing this proposal brings to the table is the ability to mark, from within your code, exactly what object you're worried about the leakiness of. You also get very understandable error messages for determining who's using that object. Pouring through the list of retained objects, trying to find the one you're concerned about by looking through ambiguous short names or via the profiler's deep tree hierarchy, is not nearly as straightforward. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Array.prototype.contains
-Original Message- From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Erik Arvidsson Sent: Friday, November 2, 2012 13:21 If we call it has, should we also rename String.prototype.contains? I'd say no; the distinction between collections having an element and strings containing a substring seems very sensible. It's a bit more awkward to say a string has a substring, and a string is definitely not a collection of substrings in any reasonable sense. If anyone had proposed String.prototype.has(singleCharOrMaybeCodePoint), then perhaps that name would make sense. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Promises
I guess now is a good a time as any to pre-announce Promises/A+: https://github.com/promises-aplus/promises-spec It’s an attempt to improve significantly on the minimal-but-perhaps-too-minimal Promises/A of CommonJS, making the language more rigorous and speccing several important things Promises/A missed. Here’s a short summary of the differences: https://github.com/promises-aplus/promises-spec/issues/17 The two most important ones, in my opinion, are: * Cover the case of handlers returning a promise (chaining) * Require asynchronous resolution Promises/A+ is a collaborative effort led by Brian Cavalier (when.js) with help from myself and Kris Kowal (Q), as well as Yehuda Katz (rsvp.js, TC39) and others with whom I am less personally familiar with but have also been very helpful. --- I say “pre-announce” because there are a number of bookkeeping issues we want to take care of before saying it’s truly done: https://github.com/promises-aplus/promises-spec/issues But everything important is already in the repo. We also have a (again, preliminary) conformance test suite at https://github.com/promises-aplus/promises-tests --- I hope this is helpful to TC39 or others considering promise standardization. My ideal vision is that the community experiments with promises + generators (a la taskjs) in the ES6 timeframe, then in ES7 we standardize on something like the concurrency strawman or a C#-like async/await pattern based on promises. We welcome feedback from TC39 and others, preferably as GitHub issues in the repo (and thus we can avoid derailing this thread). We’d especially love the eyes of spec-experienced folks such as those that frequent this list. From: David Bruant Sent: November 6, 2012 13:47 To: EcmaScript Subject: Promises Hi, In a post to public-script-coord yesterday, Alex Russel wrote the following [1]: [Web]IDL *is handy. *More to the point, it's the language of the specs we have now, and the default mode for writing new ones is copy/paste some IDL from another spec that looks close to what I need and then hack away until it's close. This M.O. is exacerbated by the reality that most of the folks writing these specs are C++ hackers, not JS developers. For many, WebIDL becomes a safety blanket that keeps them from having to ever think about the operational JS semantics or be confronted with the mismatches. I wasn't aware of this and then read through about a dozen WebAPIs [2] between yesterday and today and... discovered it's the case. In my opinion, one of the most absurd example is the DOMRequest thing which looks like: { readonly attribute DOMString readyState; // processing or done readonly attribute DOMError? error; attribute EventListener onsuccess; attribute EventListener onerror; attribute readonly any? result; }; Read it carefully and you'll realize this is actually a promise... but it has this absurd thing that it has to have both an error and result field while only one is actually field at any given point. Also, these APIs and JavaScript as it they are won't support promise chainability and the excellent error forwarding that comes with it off-the-shelf. Also, the lack of a built-in Q.all really doesn't promote good code when it comes to event synchronization. Oh yes, of course, you can always build a promise library on top of the current APIs, blablabla... and waste battery with these libraries [3]. I'm coming with the following plan: 1) get promises in ECMAScript 2) get WebIDL to support ECMAScript promises 3) get browser APIs to use WebIDL promises About the first step, there is a strawman [4] that contains promises and it requires to define the event loop, so that's probably too much for ES6. Yet, it doesn't prevent to agree on a promise API that will be adopted in ES7. Besides the strawman, promises have run a long way from CommonJS [5] to jQuery [6] to Q [7] to Irakli's excellent post [8] to Domenic's recent rant [9] and I've missed a lot of other examples probably. The JS community is ready for promises. The idea has been used a lot. Different libraries have different APIs and I have no preference. The only things I really care about is chaining (with error forwarding) and a promise-joining function à la Q.all. I'll let people who care about naming fight. I'm sure TC39 can come to an agreement *before* ES7 standardization, agreement that can be used by WebIDL and browser APIs (why not implemented long before ES7 work has even started). If you're a JS dev and care about promises, please show some support to this proposal :-) David [1] http://lists.w3.org/Archives/Public/public-script-coord/2012OctDec/0122.html [2] https://wiki.mozilla.org/WebAPI#APIs [3] http://assets.en.oreilly.com/1/event/79/Who%20Killed%20My%20Battery_%20Analyzing%20Mobile%20Browser%20Energy%20Consumption%20Presentation.pdf [4] http://wiki.ecmascript.org/doku.php?id=strawman:concurrency [5]
RE: Promises
From: es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org] on behalf of Mikeal Rogers [mikeal.rog...@gmail.com] Sent: Tuesday, November 06, 2012 15:33 also, node.js won't adopt either a promise API or a promise syntax for it's core API. if it lands in the language then nothing is stopping people from using it but the ecosystem is highly unlikely to adopt it either since it's not uniform across node. Um: https://twitter.com/izs/status/257634118320410624 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Promises
As an interesting aside, I just wanted to highlight the section of Promises/A+ that Rick was referring to, because I think it uses a rather clever trick to avoid discussing the event loop while still requiring the behavior we want: onFulfilled and onRejected must not be called before then returns [1]. This trick is borrowed from Kris Kowal's UncommonJS promises specification. -Original Message- From: es-discuss-boun...@mozilla.org [mailto:es-discuss- boun...@mozilla.org] On Behalf Of David Bruant Sent: Tuesday, November 6, 2012 14:43 To: Rick Waldron Cc: EcmaScript Subject: Re: Promises Le 06/11/2012 20:35, Rick Waldron a écrit : Based on a read through of https://github.com/promises-aplus/promises-spec, these things initially come to mind, please regard as a loose collection of varying thoughts that may or may not be completely relevant: 1. The definition of a promise is really just a plain object or function with an expando property, I would think that a language level addition would require its own standard built-in object: Promise, which when invoked as a constructor initializes a new promise object which has a then method... Domenic has it covered from there. I fully agree. 2. The notes describe some excellent practical implementation points, but none of them are actually part of the ECMAScript standard, eg. setTimeout, process.nextTick. Should these be specified or left unspecified? Object.observe describes delivery as Schedule change events to be delivered asynchronously 'at the end of the turn', which is not very specific. As I suggested, Object.observe opens the breach and I think it means the event loop (including the notion of turn) will have to be fully specified within ECMAScript. 3. Does this belong in the language or would it make more sense to exist as a standard module? Are you referring to the event loop or promises? event loop : the language promises : arguably standard module David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Promises
-Original Message- From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Axel Rauschmayer Sent: Tuesday, November 6, 2012 19:07 Different issue: do we already have a solution for a missing error handler causing silent failures? task.js should cover this, too (right?) Yes, since task.js essentially adds fulfillment and rejection handlers everywhere automatically, it's impossible to be left with an unhandled rejection. (This assumes you use `yield` on all your promises, but then again, if you don't, you are essentially signaling that you don't care about the result.) ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Promises
From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Kevin Smith Sent: Wednesday, November 7, 2012 09:58 The only hard part that isn't really addressed by currently library implementations is error handling. I feel pretty strongly that rejections (and by extension, errors thrown from `then` callbacks), should ALWAYS be observable. In other words, if a rejection is not observable via error listeners at the time when error listeners should be called, then an unhandled error should be thrown by the runtime. In my usage of promises I have never wanted anything other than this behavior. The problem with this is that it disallows treating promises as first-class objects that can be passed around, unobserved, only to be observed at a later date. As a trivial example, consider: ``` let promise = Q.reject(); // a rejected promise setTimeout(= { promise.then(null, (err) = { console.err(Got an error!, err); }); }, 100); ``` In this example there is nobody observing the promise at the time it is rejected, or even a tick after rejection. So should the rejection be thrown by the runtime? You would suggest yes. But then the error handling code inside the `setTimeout` will never be called. --- OK, so that's a trivial example. What about a less trivial example? Well, consider using promises as remote objects. A rejected promise could be passed across the wire in various ways, all of which take much longer than a single tick. Or consider just normal control flow that uses promises as first-class mechanisms of state. For example the upthread-mentioned promises in place of loading events: many libraries will only end up listening to loading events far after they are completed, since the loading promise is a first-class observable property of the object being loaded (page, image, database, etc.). In short, it creates a serious refactoring hazard. If you accept a promise, you can no longer introduce asynchronicity into your functions that handle it (ironic!) due to the risk of its errors escaping you: ``` function processData(promiseForDatabase) { // All good: return promiseForDatabase.then(= ..., = ...) } function processData(promiseForDatabase) { // No good!! You lost the state of `promiseForDatabase`. Its errors have escaped, // possibly crashing your app if you are e.g. in a Node.js or Windows 8 Metro environment. return getDataForPreprocessing().then(= { return promiseForDatabase.then(= ..., = ...); }); } ``` --- As mentioned upthread, this is solved by task.js, but this is by far the thorniest issue faced by promise implementations today. In Q and WinJS, the solution is to always cap your promise chains with `.done()`. So all promise code should either be returning the promise, or capping with `.done()`. Other mechanisms we are considering are mostly about enabling greater visibility into any currently-unhandled rejections. For example, some type of Q.onunhandled/Q.onhandled pair, or integration into some simple browser-console extensions that would create a pane where you could view such rejected promises, or a mode that sets a maximum timeout before we consider an unhandled rejection erroneous and throw it (for development purposes), or somehow showing the errors on exit (page unload, process exit in Node, ...). ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Promises
From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Mark S. Miller Sent: Friday, November 9, 2012 08:33 Hi David, thanks for your thoughtful post. I've always used the two-arg form of .then[1], but your post makes a strong case for more often using separate one-arg .then and .fail calls. We have found this to be more expressive as well. Especially in ES5 environments, where we can use Q's alias of `catch` instead of `fail`: p1.then(val = doStuff) .catch(err = console.error(err)); I have been using when rather than then. Because these are otherwise compatible AFAICT with A+, for the sake of consensus I'm willing to change this to then everywhere. But before I do, I'd like to make one last plea for when and see how this community responds. I think perhaps because of my background as someone who has only ever programmed for nontrivial amounts of time in curly-bracket languages (C, C++, C#, JavaScript), I really don't see then as part of an if-then-else chain. None of your examples seem confusing to me! I don't know though, as this is obviously very subjective. However, I see a lot of value in when as a word still. Then makes sense when used as a method: doThis().then(doThat).then(doAnotherThing) But when makes sense when used as a function: let this = doThis(); let that = when(this, doThat); let anotherThing = when(that, doAnotherThing); or even let that = when(this).then(doThat); where here `when()` is either making a value into a promise or assimilating an untrusted (or crappily-implemented) promise. It also, to me, makes sense when used as a message, in the sense of promiseSend. This is a bit less important though I guess. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
then
The recent promise discussion prompted me to recall the following musing/proposal from Kris Kowal: https://github.com/kriskowal/q/wiki/On-Exceptions In short, there's a common code pattern that you can do with promises that you can't do with synchronous code. The proposal is for a language extension `then` that would allow synchronous code like this: var info, processed; try { info = JSON.parse(json); } catch (exception) { console.log(Information JSON malformed.); } then { processed = process(info); } catch (exception) { console.log(Error processing information.); } Since seeing this, I've run into a lot of situations where a `then` would come in handy. I wanted to see if anyone else thought this was a great idea, and if it has any chance as an ES7-level proposal. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: then
The idea is to not do the processing if the JSON parsing fails. From: Cryptic Swarm [mailto:crypticsw...@gmail.com] Sent: Friday, November 9, 2012 11:55 To: Domenic Denicola Cc: es-discuss@mozilla.org Subject: Re: then The following should work? Finally expects a block statement, so need to wrap it in { }... var info, processed; try { info = JSON.parse(json); } catch (exception) { console.log(Information JSON malformed.); } finally { try { processed = process(info); } catch (exception) { console.log(Error processing information.); }} On Fri, Nov 9, 2012 at 1:46 PM, Domenic Denicola dome...@domenicdenicola.commailto:dome...@domenicdenicola.com wrote: The recent promise discussion prompted me to recall the following musing/proposal from Kris Kowal: https://github.com/kriskowal/q/wiki/On-Exceptions In short, there's a common code pattern that you can do with promises that you can't do with synchronous code. The proposal is for a language extension `then` that would allow synchronous code like this: var info, processed; try { info = JSON.parse(json); } catch (exception) { console.log(Information JSON malformed.); } then { processed = process(info); } catch (exception) { console.log(Error processing information.); } Since seeing this, I've run into a lot of situations where a `then` would come in handy. I wanted to see if anyone else thought this was a great idea, and if it has any chance as an ES7-level proposal. ___ es-discuss mailing list es-discuss@mozilla.orgmailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Promises
Why go purposefully against the existing terminology of the JavaScript ecosystem? Just say “deferred” where you have “promise” and “promise” where you have “future” and you avoid needless confusion and conflict. This isn’t Scala; we have existing terminology for exactly these concepts. Just use it. From: Kevin Smith Sent: November 14, 2012 11:23 To: David Bruant CC: Mark S. Miller, EcmaScript Subject: Re: Promises If the second argument is optional, it's possible to have both one-arg and two-arg styles in the same API. What do people think about this idea? Maybe - minimalism served the class proposal quite well. It might be a good strategy here, too. Here's what I'm thinking: // Creates a new promise let promise = new Promise(); // Resolves the promise (ala Q) promise.resolve(value); // Rejects the promise (ala Q) promise.reject(value); // A handle to the eventual value of the promise promise.future; // The then method (ala Promises/A+) promise.future.then(val = { // Success handler }, err = { // Error handler }); // Returns a future for the value Promise.when(value); // Returns a rejected future with the specified error Promise.reject(error); // Returns a future for every eventual value in the list Promise.whenAll(list); // Returns a future for the first resolved future in the list Promise.whenAny(list); Initial implementation here: https://github.com/jscloud/Promise I think it's important to separate Promise from Future. Back in the CommonJS mailing list days, there was contention between Promises/A (thenables) and Promises/B (basically Q). But they really are complementary: futures and promises. - Kevin ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Promises
From: Kevin Smith [khs4...@gmail.com] Sent: Wednesday, November 14, 2012 11:41 Why go purposefully against the existing terminology of the JavaScript ecosystem? Just say “deferred” where you have “promise” and “promise” where you have “future” and you avoid needless confusion and conflict. I prefer to find the optimal solution first and then consider migration costs later. I think you meant optimally colored bikeshed, but OK. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: let and strict mode
Personally, the fact that modules opt in to strict mode completely obviates the problem for me. I anticipate this to be the case for most non-beginner ES programmers as well, since they are largely using either a CommonJS-like or an AMD module system, and as part of an ES6 migration would then move to ES6 modules. (Note: perspective bias probably in play here.) Even for future-beginners, i.e. beginners in a post-ES6 world, they will presumably be taught to always use modules. Of course it remains important to specify exactly which course you guys want to take, but I just wanted to provide some perspective that the exact solution for non-strict code is probably, hopefully, not terribly impactful. I guess this could be an argument toward (1)? -Original Message- From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Brendan Eich Sent: Sunday, November 18, 2012 04:25 To: Yehuda Katz Cc: es-discuss Subject: Re: let and strict mode Yehuda Katz wrote: On Sat, Nov 17, 2012 at 6:06 PM, Brendan Eich bren...@mozilla.com mailto:bren...@mozilla.com wrote: Dave Herman proposed as part of 1JS that module imply strict mode, so let is reserved in module. So that helps. For let outside of modules, we could contextually parse let at start of statement if followed by an identifier or a { that starts an object pattern. We could even allow LineTerminator after let, and perhaps should try to get away with that. But if we allow LineTerminator and risk some backward incompat, can we up the ante by allowing [ after let? Who knows, but we have some choices: 1. 'let' only in strict code including modules per 1JS as originally proposed. This would essentially be sending the message: get your ES5 house in order before trying to use ES6 binding forms. I'm not sure how I feel about this, but getting people to clean up code invalid in ES5 strict mode is a nice carrot. Yes, this is the simplest and safest course. 2. 'let' followed by identifier or { but not LineTerminator. 3. 'let' followed by identifier or { with LineTerminator and other space allowed in between. 4. 'let' followed by identifier, {, or [ and LineTerminator in between is ok. Trying to identify `let` usage by known ES6 syntax could be future hostile, by limiting our ability to extend the BindingList grammar. It would essentially restrict us from adding any prefixes to BindingIdentifier that could be ambiguous in ES5. I'm not fully enough aware of all of the historical proposals to know whether any of these could become issues in the future: let ?foo, let ^foo, let foo. Maybe there's something I'm missing and this category of problem could not arise? Good points, especially ? as prefix, although we seemed to agree that patterns are irrefutable (match undefined), so a refutable option might prefer prefix-! to imply a cut (throw in a binding form; try next pattern in a multi-match construct). 5. We could also allow 'let' per (4) in functions not in modules that do not use strict but do use new ES6 syntax in their heads, e.g. destructuring parameters, default parameters, rest parameters. Those head features could arguably opt into 'let' syntax but not strict mode. I'd be worried that it would confusingly break refactored code: function isPermitted(user) { var permissions = [].slice.call(arguments, 1), let = authorize(permissions); if (!let) { return false; } else return permissions; } // to function isPermitted(user, ...permissions) { var let = authorize(permissions); if (!let) { return false; } else return permissions; } Yes, this is a downside. I don't favor (5) on this account. New syntax is its own opt-in but using a rest parameter should not opt the whole body into a different piece of new syntax. /be Comments? /be Kevin Smith wrote: var let = function() {}; let(); If let is a contextual keyword (in non-strict mode of course), then we can look ahead to the token after `let` to validate it. An open paren cannot follow a let *keyword*, so therefore it must be an identifier. var let = { it: be }; let.it http://let.it http://let.it // be Same logic applies. A dot cannot follow a let keyword so we parse it as an identifier. On the other hand, an open square bracket *can* follow a let keyword (by array destructuring), so we have a potential ambiguity there. - Kevin ___ es-discuss mailing list es-discuss@mozilla.org mailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Yehuda Katz (ph) 718.877.1325 ___ es-discuss mailing
RE: Subclassing basic types in DOM - best method?
For URLQuery in particular, since it's a String-String map, why not just use a plain-old-JavaScript-object with appropriate interceptions via a proxy? This provides a much more idiomatic API: new URLQuery(object) stays the same urlQuery.get(name) - urlQuery[name][0] urlQuery.getAll(name) - urlQuery[name] urlQuery.set(name, values) - urlQuery[name] = values; use proxy here urlQuery.add(name, values) - urlQuery[name].push(...values); use proxy here urlQuery.has(name) - Object.prototype.hasOwnProperty.call(urlQuery, name) urlQuery.delete(name) - delete urlQuery[name] urlQuery.delete(name, value) - if (urlQuery[name]) { urlQuery[name] = urlQuery[name].filter(x = x !== value); } use proxy here means use it to do argument validation and manipulation of the associated URL object, with percent-encoding. The above assumes you want urlQuery[name] to always be an array; alternatively it could be either a string or array of strings, with appropriate magic behavior for either. -Original Message- From: es-discuss-boun...@mozilla.org [mailto:es-discuss- boun...@mozilla.org] On Behalf Of Tab Atkins Jr. Sent: Monday, November 19, 2012 18:16 To: es-discuss Subject: Subclassing basic types in DOM - best method? For several things in the DOM and related APIs, we want objects that are more-or-less the same as some basic ES stuff, like Arrays or Maps, and which are appropriate to treat as those objects in a generic manner. For example, the URLQuery interface in the URL Standard http://url.spec.whatwg.org/#interface-urlquery, which represents the query portion (key/value pairs) of a URL, is basically a Map. (It's missing a few pieces right now, like has() and the iterator-producing functions, but Anne plans to add them.) Ideally, an author could take a library with generic Map-manipulating functions, pass a URLQuery object in, and have a reasonable chance of having that just succeed. Hopefully, this should be robust to common type-checking operations, like doing a structural test, or an instanceof test. Naively, this is doable just by subclassing Map (in the standard proto way), and overriding the methods, to delegate to the Map methods and then do additional things. AWB posted some code to WHATWG detailing how you would do this in ES5 and ES6; it's predictably simple. However, URLQuery has some invariants it needs to maintain: it's a String-String map, not Any-Any. As such, it probably doesn't want to actually initialize itself as a Map and forward to the Map methods; instead, it should probably maintain a hidden internal Map and control the access to that itself, so it can ensure that no non-Strings leak into the map. If we did this, the only reason to continue subclassing Map is to get instanceof checks to work. Is this acceptable? Are there better ways, perhaps on the horizon? Any other thoughts? (Further examples: NodeList being an Array, URLFragments being an Array, a few DOM-CSS bridges being Maps...) ~TJ ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Default value argument for Map/WeakMap.prototype.get()
Using https://github.com/substack/defined you can do var d = require(defined); var x = d(m.get(key), defaultValue); Not sure if this is an argument for adding default value because this module is so ridiculous ... or against it since it’s so trivial to get the functionality yourself. From: Andrea Giammarchi Sent: November 28, 2012 14:27 To: Jason Orendorff CC: es-discuss Subject: Re: Default value argument for Map/WeakMap.prototype.get() it was there and it has been removed ... curious to see if it will be back. Said that, same way you do obj.prop = obj.prop || def; you can do obj.set(prop, obj.get(prop) || {}); I know it's not the equivalent since you might want to be able to set null, false, , NaN, etc etc ... but it's easy to add utilities to current logic while it might be ambiguous to change defaultValue behavior later on. As example, I might want to consider an inherited property as valid value while what you are suggesting, in a more generic approach, is not considering inheritance because the property is not own br On Wed, Nov 28, 2012 at 11:07 AM, Jason Orendorff jason.orendo...@gmail.commailto:jason.orendo...@gmail.com wrote: I propose adding an optional second argument to the .get() method on Map and WeakMap. Map.prototype.get(key[, defaultValue]) The default value would be returned only when the given key is not in the map. That is, in the last step of the spec for these two methods, instead of Return undefined, it would say Return defaultValue. Python and Ruby have this. (In Ruby it's called fetch.) It's handy in cases like: var counts = new Map; for (let word of words) counts.set(word, counts.get(word, 0) + 1); -j ___ es-discuss mailing list es-discuss@mozilla.orgmailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Proposal: Reflecting on non-string property names
-Original Message- From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Allen Wirfs-Brock Sent: Friday, November 30, 2012 19:18 1) Object.getOwnPropertyNames and Object.keys remain unchanged. They only return a string property key values. 2) Reflect.ownKeys(obj) is a new reflection function that returns an iterator. The iterator produces the keys of all public own properties of the object pass as an argument. This includes both string and Symbol key values. A minor qualm compared to all the other things being discussed here, but isn't it confusing to have keys mean two different things? In ES5 usage it means enumerable, string-valued whereas in this proposed Reflect.ownKeys it means no qualifiers: non-enumerable OK, symbol-valued OK. From an ES5 perspective, property names (as in getOwnPropertyNames) are enumerable or non-enumerable string-valued whereas keys are enumerable string-valued. Ideally there would be a new designation for non-string–valued. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: (Map|Set|WeakMap)#set() returns `this` ?
+1 (to all sentiments in the message :) From: Nathan Wallmailto:nathan.w...@live.com Sent: 12/3/2012 17:53 To: Andrea Giammarchimailto:andrea.giammar...@gmail.com; Rick Waldronmailto:waldron.r...@gmail.com Cc: es-discuss@mozilla.orgmailto:es-discuss@mozilla.org Subject: RE: (Map|Set|WeakMap)#set() returns `this` ? I'm not a person of influence, but as a JS developer, I agree with Andrea on this. I think Map#set() should return the value. I would expect the same behavior as obj[key] = value. I find Andrea's use case (m.get(k) || m.set(k, v)) more compelling than the method chaining possibilities. Nathan Date: Mon, 3 Dec 2012 14:21:24 -0800 Subject: Re: (Map|Set|WeakMap)#set() returns `this` ? From: andrea.giammar...@gmail.com To: waldron.r...@gmail.com CC: es-discuss@mozilla.org IMHO, a set(key, value) should return the value as it is when you address a value var o = m.get(k) || m.set(k, v); // o === v // equivalent of var o = m[k] || (m[k] = v); // o === v a set with a key that returns `this` is a non case so almost as useless as the void return is. Usefulness comes with use cases ... except this jQuery chainability thingy that works fine for jQuery structure ( an ArrayLike Collection ) who asked for map.set(k0, v0).set(k1, v1).set(k2, v2) ? Or even map.set(k0,v0).get(k1) ? what are use cases for this? I am honestly curious about them because I cannot think a single one ... specially with the Set s.add(k0).add(k1).add(k2) ... this code looks weird inlined like this ... Thanks for your patience On Mon, Dec 3, 2012 at 2:04 PM, Rick Waldron waldron.r...@gmail.commailto:waldron.r...@gmail.com wrote: On Mon, Dec 3, 2012 at 4:28 PM, Andrea Giammarchi andrea.giammar...@gmail.commailto:andrea.giammar...@gmail.com wrote: I wonder what was the use case that convinced TC39 to return `this` with these methods. Assuming you read the notes, I proposed the agenda item based on the best practice of ensuring meaningful returns, and in the case of mutation methods, |this| is a meaningful return. Accordingly, this will never work: var query = map.has('queried') ? map.get('queried') : map.set('queried', $('myquery')); Previously, map.set() had a useless void return... And it will be something like: var query = map.has('queried') ? map.get('queried') : map.set('queried', $('myquery')).get('queried'); which is ugly and I don't really understand where map.set(k0, v0).set(k1, v1).set(k2, v2) could be useful. Accessing the object post-mutation allows for more expressive use of the API. Rick Thanks for clarifications ( a use case would be already good ) br ___ es-discuss mailing list es-discuss@mozilla.orgmailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: On dropping @names
On the subject of ugly code, I believe the killing of @names and the reintroduction of computed properties means that the typical iterator form will be something like: let iterable = { *[iterator]() { yield 5; } }; Presented without comment... From: Brandon Benviemailto:bran...@brandonbenvie.com Sent: 12/3/2012 18:00 To: es-discuss discussionmailto:es-discuss@mozilla.org Subject: On dropping @names From the meeting notes it appears that support for @names is out, which I believe is quite unfortunate. I'd like to either propose a way to resolve the issues that caused them to be dropped, or come to an understanding of what the reason is that they can't be resurrected. First, I wanted to touch on the hypothetical do I have to look up in scope to know what prop means in { prop: val }. Without @names Symbols are eternally computed despite actually being specific values that are statically resolvable. From the debugging standpoint, there's not actually a way to usefully represent properties with symbol keys. Furthermore, there's no way definitively look at source code and be able to determine when a property has a string key or a symbol. The only way you can is if you can trace back to the original `import Symbol from '@symbol'` used to create the value associated with a given variable. This is the same problem, but even worse because without the '@' it can't even be determined if something is a string or a symbol, not just what symbol it is. Unless I'm not interpreting the correct meaning from the notes, the assertion was made that @names aren't static. My reading of the proposal indicates that you can only declare an @name once in a given scope and that you can only assign to it in the declaration. The only hazard that this creates is that it's possible to end up with one Symbol that's assigned to more than one @name in a given scope. In all other cases they behave as expected. Having @name declarations shadow outer ones is the same behavior as any other declaration and that's expected behavior. To address the problem with one symbol initializing multiple @names, @name initialization should be limited to the bare minimum. The main (only?) reason @name declarations needed an initializer is to facilitate importing them. If @name initialization was limited to import declarations then a duplicate check during module loading results in the desired static runtime semantics. Using the MultiMap functional spec from Tab Atkins earlier today, I created a side by side comparison with and without @names. https://gist.github.com/4198745. Not having syntactic support for Symbols is a tough pill to swallow. Using Symbols as computed values with no special identifying characteristics results is significantly reduced code readability. Really ugly code, in fact. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: (Map|Set|WeakMap)#set() returns `this` ?
Readability or library preference aside, I still think it's bizarre that map.set(key, val) is analogous to (dict[key] = val, dict) and not to dict[key] = val When I'm using a fluent library like jQuery or a configuration DSL like those in the npm packages surveyed, I can see the attraction of chaining. But when I am using a basic primitive of the language, I expect uniformity across primitives. From: es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org] on behalf of Tab Atkins Jr. [jackalm...@gmail.com] Sent: Wednesday, December 05, 2012 14:57 To: Mark S. Miller Cc: es-discuss@mozilla.org Subject: Re: (Map|Set|WeakMap)#set() returns `this` ? On Wed, Dec 5, 2012 at 10:04 AM, Mark S. Miller erig...@google.com wrote: On Wed, Dec 5, 2012 at 1:50 AM, Jussi Kalliokoski jussi.kallioko...@gmail.com wrote: My 2 cents against the windmills... I personally think returning `this` in absence of any meaningful value (and chaining in general) is a bad pattern. Chaining leads to worse readability (there's nothing subjective about this, if you have to scan the code to another page to figure out which object the code is interacting with, it's bad readability) This is an excellent point, and has changed my mind. I return to not supporting the return this for these cases. Thanks. The readability of chaining *is* very subjective. I find it perfectly readable. Andrea and a few others feel strongly about this, and I respect that. But most JS libraries have gone the other way, and authors in general seem to like that direction. This constitutes pretty clear evidence about which pattern JS devs en masse prefer, and we shouldn't pretend like we know better than them. In the absence of technical problems that doom a solution, let's vote with the herd. ~TJ ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Module Comments
For the record, here's the idea Yehuda and I worked out: https://gist.github.com/1ab3f0daa7b37859ce43 I would *really* appreciate if people read it (it's easy reading, I promise!) and incorporated some of our concerns and ideas into their thinking on module syntax. In general, it tries to eliminate the ExportSpecifierSet and ImportSpecifierSet microsyntaxes in favor of standard object literal/destructuring forms, respectively. It also made export and import syntax symmetric. It apparently failed to get much traction among committee members, mainly because of objections to our reformation of the export-side syntax. (Second-hand info.) E.g. the current export function foo() { } was preferred to the proposed export { foo() { } }, and---less aesthetically---our special behavior for ObjectLiteral expressions over other expressions was a bit weird. I still think the import-side reformation is important and stand by everything in the proposal in that regard. As mentioned in other messages in this thread, the current form is confusingly dual-natured. And I maintain that the incomplete semi-destructuring microsyntax of ImportSpecifierSet adds a lot of cognitive burden. If we can start by fixing the import side, I have some other ideas on how to make the export side better that hopefully will be more appealing to the committee. But I don't want to try proposing those yet until we can get the buy-in on fixing import. From: es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org] on behalf of Erik Arvidsson [erik.arvids...@gmail.com] Sent: Thursday, December 06, 2012 09:54 To: Kevin Smith Cc: es-discuss Subject: Re: Module Comments On Thu, Dec 6, 2012 at 9:42 AM, Kevin Smith khs4...@gmail.commailto:khs4...@gmail.com wrote: Dave responded by pointing out that we don't want from to have overloaded semantics. I actually think this form has potential, because it further aligns import with the other binding forms: var a = x; var { b } = y; // Symmetry! import a from x; import { b } from y; +1 This also matches what Yehuda and Domenic proposed a few weeks ago. -- erik ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Module Comments
-Original Message- From: Andreas Rossberg [mailto:rossb...@google.com] Sent: Thursday, December 6, 2012 11:31 On 6 December 2012 16:44, Domenic Denicola dome...@domenicdenicola.com wrote: For the record, here's the idea Yehuda and I worked out: https://gist.github.com/1ab3f0daa7b37859ce43 I would *really* appreciate if people read it (it's easy reading, I promise!) and incorporated some of our concerns and ideas into their thinking on module syntax. However, the more radical parts of your proposal (allowing arbitrary export expressions, and arbitrary import patterns) do not work. The problem is that imports are not normal variable assignments. They do not copy values, like normal destructuring, they are aliasing bindings! If you were to allow arbitrary expressions and patterns, then this would imply aliasing of arbitrary object properties. Not only is this a completely new feature, it also is rather questionable -- the aliased location might disappear, because objects are mutable. Thanks for the feedback Andreas; this is really helpful. It took me a while to figure out what you meant by this, but I think I understand now. However, I think that since the bindings are const bindings, the difference between copying and aliasing is unobservable—is that right? Thus the mental model could be copying in all cases, both top-level and deeper. I think the symmetry I am looking for is that import { x: [a, b], f } from foo; should work the same as import foo from foo; const { x: [a, b], f } = foo; And I realize the linked gist does not introduce const bindings, but instead let bindings; that's easy enough to fix if it's the right path forward. You could also consider imports always meaning copying, but then you exporting a variable will no longer be useful. This is the part that made me question whether I understand what you're saying. What do you mean by exporting a variable and useful? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Number.isNaN
From: es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org] on behalf of Nathan Wall [nathan.w...@live.com] Sent: Friday, December 14, 2012 13:34 On another note, I do sort of wonder why `Number.isNaN` is coming into the language now at the same time as the `is` operator and `Object.is`. It seems teaching people (and getting them to remember long-term) the nuances of `isNaN` and `Number.isNaN` will be more difficult than just teaching people to use `x is NaN` in ES6 or `Object.is(x, NaN)` in an ES3/5 + ES6 shims environment. `is` operator is dead :( :( :( (Someone want to find a link to the minutes that killed it? I keep having to correct people on this.) There's not an `isNull` or `isUndefined`. The only reason `isNaN` was needed was because `===` didn't work with `NaN`, but `is` does. This is pretty reasonable, actually. The only argument I can see is that `array.filter(Number.isNaN)` is shorter than `array.filter(x = Object.is(x, NaN))`. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Reflection of global bindings
From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] On Behalf Of Brendan Eich Sent: Saturday, December 15, 2012 14:26 Reflecting var and function bindings on window (or |this| or |self| or other aliases) as configurable properties, but refusing to allow reconfiguration, is a solution, however distasteful. Allowing configuration is no good, of course. As someone who's trying desperately to follow along with all these subtle issues from the sidelines... Why is allowing configuration of such properties no good? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: URLs / subclassing JavaScript
From: es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org] on behalf of Anne van Kesteren [ann...@annevk.nl] Sent: Monday, December 17, 2012 09:56 By types I mean e.g. constraining set() to just accept strings. I think the JavaScript-y way of doing this, as exemplified in the ES5 spec's built-in functions, is to do a ToString() abstract operation on the input. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Do Anonymous Exports Solve the Backwards Compatibility Problem?
-Original Message- From: es-discuss-boun...@mozilla.org [mailto:es-discuss- boun...@mozilla.org] On Behalf Of Brendan Eich Sent: Wednesday, December 19, 2012 23:11 In a thread you may not have caught up on, Andreas did argue for a special form such as module foo at foo; for anonymous import, so that the system can check that foo indeed does export = ... and throw otherwise. Sorry if you did see this and reply (in which case I missed the reply!). If not, whaddya think? IMO this is undesirable. In such a situation, modules can no longer be abstraction boundaries. Instead you must peek inside each module and see which form it exported itself using. If we instead had import foo from foo; where `foo` became either the module instance object (in the multi-export case) or the singly-exported value (single-export case), abstraction boundaries are preserved much more neatly. This goes both ways, of course. I.e., ideally, this should work too: ```js module glob { function glob() { } glob.sync = function () { }; } import { sync } from glob; ``` (see https://npmjs.org/package/glob) This was much of the motivation behind Yehuda and I's proposal, FWIW. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Do Anonymous Exports Solve the Backwards Compatibility Problem?
On Dec 20, 2012, at 19:02, David Herman dher...@mozilla.com wrote: On Dec 20, 2012, at 1:29 PM, Brendan Eich bren...@mozilla.com wrote: So the particular approach -- in particular -- that you are questioning is adding export = to ES6 modules. I agree it is ad-hoc. It also seems likely to confuse, compared to the self-hosted NPM precedent. It's one of those almost-but-not-quite-the-same things where the differences seem likely (to me at any rate) to bite back. I think the complaint about the syntactic similarity and semantic difference between `export = { ... }` and `export { ... }` is a very strong point, even though I don't believe it's Andreas's primary objection. ;-) I'd be a fan of coloring the bikeshed `export only { … }` ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: On dropping @names
From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] On Behalf Of David Herman Sent: Wednesday, December 26, 2012 19:50 I imagine your reply is: don't do that transformation; place your `let` declarations as late as possible before they are going to be used. I guess I need to be convinced that the equivalence is of no value. I would agree with this putative reply, and state that the equivalence is indeed of no value. What follows is my subjective feelings on why that is; I hope they are helpful, but I certainly don't claim this perspective is objectively better. My perspective is as someone coming from other languages. Hoisting is, in my experience, a uniquely JavaScript weirdness. (Admittedly I don't have experience with too many other languages.) It often makes the top 3 list of JavaScript gotchas, hardest language features to understand, interview questions, etc. Having semantics where UBI is prohibited would bring back some sanity to the proceedings, and in an always use let world, eliminates hoisting almost entirely. (The remaining case is function declarations, which are much less confusing since there is no assignment involved.) The fact that var declarations are manually hoisted to the top of the function by some is a direct consequence of the equivalence you mention; it's programmers trying to do what the computer would do anyway. I would guess that what most programmers *want* is the ability to declare variables as close as possible to their actual use. They manually hoist, instead, because the language does not support the semantics they desire; in other words, declaration-close-to-use is deceptive in that your code looks like it's doing something, but the computer will hoist, making the code do something slightly different. If we gave them semantics that supported declare-close-to-use, viz. TDZ-UBI semantics, everything would be happy and there would be rejoicing in the streets. If we just hoisted to the top of the block, then the ability to declare close to use while maintaining parallel semantics to those the computer will do anyway is lost (in many cases). That said, `let` has a lot going for it even without TDZ-UBI. E.g. the ability to use blocks to prevent scope pollution, or the sane per-loop bindings. So I'm a fairly-happy clam as-is. Just wanted to put in a word in favor of TDZ-UBI. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss