Re: Look-behind proposal
Thank you Brendan for picking this up! Nozomu, Brendan, please let me know if I can be of any help. Sebastian On 8 June 2015 at 18:47, Brendan Eich bren...@mozilla.org wrote: I will do it if no one else steps up by 10pm tonight PDT. Thank you to Nozomu Katō for writing it up! /be Sebastian Zartner wrote: So the question is, how to recruit a TC39 member? Through this list? Is it possible to become a member as a private person? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Ideas on type hinting and named parameters
I like that syntax. I wonder about the runtime semantics of it, though. (I know TypeHint is a TODO, but…) Is there any implication at runtime of a function that returns a String? Is this: ```js var point = { x Number, y Number }; ``` … the same as this? ```js var point = { x: Number(), y: Number() }; ``` In which case we would need rules for constructors to always have default parameters, right? If those annotations are all only for a non-runtime type check, I feel strange now about having type analysis only for newly defined symbols. Since this is meant as some kind of pre-runtime `assert(symbol instanceof Type)`, we might want to check: - field types (such as `foo {bar Number}`) - parameter types (such as `Array[Number]` or `Map[String, Array[String]]`) - function types (such as `function(String) Number`) - union types (such as `RegExp | null`) - generics, possibly with extends / superclass (such as `function(items Array[T extends Entity], unmap function(Number) T)`)? Could we typedef types? Could we define covariance and contravariance rules in new types with generics? On a side-note, we can actually track the full list of methods used for each parameter, and check that each function call respects them. Maybe type inference has been researched enough that we can now use better tools that need no type hints. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ES6 Proxy Function Call Trap
Alright first I'll say I'm using FF to test because FF supports proxies, and I really don't know how to use Reflect and how it works yet. FF as well does not support Reflect right now. Therefore I'll look into that. So from [this source]( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply#Interceptions) it seems that it would only work if the actual proxy is invoked as a function? Take a look at the example in that link as well. Now I'm not sure if Reflect changes that somehow. **BTW** When I ran the code, I didn't get an `Error` saying that `Reflect` is not defined I got: `TypeError: people.logFullName is not a function` So I don't think that worked. On Tue, Jun 9, 2015 at 3:39 AM, Claude Pache claude.pa...@gmail.com wrote: Le 9 juin 2015 à 07:58, Edwin Reynoso eor...@gmail.com a écrit : **Or does someone know how to do what I'm trying to accomplish** Maybe the following code goes in the direction of what you want? ```js var people = new Proxy([new Person('Edwin', 'Reynoso'), new Person('That', 'Guy')], { get(target, property) { if (target[property] !== undefined) return target[property]; var arr = []; for (var person of target) arr.push(person[property]); return new Proxy(arr, { apply(target, thisArg, args) { return target.map(item = Reflect.apply(item, thisArg, args)) } }) } }); ``` About your proposal, I recall that, at some point in the history of ES6 draft, there was an `[[Invoke]]` MOP, and a corresponding `invoke` trap for proxies, that were finally eliminated. —Claude ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Ideas on type hinting and named parameters
quick personal thoughts on this matter, leaving the named arguments part beside (as it is looks kinda redundant/unnecessary effort that could wait) We've been talking about types for long time in here and the good old direction was *binary data* in the form of `StructType` ```js const Point2D = new StructType({x:uint32, y:uint32}); let xy = new Point2D({ x: 0, y: 0 }); ``` Not only this option looks and feel more consistent with typed options we have already in core such `Int32Array` and others, but it will be way easier to gracefully migrate to such new pattern and fully, or partially, polyfill for older engines. Back to typed Array, I think this: ```js var xyz = new Int32Array([1, 2, 3]); ``` is better than: ```js var xyz = [ int32 = 1, int32 = 2, int32 = 3 ]; ``` or whatever repeated operation we could have per each `xyz` like variable of that kind, so whatever would eventually work as StructType might be in my opinion more suitable. 1. you recognize upfront what kind of duck you are working with 2. you define such type once instead of each time, reducing errors/typos 3. when you pass data around you can specify as example just `Point2D` instead of `ArrayT Int32` and friends that are imo not so nice to have in a scripting language 4. we have already tools capable of bringing in types in similar fashion you proposed ... how about we do something better than some syntax tools friendly, instead of some syntax optimized for developers? Moreover about classes, you have defined properties that AFAIK are not allowed by current specs. ES6 classes accepts only methods and/or getters and setters so I'm not sure properties should be discussed together with types, maybe worth waiting for better understanding on how properties will be? That being said, I see why you used space instead of colon, and for literal objects that indeed looks like a better approach. Best Regards On Tue, Jun 9, 2015 at 5:19 AM, Luke Scott l...@webconnex.com wrote: Hello All, I wanted to share some ideas with you for type hinting: https://github.com/lukescott/es-type-hinting I’m also putting this together for named parameters: https://github.com/lukescott/es-named-arguments The two are somewhat related. The type hinting doc uses white-space instead of a colon. And in the named-arguments doc a colon is used for named arguments. I realize that there may be some strong opinions on a colon vs white-space. Using white-space instead is an attempt to be compatible with existing ES syntax (POJO uses colon already), while allowing for other new features, such as named parameters. Looking for feedback and any interest on any of the above. Luke ___ 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
PerformPromiseAll
https://people.mozilla.org/~jorendorff/es6-draft.html#sec-performpromiseall https://people.mozilla.org/~jorendorff/es6-draft.html#sec-performpromiseall I’m wondering: Is it OK that PerformPromiseAll invokes `resolve()` via `C.resolve()` (versus `this.resolve()`) with `C` determined via the species pattern? Rationale: `resolve()` uses the species pattern, too (which is why `this.resolve()` works well). Therefore, the species pattern is used twice, which may lead to unexpected effects: You define the species of `this` to be X, but the species of X is Y. Then `Promise.all()` creates an array with instances of Y, not X. -- Dr. Axel Rauschmayer a...@rauschma.de rauschma.de ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ES6 Proxy Function Call Trap
Le 9 juin 2015 à 07:58, Edwin Reynoso eor...@gmail.com a écrit : **Or does someone know how to do what I'm trying to accomplish** Maybe the following code goes in the direction of what you want? ```js var people = new Proxy([new Person('Edwin', 'Reynoso'), new Person('That', 'Guy')], { get(target, property) { if (target[property] !== undefined) return target[property]; var arr = []; for (var person of target) arr.push(person[property]); return new Proxy(arr, { apply(target, thisArg, args) { return target.map(item = Reflect.apply(item, thisArg, args)) } }) } }); ``` About your proposal, I recall that, at some point in the history of ES6 draft, there was an `[[Invoke]]` MOP, and a corresponding `invoke` trap for proxies, that were finally eliminated. —Claude___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Ideas on type hinting and named parameters
On Jun 9, 2015, at 1:57 AM, Andrea Giammarchi andrea.giammar...@gmail.commailto:andrea.giammar...@gmail.com wrote: quick personal thoughts on this matter, leaving the named arguments part beside (as it is looks kinda redundant/unnecessary effort that could wait) We've been talking about types for long time in here and the good old direction was *binary data* in the form of `StructType` ```js const Point2D = new StructType({x:uint32, y:uint32}); let xy = new Point2D({ x: 0, y: 0 }); ``` Not only this option looks and feel more consistent with typed options we have already in core such `Int32Array` and others, but it will be way easier to gracefully migrate to such new pattern and fully, or partially, polyfill for older engines. Back to typed Array, I think this: ```js var xyz = new Int32Array([1, 2, 3]); ``` is better than: ```js var xyz = [ int32 = 1, int32 = 2, int32 = 3 ]; ``` or whatever repeated operation we could have per each `xyz` like variable of that kind, so whatever would eventually work as StructType might be in my opinion more suitable. 1. you recognize upfront what kind of duck you are working with 2. you define such type once instead of each time, reducing errors/typos 3. when you pass data around you can specify as example just `Point2D` instead of `ArrayT Int32` and friends that are imo not so nice to have in a scripting language 4. we have already tools capable of bringing in types in similar fashion you proposed ... how about we do something better than some syntax tools friendly, instead of some syntax optimized for developers? You are talking about new primitive types, right? I’m focusing mostly on class types and inheritance (instanceof checking). String, Number, and Boolean are special cases though. `uint32` is not a reserved word as far as I know. Do we care that they aren’t? If not, I suppose `string` could be part of that list of primitive type symbols, right? In which case `name string` could be used instead of `name String`. Is StructType passed by value or by reference? If by reference, wouldn’t that be a bit misleading? Structs are usually supposed to be cheaper than objects because of how / where they are allocated. For structs I was thinking about something along the lines of: ```js struct Point2D { x Number y Number }; let xy = Point2D(x: 5, y: 10); ``` …which goes nicely with named arguments :). Moreover about classes, you have defined properties that AFAIK are not allowed by current specs. ES6 classes accepts only methods and/or getters and setters so I'm not sure properties should be discussed together with types, maybe worth waiting for better understanding on how properties will be? Class properties are listed in stage 0 here: https://github.com/tc39/ecma262/blob/master/stage0.md https://gist.github.com/jeffmo/054df782c05639da2adb It currently uses `=` to define properties. And there is some debate whether or not properties should be initialized in the constructor or be on the prototype. In the type-hinting repo I show both `=` and `:`, although I would prefer `:` to keep consistent with plain objects. Thinking about how other proposals could overlap and trying to avoid any unnecessary conflict can be important. That being said, I see why you used space instead of colon, and for literal objects that indeed looks like a better approach. Thank you your kind words. I’ll have to admit I was expecting more backlash. The day is still young though :) Luke ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Ideas on type hinting and named parameters
On Tue, Jun 9, 2015 at 8:30 AM, Luke Scott l...@webconnex.com wrote: [...] It currently uses `=` to define properties. And there is some debate whether or not properties should be initialized in the constructor or be on the prototype. There is no debate about whether per-instance state (of whatever form) can be initialized in the constructor. Often, this needs to be initialized to some value dependent on the values of the constructor parameters. Given that we have no choice about supporting initialization in constructors, the debate is *only* about whether we should also bother to support initialization in the class body outside the constructor. IMO, no. Why add a redundant and less expressive mechanism? As for properties on the prototype, these are rarely enough motivated that doing it imperatively after class initialization seems fine. I don't recall anyone strongly advocating that we need syntactic support for properties on the prototype, though perhaps I missed it. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Ideas on type hinting and named parameters
On Jun 9, 2015, at 1:21 AM, Thaddee Tyl thaddee@gmail.com wrote: I like that syntax. I wonder about the runtime semantics of it, though. (I know TypeHint is a TODO, but…) Is there any implication at runtime of a function that returns a String? Is this: ```js var point = { x Number, y Number }; ``` … the same as this? ```js var point = { x: Number(), y: Number() }; ``` In which case we would need rules for constructors to always have default parameters, right? This brings up a good point. I’ll open an issue for it. Likely built-in types such as String, Number, and Boolean would have special meaning, assuming they are not shadowed. Their default values would be “”, 0, and false. Other types would be undefined by default. Alternatively it could always be undefined, but that can be problematic, especially with Number. If those annotations are all only for a non-runtime type check, I feel strange now about having type analysis only for newly defined symbols. Since this is meant as some kind of pre-runtime `assert(symbol instanceof Type)`, we might want to check: - field types (such as `foo {bar Number}`) - parameter types (such as `Array[Number]` or `Map[String, Array[String]]`) - function types (such as `function(String) Number`) - union types (such as `RegExp | null`) - generics, possibly with extends / superclass (such as `function(items Array[T extends Entity], unmap function(Number) T)`)? Types should probably be checked at runtime. However, having the flexibility to catch errors with a linter before running the code would be extremely valuable. So I’m not sure I would actually take it as far as Array[Number] because you can only enforce that at runtime given that an Array can contain anything. Adding typed arrays in the language may be more beneficial. For example if you had NumberArray you could enforce the types in the array before they are added: ```js push(...values Number) {...} ``` Luke ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: PerformPromiseAll
On Tue, Jun 9, 2015 at 11:11 AM, Mark S. Miller erig...@google.com wrote: Ok, thanks for the example. I understand your rationale. This is what I asked for but not what I was really looking for. Can we come up with an example where class and species usefully differ where neither is Promise? IOW, where the species a proper subclass of Promise and a proper superclass of the class in question. http://www.mimuw.edu.pl/~sl/teaching/00_01/Delfin_EC/Glossary.htm#S says: species: The generic class of an object. This is normally the same as the class of an object, otherwise it is a class which describes the generic group of classes to which a particular class belongs. Note that this does not necessarily have to be class from the same branch of the hierarchy. But I was not able to find this any examples where the species was not from the same branch of the hierachy in my smalltalk research. The only examples I could dig up had the species equal to the top-level superclass for the generic group, like Array, Promise, etc. But I'm not a smalltalk expert, by any means. I hope that some of the smalltalkers among us (or those who work with former smalltalkers?) might be able to come up with more examples. That said, I think the WeakPromise and TimeoutPromise examples are reasonably compelling. Further, note that if you are using the `prfun` library, the Promise you are using is actually a subclass of `globals.Promise`. This is so that `prfun` can add all of its fun `Promise.try` etc methods without polluting the global `Promise`. So in that case: `PrFunPromise extends Promise`, `TimeoutPromise extends PrFunPromise`, and `TimeoutPromise[Symbol.species] = PrFunPromise`. But that's probably not really what you were looking for, either. On Tue, Jun 9, 2015 at 11:04 AM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: I generally agree. You invoke one of these methods on a specific Promise constructor, presumably with the intend that it is an instance to that constructor you expect to get back. For example, compare the likely intent of: WeakPromise.all(iterator) and Promise.all(iterator) It seems just like what we discussed for Promise.resolve I generally agree, and would not object to travelling down this path. *However*, note that the implementations given for `Promise.all` and `Promise.race` use Promises in two different ways: (1) every element of the array argument has `C1.resolve(elem).then()` applied to it, and (2) the result is constructed with `NewPromiseCapability(C2)`. It's not entirely clear to me that C1 and C2 should be the same. Consider the `TimeoutPromise`: do we want to apply a timeout to every element individually *and* to the result as a whole? It seems that C1 might use species (to avoid the timeout/weak reference), but C2 ignore it (to apply the timeout/weak reference to the final result) The idea that `WeakPromise.all(x)` means `WeakPromise.resolve(x).all()` is a little bit surprising (because the constructed `WeakPromise` is not visible externally and thus the result honors species and is not itself a `WeakPromise`), but does have a consistency of its own. So I'm torn. But if we decided that `WeakPromise.all()` should return a `WeakPromise` then I'd suggest that we change step 6 from: Let promiseCapability be NewPromiseCapability(C). to Let promiseCapability be NewPromiseCapability(this). in both `Promise.all` and `Promise.race`, but leave the definition of C otherwise alone, so that internally-created promises honor the species. --scott ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ES6 Proxy Function Call Trap
On Tue, Jun 9, 2015 at 3:44 AM, Edwin Reynoso eor...@gmail.com wrote: Alright first I'll say I'm using FF to test because FF supports proxies, and I really don't know how to use Reflect and how it works yet. FF as well does not support Reflect right now. Therefore I'll look into that. That's right. Reflect is a key tool when you're writing proxy handlers. I'm working on implementing it in Firefox now. If you like, you can subscribe to this bug and get updates (quiet so far): https://bugzilla.mozilla.org/show_bug.cgi?id=987514 Here, I think the technique you're looking for might be that the proxy handler's get() method should return a new proxy (representing an array of methods). This new method proxy needs something callable as its target. When the method proxy's .call() trap is called, it'll receive the arguments. -j ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: PerformPromiseAll
It would help to have a concrete motivating example where the Promise subclass were usefully distinct from the Promise subclass' species. On Tue, Jun 9, 2015 at 7:30 AM, C. Scott Ananian ecmascr...@cscott.net wrote: `Promise.resolve` doesn't use the species pattern any more: https://esdiscuss.org/topic/fixing-promise-resolve The rationale was that `resolve` is more like a constructor than a mutator. I don't have a strong opinion about `Promise.all`, but I think perhaps it would be better if none of the static methods of `Promise` (Promise.all, Promise.race, Promise.reject) used the species pattern, which is more appropriate for instance methods (like `Promise.prototype.then`, where it is a natural fit). However, consider another way of looking at it. Let's make the fundamental implementation `Promise.prototype.all` (defined by some utility libraries, including bluebird and prfun, and would be a good candidate for ES7) which operates on a promise resolving to an array. It seems natural for that to use a species pattern, since it's an instance transformation method, like `then` and `catch`. The natural implementation of `Promise.all` would then be: ``` Promise.all = function(a) { return this.resolve(a).all(); }; ``` This doesn't use the species pattern for the initial `resolve`, but then does use it to implement the instance method `all`. So the result of `Promise.all` effectively uses the species pattern. So: on one hand, static methods don't use @species. On the other, `Promise.prototype.all` would naturally use the species pattern, and that suggests a natural implementation of `Promise.all` would as well. On the gripping hand, given a non-species-using `Promise.all`, it is easy to define `Promise.prototype.all` (just do the initial `resolve` using the species), but the converse isn't true. So perhaps a non-species-using `Promise.all` would be a more useful building block. I'd appreciate further opinions here. My bias is against trying to make late changes to the ES6 spec, so perhaps I'm rationalizing away the potential problems with `Promise.all` and `Promise.race`. --scott On Tue, Jun 9, 2015 at 6:46 AM, Axel Rauschmayer a...@rauschma.de wrote: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-performpromiseall I’m wondering: Is it OK that PerformPromiseAll invokes `resolve()` via `C.resolve()` (versus `this.resolve()`) with `C` determined via the species pattern? Rationale: `resolve()` uses the species pattern, too (which is why `this.resolve()` works well). Therefore, the species pattern is used twice, which may lead to unexpected effects: You define the species of `this` to be X, but the species of X is Y. Then `Promise.all()` creates an array with instances of Y, not X. -- Dr. Axel Rauschmayer a...@rauschma.de rauschma.de ___ 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 -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Look-behind proposal
Allen Wirfs-Brock wrote on Tue, 9 Jun 2015, at 07:27:36 -0700: Nozomu, Also, please register as an Ecma TC39 non-member contributor by following the steps described at https://github.com/tc39/ecma262#contributing-new-proposals I just did. Thank you for telling me that. Nozomu ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: PerformPromiseAll
`Promise.resolve` doesn't use the species pattern any more: https://esdiscuss.org/topic/fixing-promise-resolve The rationale was that `resolve` is more like a constructor than a mutator. I don't have a strong opinion about `Promise.all`, but I think perhaps it would be better if none of the static methods of `Promise` (Promise.all, Promise.race, Promise.reject) used the species pattern, which is more appropriate for instance methods (like `Promise.prototype.then`, where it is a natural fit). However, consider another way of looking at it. Let's make the fundamental implementation `Promise.prototype.all` (defined by some utility libraries, including bluebird and prfun, and would be a good candidate for ES7) which operates on a promise resolving to an array. It seems natural for that to use a species pattern, since it's an instance transformation method, like `then` and `catch`. The natural implementation of `Promise.all` would then be: ``` Promise.all = function(a) { return this.resolve(a).all(); }; ``` This doesn't use the species pattern for the initial `resolve`, but then does use it to implement the instance method `all`. So the result of `Promise.all` effectively uses the species pattern. So: on one hand, static methods don't use @species. On the other, `Promise.prototype.all` would naturally use the species pattern, and that suggests a natural implementation of `Promise.all` would as well. On the gripping hand, given a non-species-using `Promise.all`, it is easy to define `Promise.prototype.all` (just do the initial `resolve` using the species), but the converse isn't true. So perhaps a non-species-using `Promise.all` would be a more useful building block. I'd appreciate further opinions here. My bias is against trying to make late changes to the ES6 spec, so perhaps I'm rationalizing away the potential problems with `Promise.all` and `Promise.race`. --scott On Tue, Jun 9, 2015 at 6:46 AM, Axel Rauschmayer a...@rauschma.de wrote: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-performpromiseall I’m wondering: Is it OK that PerformPromiseAll invokes `resolve()` via `C.resolve()` (versus `this.resolve()`) with `C` determined via the species pattern? Rationale: `resolve()` uses the species pattern, too (which is why `this.resolve()` works well). Therefore, the species pattern is used twice, which may lead to unexpected effects: You define the species of `this` to be X, but the species of X is Y. Then `Promise.all()` creates an array with instances of Y, not X. -- Dr. Axel Rauschmayer a...@rauschma.de rauschma.de ___ 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: PerformPromiseAll
Mark: I outlined two of these use cases in https://esdiscuss.org/topic/subclassing-es6-objects-with-es5-syntax#content-50 One is `WeakPromise` which is a promise holding a weak reference to its resolved value. This is the closest analogy with the canonical Smalltalk motivating example for species. Another is `TimeoutPromise` which is a promise that rejects in a fixed time if not resolved before then. Both of these would set `WeakPromise[Symbol.species] = TimeoutPromise[Symbol.species] = Promise;` so that the weak reference/timeout is not contagious across `then()`. `WeakPromise.all([...])` reads like it should return a `WeakPromise` (ie, ignore species). This is consistent with the static methods ignore species rule. *However*, `WeakPromise.resolve([]).all()` makes it clearer that weak reference held by `WeakPromise` is actually just to the initial array, and that the result of `WeakPromise.prototype.all` should in fact be a `Promise` (ie, honor species). Similarly for `TimeoutPromise`: `TimeoutPromise.resolve([...]).all()` implies a timeout to resolve the initial array-of-promises, but the result of the `all()` is a normal Promise and won't timeout. But on the other hand, you wouldn't be wrong if you thought that `TimeoutPromise.all([...])` should timeout the result of the all. So, to me it seems like if you think that `Promise.all(x)` is shorthand for a future `this.resolve(x).all()`, then honoring the species is not a terrible thing. In ES7-ish, when you allow `Promise.all` and `Promise.race` to accept Promises as their arguments (in addition to iterables), then you could clarify the spec to indicate that the species is ignored when resolving the Promise argument, then honored when processing the `all` or `race`. But if you want a crisp semantics and weren't afraid of more last-minute changes to the Promise spec, then you'd define `Promise.all` and `Promise.race` to ignore species, and handle the species issue in ES7 when you define `Promise.prototype.all` and `Promise.prototype.race`. IMO, at least. --scott ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Look-behind proposal
On Jun 9, 2015, at 6:18 AM, Nozomu Katō wrote: On 8 June 2015 at 18:47, Brendan Eich wrote: I will do it if no one else steps up by 10pm tonight PDT. I thank you very much indeed for taking this proposal on. I am very relieved! Nozomu, Also, please register as an Ecma TC39 non-member contributor by following the steps described at https://github.com/tc39/ecma262#contributing-new-proposals Thanks, Allen Sebastian Zartner wrote on Tue, 9 Jun 2015, at 10:20:00 +0200: Nozomu, Brendan, please let me know if I can be of any help. Thank you for your kindness. Any action that could make the proposal move forward is a great help to me. This is the first time for me to see how a proposal becomes part of the ECMAScript standard. If/whenever I do not a required action please urge me to do it. Regards, Nozomu ___ 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: PerformPromiseAll
On Jun 9, 2015, at 7:30 AM, C. Scott Ananian wrote: `Promise.resolve` doesn't use the species pattern any more: https://esdiscuss.org/topic/fixing-promise-resolve The rationale was that `resolve` is more like a constructor than a mutator. I don't have a strong opinion about `Promise.all`, but I think perhaps it would be better if none of the static methods of `Promise` (Promise.all, Promise.race, Promise.reject) used the species pattern, which is more appropriate for instance methods (like `Promise.prototype.then`, where it is a natural fit). I generally agree. You invoke one of these methods on a specific Promise constructor, presumably with the intend that it is an instance to that constructor you expect to get back. For example, compare the likely intent of: WeakPromise.all(iterator) and Promise.all(iterator) It seems just like what we discussed for Promise.resolve Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: PerformPromiseAll
On Tue, Jun 9, 2015 at 7:58 AM, C. Scott Ananian ecmascr...@cscott.net wrote: Mark: I outlined two of these use cases in https://esdiscuss.org/topic/subclassing-es6-objects-with-es5-syntax#content-50 One is `WeakPromise` which is a promise holding a weak reference to its resolved value. This is the closest analogy with the canonical Smalltalk motivating example for species. Another is `TimeoutPromise` which is a promise that rejects in a fixed time if not resolved before then. Both of these would set `WeakPromise[Symbol.species] = TimeoutPromise[Symbol.species] = Promise;` so that the weak reference/timeout is not contagious across `then()`. Ok, thanks for the example. I understand your rationale. This is what I asked for but not what I was really looking for. Can we come up with an example where class and species usefully differ where neither is Promise? IOW, where the species a proper subclass of Promise and a proper superclass of the class in question. Btw, Allen's conclusion sounds right to me. But I'd like to see such an example, or see us fail to find one, before considering the what-it-should-be-in-the-absence-of-timing issue settled. Thanks. Given the timing, unless the case is very strong, which you clearly doubt as well, I'm sure we won't actually revisit this for ES6, and thus never. `WeakPromise.all([...])` reads like it should return a `WeakPromise` (ie, ignore species). This is consistent with the static methods ignore species rule. *However*, `WeakPromise.resolve([]).all()` makes it clearer that weak reference held by `WeakPromise` is actually just to the initial array, and that the result of `WeakPromise.prototype.all` should in fact be a `Promise` (ie, honor species). Similarly for `TimeoutPromise`: `TimeoutPromise.resolve([...]).all()` implies a timeout to resolve the initial array-of-promises, but the result of the `all()` is a normal Promise and won't timeout. But on the other hand, you wouldn't be wrong if you thought that `TimeoutPromise.all([...])` should timeout the result of the all. So, to me it seems like if you think that `Promise.all(x)` is shorthand for a future `this.resolve(x).all()`, then honoring the species is not a terrible thing. In ES7-ish, when you allow `Promise.all` and `Promise.race` to accept Promises as their arguments (in addition to iterables), then you could clarify the spec to indicate that the species is ignored when resolving the Promise argument, then honored when processing the `all` or `race`. But if you want a crisp semantics and weren't afraid of more last-minute changes to the Promise spec, then you'd define `Promise.all` and `Promise.race` to ignore species, and handle the species issue in ES7 when you define `Promise.prototype.all` and `Promise.prototype.race`. IMO, at least. --scott -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Ideas on type hinting and named parameters
Syntax for putting properties on the prototype was long-ago rejected because of footgun potential. Correction: *data* properties. : ) ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Ideas on type hinting and named parameters
TypeScript was just an example, but being class a different Syntax beast than just prototype (right?) why would that be bad? It will be indeed not-unexpected as Kevin mentioned later on. Using classes thinking prototypes feel something developers won't do (specially new comers) so TypeScript behavior looks OKish to me, but in ES7 doesn't have to be like that, it can be actually part of the prototype if you prefer, and do a copy of non primitives ( or leave the Kevin's mentioned footgun in, I don't mind, it never hurt me personally :-) ) Regards On Tue, Jun 9, 2015 at 5:18 PM, Mark S. Miller erig...@google.com wrote: On Tue, Jun 9, 2015 at 9:13 AM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: Mark, properties on the prototype are in TypeScript, and probably every other OOP based language. Defaults can be easily defined as such, i.e. ```js class Person { name = 'anonymous'; age = 0; } ``` At http://www.typescriptlang.org/Playground, putting this code into the left pane causes the right pane to show var Person = (function () { function Person() { this.name = 'anonymous'; this.age = 0; } return Person; })(); which clearly indicates that these are *not* properties on the prototype. They are per-instance, but merely written with a confusing syntax that misled you into believing that they were properties on the prototype. Not only, defaults could be optimized upfront by parsers without needing to infer or do extra analysis on the constructor. Defaults also as static property/state is quite common. ```js class Admin { PRIVILEGES = 'all'; } ``` Anyway, I'm curious to know why do you think getters and setters are OK and properties are not. I don't see any technical difference, specially considering get/set for lazy property computation/assignment through the prototype getter anyway. JS4lf ... you hit an already opened door about strict descriptors, already proposed years ago ;-) https://github.com/WebReflection/define-strict-properties#define-strict-properties Best Regards On Tue, Jun 9, 2015 at 4:44 PM, Mark S. Miller erig...@google.com wrote: On Tue, Jun 9, 2015 at 8:30 AM, Luke Scott l...@webconnex.com wrote: [...] It currently uses `=` to define properties. And there is some debate whether or not properties should be initialized in the constructor or be on the prototype. There is no debate about whether per-instance state (of whatever form) can be initialized in the constructor. Often, this needs to be initialized to some value dependent on the values of the constructor parameters. Given that we have no choice about supporting initialization in constructors, the debate is *only* about whether we should also bother to support initialization in the class body outside the constructor. IMO, no. Why add a redundant and less expressive mechanism? As for properties on the prototype, these are rarely enough motivated that doing it imperatively after class initialization seems fine. I don't recall anyone strongly advocating that we need syntactic support for properties on the prototype, though perhaps I missed it. -- Cheers, --MarkM -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: When the only tool you have is subclassing, all extensions look like....
On Tue, Jun 9, 2015 at 9:35 AM, C. Scott Ananian ecmascr...@cscott.net wrote: Promise subclassing is super useful. `prfun` uses it extensively: first to override the global `Promise` to avoid polluting the global namespace, and then secondly to implement features like `Promise#bind`. I've also used it experimentally to implement functional promises (with a `Promise#chain` method) on top of ES6 Promises. I actually had a paragraph like this in my earlier response (on the other thread) and deleted it, since it seemed off-topic there. But suffice it to say I've already used the subclass extension mechanism for Promises in a number of ways which are impossible with the more-limited and ad hoc makeRemote mechanism. And you say that you can implement pipelining on top of subclassing. So subclassing seems more general to me... What's the specific use case which you can't make work with a Promise subclass? Funny enough, I replied before I saw this. The use case I can't make work using only subclassing as an extension mechanism is promise pipelining. --scott On Tue, Jun 9, 2015 at 12:13 PM, Mark S. Miller erig...@google.com wrote: My larger theme here is that I think promise subclassing is way overrated. OO programmers tend to treat subclassing according to the everything is a hammer rule. Promises do need an extension point, such as the old makeFar and makeRemote proposals explained at http://wiki.ecmascript.org/doku.php?id=strawman:concurrency#fundamental_static_q_methods and implemented at https://github.com/tvcutsem/es-lab/blob/master/src/ses/makeQ.js#L476, in order to enable promise pipelining. However, since we have (mal)invested so much effort into providing subclassing as the promise extension mechanism, when rebuilding promise pipelining on ES6 promises, we will use the subclassing extension point instead, even though it is less modular. At least pipelining is a case which does require propagation, so the ES6 subclassing mechanisms should work for these. (With some caveats to be explained in later email.) On Tue, Jun 9, 2015 at 9:00 AM, Mark S. Miller erig...@google.com wrote: I know I'm being picky here, but if timeout-ness is not intended to propagate, which seems sensible, then why would I ever want to invent a TimeoutPromise subclass rather than using a combinator like delay or race on a plain Promise? -- Cheers, --MarkM -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: PerformPromiseAll
I know I'm being picky here, but if timeout-ness is not intended to propagate, which seems sensible, then why would I ever want to invent a TimeoutPromise subclass rather than using a combinator like delay or race on a plain Promise? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Ideas on type hinting and named parameters
Why can't we use proxy or a new global object call StrictType, or a new property call definePropertiesType on the global Object Than we could use the syntax style of the language : Object.definePropertiesType(object,{ age:{type:Number}, name:{type:String}, height:{type:Float} }); All of these additional feature will make the language hard to learn. Adding on these new syntax in hope to please other comming from other programming language. No matter what it'll never be 100% familiar to others that's come from different languages. It becoming bulky in my opinion Pretty soon will be in the same boat as w3c. ...it's almost like who every can make the most specific, understandable, detail proposal will get the feature included in the language. JS4Lf On Jun 9, 2015, at 4:57 AM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: quick personal thoughts on this matter, leaving the named arguments part beside (as it is looks kinda redundant/unnecessary effort that could wait) We've been talking about types for long time in here and the good old direction was *binary data* in the form of `StructType` ```js const Point2D = new StructType({x:uint32, y:uint32}); let xy = new Point2D({ x: 0, y: 0 }); ``` Not only this option looks and feel more consistent with typed options we have already in core such `Int32Array` and others, but it will be way easier to gracefully migrate to such new pattern and fully, or partially, polyfill for older engines. Back to typed Array, I think this: ```js var xyz = new Int32Array([1, 2, 3]); ``` is better than: ```js var xyz = [ int32 = 1, int32 = 2, int32 = 3 ]; ``` or whatever repeated operation we could have per each `xyz` like variable of that kind, so whatever would eventually work as StructType might be in my opinion more suitable. 1. you recognize upfront what kind of duck you are working with 2. you define such type once instead of each time, reducing errors/typos 3. when you pass data around you can specify as example just `Point2D` instead of `ArrayT Int32` and friends that are imo not so nice to have in a scripting language 4. we have already tools capable of bringing in types in similar fashion you proposed ... how about we do something better than some syntax tools friendly, instead of some syntax optimized for developers? Moreover about classes, you have defined properties that AFAIK are not allowed by current specs. ES6 classes accepts only methods and/or getters and setters so I'm not sure properties should be discussed together with types, maybe worth waiting for better understanding on how properties will be? That being said, I see why you used space instead of colon, and for literal objects that indeed looks like a better approach. Best Regards On Tue, Jun 9, 2015 at 5:19 AM, Luke Scott l...@webconnex.com wrote: Hello All, I wanted to share some ideas with you for type hinting: https://github.com/lukescott/es-type-hinting I’m also putting this together for named parameters: https://github.com/lukescott/es-named-arguments The two are somewhat related. The type hinting doc uses white-space instead of a colon. And in the named-arguments doc a colon is used for named arguments. I realize that there may be some strong opinions on a colon vs white-space. Using white-space instead is an attempt to be compatible with existing ES syntax (POJO uses colon already), while allowing for other new features, such as named parameters. Looking for feedback and any interest on any of the above. Luke ___ 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: PerformPromiseAll
On Tue, Jun 9, 2015 at 12:38 PM, Mark S. Miller erig...@google.com wrote: Do you ever test that the object returned by `Promise#timeout(n)` is something other than a plain promise? Responded on the other thread. Let's keep this one focused on: do we need to tweak the definitions of `Promise.all` and `Promise.race` as they relate to species, and if so: how? Option 1: don't consult species at all; Option 2: use species for intermediate results, but don't use species for final result; Option 3: you tell me! Since I'm personally rationalizing away the current behavior as grody but acceptable, I'm particularly interested in hearing me, toos (via private email to me or Allen) if you think we should make a change. --scott ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: When the only tool you have is subclassing, all extensions look like....
On Tue, Jun 9, 2015 at 9:13 AM, Mark S. Miller erig...@google.com wrote: My larger theme here is that I think promise subclassing is way overrated. OO programmers tend to treat subclassing according to the everything is a hammer rule. Promises do need an extension point, such as the old makeFar and makeRemote proposals explained at http://wiki.ecmascript.org/doku.php?id=strawman:concurrency#fundamental_static_q_methods and implemented at https://github.com/tvcutsem/es-lab/blob/master/src/ses/makeQ.js#L476, in order to enable promise pipelining. However, since we have (mal)invested so much effort into providing subclassing as the promise extension mechanism, when rebuilding promise pipelining on ES6 promises, we will use the subclassing extension point instead, even though it is less modular. At least pipelining is a case which does require propagation, so the ES6 subclassing mechanisms should work for these. (With some caveats to be explained in later email.) OMG, I had this *exactly* backwards! In const r = p.then(() = q); remoteness must not an cannot propagate from p to r, since the callback is necessarily local. Remoteness propagates from p to r *only* for .get, .put, .post, .delete, and .there -- none of which yet exist in the std. Worse, the std does not provide for interaction between q and r that would enable promise pipelining when q is remote. What is needed is that, when q is an unsettled remote promise, resolving r to q leaves r unsettled but gives all message pending in r, both present and future, to q so q can forward them to the remote machine. Sigh. Even though ES6 promises stayed fairly close to E promises (where makeFar and makeRemote originated), getting from ES6 promises to remote promises with promise pipelining is going to be more work than I thought. On Tue, Jun 9, 2015 at 9:00 AM, Mark S. Miller erig...@google.com wrote: I know I'm being picky here, but if timeout-ness is not intended to propagate, which seems sensible, then why would I ever want to invent a TimeoutPromise subclass rather than using a combinator like delay or race on a plain Promise? -- Cheers, --MarkM -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Ideas on type hinting and named parameters
Mark, properties on the prototype are in TypeScript, and probably every other OOP based language. Defaults can be easily defined as such, i.e. ```js class Person { name = 'anonymous'; age = 0; } ``` Not only, defaults could be optimized upfront by parsers without needing to infer or do extra analysis on the constructor. Defaults also as static property/state is quite common. ```js class Admin { PRIVILEGES = 'all'; } ``` Anyway, I'm curious to know why do you think getters and setters are OK and properties are not. I don't see any technical difference, specially considering get/set for lazy property computation/assignment through the prototype getter anyway. JS4lf ... you hit an already opened door about strict descriptors, already proposed years ago ;-) https://github.com/WebReflection/define-strict-properties#define-strict-properties Best Regards On Tue, Jun 9, 2015 at 4:44 PM, Mark S. Miller erig...@google.com wrote: On Tue, Jun 9, 2015 at 8:30 AM, Luke Scott l...@webconnex.com wrote: [...] It currently uses `=` to define properties. And there is some debate whether or not properties should be initialized in the constructor or be on the prototype. There is no debate about whether per-instance state (of whatever form) can be initialized in the constructor. Often, this needs to be initialized to some value dependent on the values of the constructor parameters. Given that we have no choice about supporting initialization in constructors, the debate is *only* about whether we should also bother to support initialization in the class body outside the constructor. IMO, no. Why add a redundant and less expressive mechanism? As for properties on the prototype, these are rarely enough motivated that doing it imperatively after class initialization seems fine. I don't recall anyone strongly advocating that we need syntactic support for properties on the prototype, though perhaps I missed it. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
When the only tool you have is subclassing, all extensions look like....
My larger theme here is that I think promise subclassing is way overrated. OO programmers tend to treat subclassing according to the everything is a hammer rule. Promises do need an extension point, such as the old makeFar and makeRemote proposals explained at http://wiki.ecmascript.org/doku.php?id=strawman:concurrency#fundamental_static_q_methods and implemented at https://github.com/tvcutsem/es-lab/blob/master/src/ses/makeQ.js#L476, in order to enable promise pipelining. However, since we have (mal)invested so much effort into providing subclassing as the promise extension mechanism, when rebuilding promise pipelining on ES6 promises, we will use the subclassing extension point instead, even though it is less modular. At least pipelining is a case which does require propagation, so the ES6 subclassing mechanisms should work for these. (With some caveats to be explained in later email.) On Tue, Jun 9, 2015 at 9:00 AM, Mark S. Miller erig...@google.com wrote: I know I'm being picky here, but if timeout-ness is not intended to propagate, which seems sensible, then why would I ever want to invent a TimeoutPromise subclass rather than using a combinator like delay or race on a plain Promise? -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: PerformPromiseAll
Mark: The `prfun` library in fact uses `Promise#timeout(n)` instead of a `TimeoutPromise` subclass. But this is really a language-design question. You might as well ask why we have `WeakMap()` as a constructor instead of using `Map#weak()` or `weakmapify(map)`. The fundamental reason is so you can name (and thus test) the type of the object. But this is really a question for the smalltalk folks. All I know is from googling smalltalk species, for example: http://computer-programming-forum.com/3-smalltalk/fbb2ef6357ba0905.htm --scott ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Ideas on type hinting and named parameters
On Tue, Jun 9, 2015 at 9:13 AM, Andrea Giammarchi andrea.giammar...@gmail.com wrote: Mark, properties on the prototype are in TypeScript, and probably every other OOP based language. Defaults can be easily defined as such, i.e. ```js class Person { name = 'anonymous'; age = 0; } ``` At http://www.typescriptlang.org/Playground, putting this code into the left pane causes the right pane to show var Person = (function () { function Person() { this.name = 'anonymous'; this.age = 0; } return Person; })(); which clearly indicates that these are *not* properties on the prototype. They are per-instance, but merely written with a confusing syntax that misled you into believing that they were properties on the prototype. Not only, defaults could be optimized upfront by parsers without needing to infer or do extra analysis on the constructor. Defaults also as static property/state is quite common. ```js class Admin { PRIVILEGES = 'all'; } ``` Anyway, I'm curious to know why do you think getters and setters are OK and properties are not. I don't see any technical difference, specially considering get/set for lazy property computation/assignment through the prototype getter anyway. JS4lf ... you hit an already opened door about strict descriptors, already proposed years ago ;-) https://github.com/WebReflection/define-strict-properties#define-strict-properties Best Regards On Tue, Jun 9, 2015 at 4:44 PM, Mark S. Miller erig...@google.com wrote: On Tue, Jun 9, 2015 at 8:30 AM, Luke Scott l...@webconnex.com wrote: [...] It currently uses `=` to define properties. And there is some debate whether or not properties should be initialized in the constructor or be on the prototype. There is no debate about whether per-instance state (of whatever form) can be initialized in the constructor. Often, this needs to be initialized to some value dependent on the values of the constructor parameters. Given that we have no choice about supporting initialization in constructors, the debate is *only* about whether we should also bother to support initialization in the class body outside the constructor. IMO, no. Why add a redundant and less expressive mechanism? As for properties on the prototype, these are rarely enough motivated that doing it imperatively after class initialization seems fine. I don't recall anyone strongly advocating that we need syntactic support for properties on the prototype, though perhaps I missed it. -- Cheers, --MarkM -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Ideas on type hinting and named parameters
Anyway, I'm curious to know why do you think getters and setters are OK and properties are not. I don't see any technical difference, specially considering get/set for lazy property computation/assignment through the prototype getter anyway. Syntax for putting properties on the prototype was long-ago rejected because of footgun potential. Users will naturally tend to think of them as per-instance, instead of shared, which leads to bugs. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: When the only tool you have is subclassing, all extensions look like....
Promise subclassing is super useful. `prfun` uses it extensively: first to override the global `Promise` to avoid polluting the global namespace, and then secondly to implement features like `Promise#bind`. I've also used it experimentally to implement functional promises (with a `Promise#chain` method) on top of ES6 Promises. I actually had a paragraph like this in my earlier response (on the other thread) and deleted it, since it seemed off-topic there. But suffice it to say I've already used the subclass extension mechanism for Promises in a number of ways which are impossible with the more-limited and ad hoc makeRemote mechanism. And you say that you can implement pipelining on top of subclassing. So subclassing seems more general to me... What's the specific use case which you can't make work with a Promise subclass? --scott On Tue, Jun 9, 2015 at 12:13 PM, Mark S. Miller erig...@google.com wrote: My larger theme here is that I think promise subclassing is way overrated. OO programmers tend to treat subclassing according to the everything is a hammer rule. Promises do need an extension point, such as the old makeFar and makeRemote proposals explained at http://wiki.ecmascript.org/doku.php?id=strawman:concurrency#fundamental_static_q_methods and implemented at https://github.com/tvcutsem/es-lab/blob/master/src/ses/makeQ.js#L476, in order to enable promise pipelining. However, since we have (mal)invested so much effort into providing subclassing as the promise extension mechanism, when rebuilding promise pipelining on ES6 promises, we will use the subclassing extension point instead, even though it is less modular. At least pipelining is a case which does require propagation, so the ES6 subclassing mechanisms should work for these. (With some caveats to be explained in later email.) On Tue, Jun 9, 2015 at 9:00 AM, Mark S. Miller erig...@google.com wrote: I know I'm being picky here, but if timeout-ness is not intended to propagate, which seems sensible, then why would I ever want to invent a TimeoutPromise subclass rather than using a combinator like delay or race on a plain Promise? -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: PerformPromiseAll
On Tue, Jun 9, 2015 at 9:29 AM, C. Scott Ananian ecmascr...@cscott.net wrote: Mark: The `prfun` library in fact uses `Promise#timeout(n)` instead of a `TimeoutPromise` subclass. But this is really a language-design question. You might as well ask why we have `WeakMap()` as a constructor instead of using `Map#weak()` or `weakmapify(map)`. The fundamental reason is so you can name (and thus test) the type of the object. Do you ever test that the object returned by `Promise#timeout(n)` is something other than a plain promise? But this is really a question for the smalltalk folks. All I know is from googling smalltalk species, for example: http://computer-programming-forum.com/3-smalltalk/fbb2ef6357ba0905.htm --scott -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: When the only tool you have is subclassing, all extensions look like....
On Tue, Jun 9, 2015 at 12:38 PM, Mark S. Miller erig...@google.com wrote: On Tue, Jun 9, 2015 at 9:29 AM, C. Scott Ananian ecmascr...@cscott.net wrote: Mark: The `prfun` library in fact uses `Promise#timeout(n)` instead of a `TimeoutPromise` subclass. But this is really a language-design question. You might as well ask why we have `WeakMap()` as a constructor instead of using `Map#weak()` or `weakmapify(map)`. The fundamental reason is so you can name (and thus test) the type of the object. Do you ever test that the object returned by `Promise#timeout(n)` is something other than a plain promise? As I said, I use `Promise#timeout` myself in my implementation, not a subclass. So I haven't written tests for TimeoutPromise myself. But the smalltalk community has a number of places where it is worth testing whether an argument is a WeakArray. Those examples would translate directly to tests for WeakPromise. And for TimeoutPromise you could imagine something like: ``` var protect = function(x) { return (x instanceof TimeoutPromise) ? x : TimeoutPromise.resolve(x); }; var doSomethingImportant = function(x) { // ensure that we're not going to hang forever waiting for x return protect(x).catch().then(); }; ``` It is rather convenient that the `protect` function already has a clever name: `TimeoutPromise.resolve`. --scott ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Ideas on type hinting and named parameters
Also static properties are on __proto__, so it seems a bit strange that instance properties would not also be on .prototype. Somewhat of a consistency issue I suppose. Methods declared as static in ES6 are defined on the constructor itself. Apparently, static data properties in TS are defined on the constructor as well. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Ideas on type hinting and named parameters
On Jun 9, 2015, at 9:23 AM, Kevin Smith zenpars...@gmail.commailto:zenpars...@gmail.com wrote: Anyway, I'm curious to know why do you think getters and setters are OK and properties are not. I don't see any technical difference, specially considering get/set for lazy property computation/assignment through the prototype getter anyway. Syntax for putting properties on the prototype was long-ago rejected because of footgun potential. Users will naturally tend to think of them as per-instance, instead of shared, which leads to bugs. Another way of eliminating the footgun potential is not allowing non-primitive defaults on properties. Any non-primitive properties would always default to undefined, forcing you to later initialize it yourself in the constructor. Defining the property without a default would just be a way to defining what the type is supposed to be. As far as I can tell this is what other languages do - non-primitive types are not allowed as property defaults. That makes sense to me. ```js class Person { name String: “John” items Array constructor() { this.items = [“food]; } } ``` Also static properties are on __proto__, so it seems a bit strange that instance properties would not also be on .prototype. Somewhat of a consistency issue I suppose. (My fault for dragging this a bit off topic. TMI in my description of class properties…) Luke ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: When the only tool you have is subclassing, all extensions look like....
What about the interaction between q and r in .then, that I mentioned in my previous email? That's the reason I changed my mind and now think we need an extension mechanism besides subclassing in order to make pipelining work. Note: it needs to work even if p is a plain promise. It is only q that knows that the scenario is special. On Tue, Jun 9, 2015 at 10:38 AM, C. Scott Ananian ecmascr...@cscott.net wrote: I think that Promise pipelining works just fine -- you just have to implement it inside Promise#get, Promise#put, etc. ``` // This is already in prfun Promise.get = function(fieldname) { return this.then(function(o) { return o[fieldname]; }); }; // This comes with your RPC mechanism RemoteObjectPromise.get = function(fieldname) { // note that this.handle is a name for the remote object, it is not a resolved value. // as such, this method doesn't have to wait until the remote object corresponding to // this.handle is resolved return new RemoteObjectPromise('GET', this.handle, fieldname); }; class RemoteObjectPromise extends Promise { this(args...) { let res, rej; super((a,b)={res=a;rej=b;}); this.handle = gensym(); // first argument is destination of the operation rpcCall(this.handle, ...args).then( v = res(v), e = rej(v) ); } } ``` --scott On Tue, Jun 9, 2015 at 12:56 PM, Mark S. Miller erig...@google.com wrote: On Tue, Jun 9, 2015 at 9:35 AM, C. Scott Ananian ecmascr...@cscott.net wrote: Promise subclassing is super useful. `prfun` uses it extensively: first to override the global `Promise` to avoid polluting the global namespace, and then secondly to implement features like `Promise#bind`. I've also used it experimentally to implement functional promises (with a `Promise#chain` method) on top of ES6 Promises. I actually had a paragraph like this in my earlier response (on the other thread) and deleted it, since it seemed off-topic there. But suffice it to say I've already used the subclass extension mechanism for Promises in a number of ways which are impossible with the more-limited and ad hoc makeRemote mechanism. And you say that you can implement pipelining on top of subclassing. So subclassing seems more general to me... What's the specific use case which you can't make work with a Promise subclass? Funny enough, I replied before I saw this. The use case I can't make work using only subclassing as an extension mechanism is promise pipelining. --scott On Tue, Jun 9, 2015 at 12:13 PM, Mark S. Miller erig...@google.com wrote: My larger theme here is that I think promise subclassing is way overrated. OO programmers tend to treat subclassing according to the everything is a hammer rule. Promises do need an extension point, such as the old makeFar and makeRemote proposals explained at http://wiki.ecmascript.org/doku.php?id=strawman:concurrency#fundamental_static_q_methods and implemented at https://github.com/tvcutsem/es-lab/blob/master/src/ses/makeQ.js#L476, in order to enable promise pipelining. However, since we have (mal)invested so much effort into providing subclassing as the promise extension mechanism, when rebuilding promise pipelining on ES6 promises, we will use the subclassing extension point instead, even though it is less modular. At least pipelining is a case which does require propagation, so the ES6 subclassing mechanisms should work for these. (With some caveats to be explained in later email.) On Tue, Jun 9, 2015 at 9:00 AM, Mark S. Miller erig...@google.com wrote: I know I'm being picky here, but if timeout-ness is not intended to propagate, which seems sensible, then why would I ever want to invent a TimeoutPromise subclass rather than using a combinator like delay or race on a plain Promise? -- Cheers, --MarkM -- Cheers, --MarkM -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: When the only tool you have is subclassing, all extensions look like....
I think that Promise pipelining works just fine -- you just have to implement it inside Promise#get, Promise#put, etc. ``` // This is already in prfun Promise.get = function(fieldname) { return this.then(function(o) { return o[fieldname]; }); }; // This comes with your RPC mechanism RemoteObjectPromise.get = function(fieldname) { // note that this.handle is a name for the remote object, it is not a resolved value. // as such, this method doesn't have to wait until the remote object corresponding to // this.handle is resolved return new RemoteObjectPromise('GET', this.handle, fieldname); }; class RemoteObjectPromise extends Promise { this(args...) { let res, rej; super((a,b)={res=a;rej=b;}); this.handle = gensym(); // first argument is destination of the operation rpcCall(this.handle, ...args).then( v = res(v), e = rej(v) ); } } ``` --scott On Tue, Jun 9, 2015 at 12:56 PM, Mark S. Miller erig...@google.com wrote: On Tue, Jun 9, 2015 at 9:35 AM, C. Scott Ananian ecmascr...@cscott.net wrote: Promise subclassing is super useful. `prfun` uses it extensively: first to override the global `Promise` to avoid polluting the global namespace, and then secondly to implement features like `Promise#bind`. I've also used it experimentally to implement functional promises (with a `Promise#chain` method) on top of ES6 Promises. I actually had a paragraph like this in my earlier response (on the other thread) and deleted it, since it seemed off-topic there. But suffice it to say I've already used the subclass extension mechanism for Promises in a number of ways which are impossible with the more-limited and ad hoc makeRemote mechanism. And you say that you can implement pipelining on top of subclassing. So subclassing seems more general to me... What's the specific use case which you can't make work with a Promise subclass? Funny enough, I replied before I saw this. The use case I can't make work using only subclassing as an extension mechanism is promise pipelining. --scott On Tue, Jun 9, 2015 at 12:13 PM, Mark S. Miller erig...@google.com wrote: My larger theme here is that I think promise subclassing is way overrated. OO programmers tend to treat subclassing according to the everything is a hammer rule. Promises do need an extension point, such as the old makeFar and makeRemote proposals explained at http://wiki.ecmascript.org/doku.php?id=strawman:concurrency#fundamental_static_q_methods and implemented at https://github.com/tvcutsem/es-lab/blob/master/src/ses/makeQ.js#L476, in order to enable promise pipelining. However, since we have (mal)invested so much effort into providing subclassing as the promise extension mechanism, when rebuilding promise pipelining on ES6 promises, we will use the subclassing extension point instead, even though it is less modular. At least pipelining is a case which does require propagation, so the ES6 subclassing mechanisms should work for these. (With some caveats to be explained in later email.) On Tue, Jun 9, 2015 at 9:00 AM, Mark S. Miller erig...@google.com wrote: I know I'm being picky here, but if timeout-ness is not intended to propagate, which seems sensible, then why would I ever want to invent a TimeoutPromise subclass rather than using a combinator like delay or race on a plain Promise? -- Cheers, --MarkM -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Ideas on type hinting and named parameters
how about introducing a well known concept in JS as `own` ? ```js class Person { static name String: A person name own name String: anonymous own items Array: [] constructor(name) { if (name) this.name = name; } } var anon = new Person, me = new Person('AG'); anon.items; // [] me.items;// [] me.items === anon.items; // false Person.name; // A person name anon.name; // anonymous me.name; // AG ``` thoughts? On Tue, Jun 9, 2015 at 7:38 PM, Kevin Smith zenpars...@gmail.com wrote: Also static properties are on __proto__, so it seems a bit strange that instance properties would not also be on .prototype. Somewhat of a consistency issue I suppose. Methods declared as static in ES6 are defined on the constructor itself. Apparently, static data properties in TS are defined on the constructor as well. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Ideas on type hinting and named parameters
how about introducing a well known concept in JS as `own` ? ```js class Person { static name String: A person name own name String: anonymous own items Array: [] Let's take a step back and ask: what's the motivation for having these property declarations and initializers outside of the constructor? As Mark pointed out, it's a syntactic feature that is strictly less expressive than the current solution of putting property assignments in the constructor body. Instance property initializer syntax is really geared toward type systems, where you are expressing type constraints (either structural or nominal) on objects created by the given constructor. I'm wary of adding syntax whose primary motivation is to express type constraints, when we haven't even defined (or proposed) what typing in JS means. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Ideas on type hinting and named parameters
Inline replies On Tue, Jun 9, 2015 at 9:01 PM, Kevin Smith zenpars...@gmail.com wrote: Let's take a step back and ask: what's the motivation for having these property declarations and initializers outside of the constructor? The same motivation of having `static` properties definition in it ... it was just possible to do the same directly through the class name without needing a new syntax, right? As Mark pointed out, it's a syntactic feature that is strictly less expressive than the current solution of putting property assignments in the constructor body. You define a class and basic/default properties per each instance. That's what people coming from other languages expect before even realizing classes methods are not own properties or classes getters and setters are not own descriptors. It's a common, well known, pattern in the class world out there, that's pretty much it. Since class in JS is sugar, why limiting such sugar? Instance property initializer syntax is really geared toward type systems, where you are expressing type constraints (either structural or nominal) on objects created by the given constructor. I'm wary of adding syntax whose primary motivation is to express type constraints, when we haven't even defined (or proposed) what typing in JS means. Agreed we are mixing up two different things that don't necessarily need each other to work. Regards ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: When the only tool you have is subclassing, all extensions look like....
I don't understand your answer. p and r are plain promises. They must be because they exist before q does. q is the first remote promise in this scenario. How does resolving r to q leave r unsettled but give q access to the messages buffered (and to be buffered) in r? I think the answer must involve the to-be-defined behavior of .get, .put, .post, .delete, and .where. These should be in bed with the implementation of the built-in promise resolve, so that when r is resolved to q, if q is a genuine promise (whatever that means in this new world), then r should migrate its messages there. However, to implement this on ES6 without monkey patching would require intervening in the internal resolving of r while still leaving r unsettled. If q intervenes by overriding .then, this does give it control during the resolution. But it doesn't give it access to r with which the buffered messages is associated. I don't get it. On Tue, Jun 9, 2015 at 11:20 AM, C. Scott Ananian ecmascr...@cscott.net wrote: On Tue, Jun 9, 2015 at 1:43 PM, Mark S. Miller erig...@google.com wrote: On Tue, Jun 9, 2015 at 10:38 AM, C. Scott Ananian ecmascr...@cscott.net wrote: I think that Promise pipelining works just fine -- you just have to implement it inside Promise#get, Promise#put, etc. ``` // This is already in prfun Promise.get = function(fieldname) { return this.then(function(o) { return o[fieldname]; }); }; // This comes with your RPC mechanism class RemoteObjectPromise extends Promise { this(args...) { let res, rej; if (typeof(args[0]) !== 'string') throw new TypeError(Not a remote reference!); super((a,b)={res=a;rej=b;}); this.handle = gensym(); // first argument to rpcCall is destination of the operation rpcCall(this.handle, ...args).then( v = res(v), e = rej(v) ); }, get(fieldname) { // note that this.handle is a name for the remote object, it is not a resolved value. // as such, this method doesn't have to wait until the remote object corresponding to // this.handle is resolved return new RemoteObjectPromise('GET', this.handle, fieldname); } } ``` What about the interaction between q and r in .then, that I mentioned in my previous email? That's the reason I changed my mind and now think we need an extension mechanism besides subclassing in order to make pipelining work. Note: it needs to work even if p is a plain promise. It is only q that knows that the scenario is special. Oh, right, I forgot: ``` RemoteObjectPromise[Symbol.species] = Promise; ``` That takes care of `then()`... And provides another nice use case for species. What would you expect `RemoteObjectPromise.all()` to do in this case? Probably `RemoteObjectPromise.prototype.all()` makes more sense -- if you have a remote reference to a (promised) array, you can pipeline the wait for all the elements in the array, without having to do all the waits on the client side. But in this case `RemoteObjectPromise.prototype.all()` is probably special-cased (and ignores species): ``` RemoteObjectPromise.prototype.all = function() { return new RemoteObjectPromise('ALL', this.handle); }; // And this is what I claim that `Promise.all` should also be: RemoteObjectPromise.all = function(x) { return this.resolve(x).all(); }; ``` Note that, given the definition above (I've tweaked it slightly), `RemoteObjectPromise.resolve(x)` throws TypeError if `x` is not already a remote object reference. You could tweak it to perform a migration or some such if you preferred. --scott ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Text by me above is hereby placed in the public domain Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: When the only tool you have is subclassing, all extensions look like....
On Tue, Jun 9, 2015 at 3:45 PM, Mark Miller erig...@gmail.com wrote: I don't understand your answer. p and r are plain promises. They must be because they exist before q does. q is the first remote promise in this scenario. How does resolving r to q leave r unsettled but give q access to the messages buffered (and to be buffered) in r? ``` const r = p.then(() = q); // q is a RemoteObjectPromise ``` I don't see any problem here. Perhaps you should work through the logic in `Promise#then` yourself to see that this works. Or play with the following in babel: ``` // babel doesn't implement this correctly: /* class RemotePromise extends Promise { static get [Symbol.species]() { return Promise; } } */ // -- so we need to do this: -- let RemotePromise = function(f) { let p = new Promise(f); Object.setPrototypeOf(p, RemotePromise.prototype); return p; }; Object.setPrototypeOf(RemotePromise, Promise); Object.defineProperty(RemotePromise, Symbol.species, { get: function() { return Promise; } }); RemotePromise.prototype = Object.create(Promise.prototype); RemotePromise.prototype.constructor = RemotePromise; // -- end crazy babel workaround -- let q = RemotePromise.resolve(42); // cheat, this would be the result of an RPC call let p = Promise.resolve({}); // local promise const r = p.then(() = q); // q is a RemoteObjectPromise r.then(function() { // show that this works properly! console.log(q instanceof RemotePromise, p instanceof RemotePromise, r instanceof RemotePromise); }); ``` I think where you are surprised is because (in this model) p.then() is implicitly requesting a *local* computation. Even though `() = q` in your sample code *looks* like a no-op, because q is a RemoteObjectPromise and p is not, you are explicitly requesting that the result of `q` be transferred to the local client so it can be operated on locally. If you want to continue doing remote computation, you need to use the remote computation methods (get/post/delete/call/etc) which keep the result on the remote server (and all of which yield a RemoteObjectPromise, not a Promise). This may differ from the E model (I don't know), but it makes good sense to me. You can't expect to do arbitrary computation inside a `then` unless the result has been transferred to the local client. --scott ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fixing `Promise.resolve()`
Is there any way to find out how this works *now*? I can’t find the May 2015 meeting notes, either. Do all static Promise methods now just use `this` (e.g. `Promise.all()` → `this.promiseResolve(···)`)? Or only `Promise.resolve()`? Thanks! Axel On 02 Jun 2015, at 23:28, Allen Wirfs-Brock al...@wirfs-brock.com wrote: On Jun 2, 2015, at 2:01 PM, Mark S. Miller wrote: Hi Scott, If the change is as simple as it appears, it seems it will go into ES6 itself! The fix has already been made to the production copy that will be released in a couple weeks when we have ECMA GA approval Allen Thanks for pushing this forward. On Tue, Jun 2, 2015 at 1:25 PM, C. Scott Ananian ecmascr...@cscott.net mailto:ecmascr...@cscott.net wrote: Thanks! It looks like core-js has already patched in the new spec: https://github.com/zloirock/core-js/issues/75 https://github.com/zloirock/core-js/issues/75 I've opened https://github.com/paulmillr/es6-shim/issues/344 https://github.com/paulmillr/es6-shim/issues/344 on es6-shim, and I'll see if I can get a patch together for it. I've filed https://bugzilla.mozilla.org/show_bug.cgi?id=1170742 https://bugzilla.mozilla.org/show_bug.cgi?id=1170742 against Mozilla. I've filed https://code.google.com/p/v8/issues/detail?id=4161 https://code.google.com/p/v8/issues/detail?id=4161 against v8. Allen: Will this be an errata to ES6, part of ES7, or something else? --scott -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Dr. Axel Rauschmayer a...@rauschma.de rauschma.de ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Look-behind proposal
This thread is a cool example of why this list is still do important. +1 to all of it! On Jun 9, 2015 4:20 AM, Sebastian Zartner sebastianzart...@gmail.com wrote: Thank you Brendan for picking this up! Nozomu, Brendan, please let me know if I can be of any help. Sebastian On 8 June 2015 at 18:47, Brendan Eich bren...@mozilla.org wrote: I will do it if no one else steps up by 10pm tonight PDT. Thank you to Nozomu Katō for writing it up! /be Sebastian Zartner wrote: So the question is, how to recruit a TC39 member? Through this list? Is it possible to become a member as a private person? ___ 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: Look-behind proposal
On 8 June 2015 at 18:47, Brendan Eich wrote: I will do it if no one else steps up by 10pm tonight PDT. I thank you very much indeed for taking this proposal on. I am very relieved! Sebastian Zartner wrote on Tue, 9 Jun 2015, at 10:20:00 +0200: Nozomu, Brendan, please let me know if I can be of any help. Thank you for your kindness. Any action that could make the proposal move forward is a great help to me. This is the first time for me to see how a proposal becomes part of the ECMAScript standard. If/whenever I do not a required action please urge me to do it. Regards, Nozomu ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss