Allow for async/await to use global.Promise and not builtin Promise
I've ported a few old fashioned callback code bases to async/await + Promises in the last year or so. When doing performance analysis and profiling I've noticed a significant negative impact of Promise / async / await in that it adds micro tasks to the queue. Previously there was a different link between the libuv syscall that my program made in node.js and the actual code being run in my application since callbacks are called synchronously and there is no micro task queue. With the async / await version of the codebase profiling is proving very challenging because the stack traces all start in the micro task queue. Would it be possible with some kind of flag or opt in mechanism to have async / await use `global.Promise` instead of the builtin native promise ? This would allow me to overwrite `global.Promise` with a non-compliant version that has no micro task queue and invokes all the callbacks synchronously. This would greatly aid with profiling and stack traces. Thank you, Jake. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Promise.cast and Promise.resolve
But, I would pick one or the other over one with multiple personalities This is a good mentality to have. Consider picking the one that allows the other one to be implemented in user land. This would allow both parties to benefit from the integrated tooling performance boosts of it being a native primitive. i.e. everybody wins. On Tue, Jan 28, 2014 at 8:12 PM, Kris Kowal kris.ko...@cixar.com wrote: In this case, a half pursuit of type purity is a side quest at the expense of users. Having two ways to resolve and two ways to observe a promise is unnecessarily confusing. In my experience, one method like then, that unwraps recursively, and one function, like Promise.cast, that automatically lifts if necessary, and then handlers that return into the waiting hands of Promise.cast are coherent and ergonomic. Having a choice between cast and resolve and a choice between then and chain, will leave developers unnecessarily confused and worried all the while they use or abandon Promises as too subtle. For quite some time, grammarians have been losing a war to impose Latin purity on English, in the case of split infinitives. Not long ago, the famous phrase, to boldly go, were a racy departure from convention because in Latin, the infinitive verb to go, is a single word, and you simply would not break the word in half to put a poetic adverb between the syllables. English is not Latin, and JavaScript is not Haskell. Auto-lifting/unwrapping promises are beautiful. Purely monadic promises are beautifully captured by type theory. But, I would pick one or the other over one with multiple personalities. I would pick Promise.cast and then, let complexity melt off the spec, and stop worrying. ___ 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: Cross-global instanceof
What are the use cases for things like 'isGenerator'. When and why would you need to know that an object upon which you are going to invoke the Iterator interface was/wasn't implemented by a generator. [`co`][1] is a library similar to Task.js that allows you to use ES6 generators as async / await. It allows you to yield multiple different types of future values and uses polymorphic dispatch to the correct await implementation based on type checks. Here there is a genuine use case for overloading yield to implement an async / await DSL that does the correct thing basd on the type of future value that you yield within the generator. In it's implementation it uses `isGenerator` and `isGeneratorFunction` ( https://github.com/visionmedia/co/blob/master/index.js#L153 ). I also personally use an `isGenerator` function ( https://github.com/Raynos/gens/blob/master/index.js#L43 ) so that I can implement the correct await semantics for the different types of future values you are allowed to yield in my library `gens` [1]: https://github.com/visionmedia/co/blob/master/index.js#L153 On Thu, Oct 31, 2013 at 11:01 AM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: On Oct 31, 2013, at 9:43 AM, Brandon Benvie wrote: On 10/31/2013 8:50 AM, David Bruant wrote: I'm not sure it's worth making it work for jQuery. This is trying to make a good use of same-origin multi-global which shouldn't exist in the first place. Keeping same-origin access as it is and encouraging people to add @sandbox even on same-origin iframes seems like a better idea. Should the addition be a nicer Object.prototype.toString.call? You're right, it's not instanceof. But I definitely think the argument can be made that there is a need for checking if something is of a certain class. I'm finding myself wanting things like `isGenerator` and `isGeneratorFunction`, for example. There's countless examples of people re-purposing Object.prototype.toString to serve this functionality ad hoc. What are the use cases for things like 'isGenerator'. When and why would you need to know that an object upon which you are going to invoke the Iterator interface was/wasn't implemented by a generator. If the reason is to know whether or not you can use the throw method (the only real difference between the generator object interface and the Iterator interface) you can test: 'throw' in possibleGenerator In general this sort of isFoo or obj.constructor === Foo class test is a bad smell in dynamic class based languages and tends to be a reflection of static nominal type thinking (which is fine in its own context, but JS is has a dynamic class model). Allen ___ 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: DOM EventStreams (take two on Streams): Request for feedback
Bacon's equivalent of EventStreamResolver.push() returns Bacon.noMore when it finds that the number of listeners has gone to 0. It should also be noted that streams2 in node return `false` from `push()` when the stream is full. Generally returning a value from `push()` as some kind of message to the source to either pause or abort is a good strategy. On Thu, Apr 18, 2013 at 4:26 PM, Jason Orendorff jason.orendo...@gmail.comwrote: (narrowing to the part that seems most productive) On Wed, Apr 17, 2013 at 9:11 PM, Tab Atkins Jr. wrote: On Wed, Apr 17, 2013 at 5:50 PM, Jason Orendorff wrote: Bacon offers two equivalent ways of unsubscribing. 1. Bacon's equivalent of the StreamInit callback returns an unsubscribe function. Each subscriber therefore gets its very own unsubscribe callback. Ah, that's an interesting idea. I'm unsure how each subscriber gets its own unsubscribe callback. The init callback is only called once, and so returns only the single value, right? Or is the subscribe callback called every time someone starts listening, so the stream can potentially act different to different listeners? That seems like it would be hard to make compatible with a multi-listener approach. Right. It's not quite per-listener; as in your design, the EventStream class copes with multiple simultaneous listeners. But when the number of listeners on an EventStream goes from 0 to 1, it calls the subscribe hook; when it goes from 1 to 0, it calls the unsubscribe hook. This is because Bacon turns off all the taps when no one's listening. Futures are not like that. Example: var clock = Bacon.interval(100, tick); clock.take(5).log(); setTimeout(() = clock.take(5).log(), 2000); The call to .log() on line 2 causes .take(5) to have a consumer, so clock's subscribe hook is called. We log some events; 500 msec later, .take(5) receives its fifth event, so it's all done. It unsubscribes itself and floats away. clock goes to 0 consumers, so it calls the unsubscribe hook. At 2000 msec, clock once again has a downstream consumer, so its subscribe hook is called a second time. 2. Additionally, Bacon's equivalent of the EventStreamResolver.push() method can return a special value (Bacon.noMore) that means unsubscribe me. That just kicks out all the listeners to the stream? Or does it end the stream? Or do you mean something else, given that you use the pronoun me, which implies it's the *listener* with somehow sends the signal? If the latter, you're confused about the role of a stream resolver. Bacon's equivalent of EventStreamResolver.push() returns Bacon.noMore when it finds that the number of listeners has gone to 0. This is indeed usually caused by the last listener unsubscribing by returning Bacon.noMore; and this is the point where I think it'll be quickest to cut short the discussion and just read some Bacon source code. This is called for every event: https://github.com/raimohanska/bacon.js/blob/6318160839d76ed4ce4eceeefe5d0d78b8e45403/src/Bacon.coffee#L777 -j ___ 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: First crack at a Streams proposal
Would it help to split the sugar and combinator from the actual stream interface? ``` callback StreamInit = void (StreamResolver resolver); callback AnyCallback = any (optional any value); [Constructor(StreamInit init)] interface Stream { Stream listen(optional AnyCallback? listenCB = null, optional AnyCallback? completeCB = null, optional AnyCallback? rejectCB = null); } interface StreamResolver { void push(optional any value); void complete(optional any value); void reject(optional any value); }; ``` One basic thing missing from this API is the ability to stop listening to a stream. Other things missing are the ability to abort / cancel / close a Stream, the ability to pause or resume a stream. It should also be made clear how and when a stream may emit values. Whether it is at any arbitrary time and it will send to whomever is listening at that moment. Whether it is only allowed to emit values after a listen call. Does every call to listen get the entire history independently of other calls? (Doing so would buffer all data and defeat the point of a stream). What happens when you push a value into the resolved and no-one is listening? Another decision that needs to be made is whether it makes sense for a stream to emit multiple errors? For a Future it doesn't make sense because it can only be fulfilled to a single value. For a stream it may make sense for multiple errors to occur. I personally like the `listen(onChunk, onEnd)` syntax as it matches a popular stream baseclass from the node community ( https://github.com/dominictarr/through#through ) in terms of simplicity. On Mon, Apr 15, 2013 at 1:31 PM, Tab Atkins Jr. jackalm...@gmail.comwrote: Inspired by DOM adding Futures http://dom.spec.whatwg.org/#futures, I've begun reworking several APIs in terms of them. While doing so, I've found several spots where Futures aren't appropriate, because I need something that can be updated multiple times, rather than just representing a single result like Futures do. I believe formalizing this notion will be as valuable as Futures, so I began by sketching out an API on my blog: http://www.xanthir.com/b4PV0. I'd like to begin discussion of this API with es-discuss, because this feature is much larger than just DOM, and you people have a lot of relevant experience. Here's a reproduction of the current state of my proposal (I'll update my blog as things progress if necessary): callback StreamInit = void (StreamResolver resolver); callback AnyCallback = any (optional any value); typedef (Stream or Future or Iterable) StreamLike; [Constructor(StreamInit init)] interface Stream { Stream listen(optional AnyCallback? listenCB = null, optional AnyCallback? completeCB = null, optional AnyCallback? rejectCB = null); Future complete(optional AnyCallback? completeCB = null); Future catch(optional AnyCallback? rejectCB = null); Future next(optional any filter = null) static from(StreamLike value, optional transformerCB, optional thisArg); static of(any... values); static reject(optional any reason); Stream filter(filterCB or primitive); Stream map(mapCB); void forEach(mapCB); Stream then(optional thenCB); Stream switch(optional switchCB); Stream throttle(milliseconds); } interface StreamResolver { void push(optional any value); void complete(optional any value); void continueWith(StreamLike continuation); void reject(optional any value); }; The overall API was designed to be similar to DOM Futures, where the constructor returns the stream and passes the resolver object to a callback argument. In several aspects it was also designed to be similar to the Array API, because streams can usefully be treated as a push-based ordered collection. The general form of a stream is zero or more updates, optionally followed by a single complete or reject event. Streams might not ever complete, and they may complete/reject without pushing any updates. The resolver has a simple API. 'push' is used to put values into the stream. complete/reject fullfill the stream with a completion or rejection signal; these both kill the resolver so that none of the methods have any effect (maybe they throw?). 'continueWith' also kills the resolver, but doesn't fulfill the stream, instead delegating the stream's future progress to the continuation stream, so the stream pushes updates when the continuation does, and fulfills when the continuation does. (I'm currently unsure whether completion should be just like an update, or not. That is, if I know that I'm about to push the very last value, should I do a push() then a complete(), or just a complete() with the value? This affects several APIs in the completion case.) The Stream's own API is also simple, and very similar to that of Future. The basic API is the 'listen' function, which takes any of three callbacks, which are called when updates are pushed, the
Re: First crack at a Streams proposal
I think all of these are only suited for single-consumer streams. My original proposal is explicitly for multi-consumer streams, as I designed it explicitly for DOM use-cases that I ran into. Most streams I've used have been single consumer streams. Whether I write FRP style programs with Signals or whether I write IO programs with streams the multi consumer use case comes up less. A far more regular case I have is a single sink consuming from multiple inputs in parallel due to some kind of merge(manyStreams) = stream function. The most common use-case for multiple consumers is a second consumer for printing / inspection purposes, but that is trivial to model as a map function that logs the value and returns it. You may want to ask other's who have used Stream like abstractions how common the multiple consumer case is. On Mon, Apr 15, 2013 at 4:35 PM, Tab Atkins Jr. jackalm...@gmail.comwrote: On Mon, Apr 15, 2013 at 4:24 PM, Jake Verbaten rayn...@gmail.com wrote: Would it help to split the sugar and combinator from the actual stream interface? ``` callback StreamInit = void (StreamResolver resolver); callback AnyCallback = any (optional any value); [Constructor(StreamInit init)] interface Stream { Stream listen(optional AnyCallback? listenCB = null, optional AnyCallback? completeCB = null, optional AnyCallback? rejectCB = null); } interface StreamResolver { void push(optional any value); void complete(optional any value); void reject(optional any value); }; Thanks, I should have done that originally! One basic thing missing from this API is the ability to stop listening to a stream. Hm, yes, you need to be able to unlisten. I'd forgotten about that. Other things missing are the ability to abort / cancel / close a Stream, the ability to pause or resume a stream. I think all of these are only suited for single-consumer streams. My original proposal is explicitly for multi-consumer streams, as I designed it explicitly for DOM use-cases that I ran into. If you have a single-consumer stream, though, I agree that you should be able to pause and cancel a stream. Same with Futures, for that matter. It should also be made clear how and when a stream may emit values. Whether it is at any arbitrary time and it will send to whomever is listening at that moment. Whether it is only allowed to emit values after a listen call. Does every call to listen get the entire history independently of other calls? (Doing so would buffer all data and defeat the point of a stream). What happens when you push a value into the resolved and no-one is listening? By virtue of not defining this, I implicitly answered your questions. ^_^ It's a purely async data source, and cares not for whether you're listening. (Again, the use-cases I was trying to solve are DOM-oriented.) If you're not listening when one comes through, too bad. Of course, recall that updates are processed async, so you can't miss any updates within any particular tick. Another decision that needs to be made is whether it makes sense for a stream to emit multiple errors? For a Future it doesn't make sense because it can only be fulfilled to a single value. For a stream it may make sense for multiple errors to occur. Good question. My design assumes that once something errors, it's because it's now invalid, and won't be producing any more. If you can emit errors and still keep updating, they probably shouldn't reject the stream, but just be a special update value. I personally like the `listen(onChunk, onEnd)` syntax as it matches a popular stream baseclass from the node community ( https://github.com/dominictarr/through#through ) in terms of simplicity. That's my syntax, except that I allow you to distinguish between the stream ending normally and with errors. If you ignore the reject callback, my listen() is *exactly* that syntax already. ~TJ ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: First crack at a Streams proposal
So one thing that is confusing is that `next()` has an API that looks like the stream is a pull stream. A pull stream means that you call next() and it will give you the next value when it has it. This type of stream generally buffers values internally and only gives you them when you pull them out by calling next(). Node's streams2 API has a similar thing with a read() API. The semantics of the stream are actually push, which means the stream will just push values out whenever it has them and it's the consumers responsibility to add listeners using `listen()`. The usage of `next()` is confusing as it's easy to mistake the stream for being pull based. On Mon, Apr 15, 2013 at 5:26 PM, Kevin Gadd kevin.g...@gmail.com wrote: OK, it sounds like this is sort of a 'lossy' stream concept, then, in that if you fail to call next() early enough, you can miss data from the stream? I can see how that would be acceptable for certain use cases. To me though, this limits use of the primitive. Here's a hypothetical. I'm building an instant messaging webapp - think google talk - and I want a 'stream' that represents the status of my online buddies. So each time someone goes online/offline, that would come through the stream. It sounds like with this design, were I to use next() to pull data out of the stream, any online status changes that have occurred before I called next() are lost forever, because at any given time all calls to next() return a future for the 'next update'. This means that if the portion of my service responsible from the contact list starts later than the actual network backend, it can miss status changes and end up with a partial picture of the state. Maybe that's ok. Similarly, it sounds like given this model if I have 3 consumers, and they all call next() once to get values, they have to be absolutely certain to call next() again *as soon as* the Future from the previous next() gets data. If they do the 'right thing' that you normally do in Future-oriented scheduling, where a future being activated results in a task being scheduled to do work, it's possible to miss data, given a flow like this: 1. The consumers call next() and get futures (we'll call these A) 2. Data A is pushed into the stream. 3. Futures A are all fulfilled with data A. The handlers responsible for responding to it push work items onto the message queue (or event pump, or setTimeout, or whatever). 4. Data B is pushed into the stream. There are no next listeners at this point. 5. The work items on the message queue run, respond to Data A, and then call next() to get futures (we'll call these futures B) 6. Data C is pushed into the stream. 7. Futures B are fulfilled with data C. In this scenario, I don't think data B would ever be observed using next(), which feels like a real trap for the unwary. You would normally solve this with some sort of buffering, like you see in sockets and many threading setups, in order to handle cases where a consumer is not able to respond instantaneously to the flow of data. Is this just an incorrect use of 'next' - are you supposed to instantaneously respond to your Future from next() completing by calling next() again? In many Future models this is inadvisable because you can end up with recursive completion of futures when the stream is full - each call to next() returns a future that is already complete, so as soon as you attach a callback to the future, that callback completes and you climb down the stack, recursively processing data until you run out of stack space. I can see how perhaps the implicit assumption here is that the stack overflow scenario is prevented by utilizing the event loop/message pump to fulfill futures, but honestly I think any design which depends on that is a rather questionable design. Another question: Given this sort of 'synchronized' update model, what happens if two consumers both cause data to be pushed into the stream? There are two values to send out, but next() only has room for one value. Does the second value get thrown away? Does an exception get raised by the second push? I don't know how you can ensure that all the consumers will see the second value. I think I will have to echo others' thoughts here that this really doesn't seem like a 'Stream' API. It does not match the semantics of any Stream primitive/concept I have ever encountered in an API. On Mon, Apr 15, 2013 at 5:14 PM, Tab Atkins Jr. jackalm...@gmail.comwrote: On Mon, Apr 15, 2013 at 5:06 PM, Kevin Gadd kevin.g...@gmail.com wrote: If this is really about multiple-consumer streams, the semantics of this proposed API are incredibly murky to me. What happens if each consumer calls next()? Do they all get the same value out of their Future when it's completed? Do they each randomly get one of the values pushed into the stream? Is the stream implicitly required to buffer data in order to be able to offer it at a
Re: Updates to Object.observe
This API looks good. I've written a similar data binder and it's nice to be able to have this functionality natively The only thing missing is the ability to observe a single property of an object rather then all properties. On Tue, Jul 17, 2012 at 4:49 PM, Erik Arvidsson erik.arvids...@gmail.comwrote: We've done a bunch of updates to Object.observe in preparation for the next weeks face to face meeting. The updates are based on feedback from multiple people but more feedback is always welcome. http://wiki.ecmascript.org/doku.php?id=strawman:observe -- 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
Deep cloning objects defined by JSON.
Most of the time the purpose of deep cloning objects is deep cloning data structures. It's been discussed that generically deep cloning proxies, privates and functions is a non-trivial problem. However it would be of value to have a mechanism to deep clone anything that would be valid JSON (Limiting to JSON is arbitary, it's a well defined subset and none of the subset would involve difficult points to resolve). This gives us - An efficient deep clone implementation in the js engine - Solves difficulties with deep cloning by disallowing difficult objects from being deep cloned. - gets rid of every clone function that every library has. I presume this would literally be a highly optimised version of JSON.parse(JSON.stringify(o)). Potential issues - subset of JSON is too restricted to be useful - Proxies/private state may cause issues (the same issues would apply to JSON.stringify ?) - What's the value of the [[Prototype]] of the clone? (JSON.parse uses the standard [[Prototype]] for the stringified object) - Do we expect anything sensible to happen with host objects? (JSON.parse returns objects with few or no properties for host objects) - Do we solve cyclic references? (JSON.parse fails on them) ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Deep cloning objects defined by JSON.
On Sun, Jan 22, 2012 at 8:29 PM, Rick Waldron waldron.r...@gmail.comwrote: Potential issues - subset of JSON is too restricted to be useful This alone seems like a deal-breaker/non-starter. How would you copy methods? Forgetting about cyclic reference exceptions for a moment: The idea here is that methods do not belong in data structures (clone should be to efficiently clone data). a possible solution would be allow you to set the [[Prototype]] of the returned clone through the API somehow and then store methods on prototypes. It does gain the benefit of not having to document the edge-case behaviour for cloning methods. It would presumably also be an API that can efficiently clone the new binary data types. The main purpose is efficient in memory copies of data and not generic cloning of things. If we add a clone, we probably want to add support for cloning binary data types to the list as well. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Deep cloning objects defined by JSON.
The idea here is that methods do not belong in data structures (clone should be to efficiently clone data). This is already too much unfortunate restriction. What about calculated get properties: var o = { ... get foo() { ... return foo; ... } ... }, ... clone = JSON.parse(JSON.stringify(o)); clone { foo: 'foo' } I don't know what the sensible choice here is. Could be either way. Your right, restrictions are annoying. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ES5 Module Systems (was: Alternative proposal to privateName.public)
However, I am confused by the module.exports = ... part of your boilerplate. The main CommonJS wiki seems down at the moment, but looking at http://wiki.commonjs.org.mirrors.page.ca/articles/m/o/d/Modules.html on the mirror site, I could not find any support for this idiom. The closest I could find was http://wiki.commonjs.org.mirrors.page.ca/articles/m/o/d/Modules_SetExports_9215.html, which suggests it should read module.setExports(...); instead. Where does module.exports = ... come from? module.exports = ... is a mechanism in node.js to overwrite the exports object entirely. (useful when you want to export, say a function rather then an object) It seems to be similar to module.setExports and is there purely to support the implementation of the module system in node.js ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ECMAScript.next features in Firefox?
Do we have a similar list for the features in chromium that are enabled through the harmony flag? ( http://codereview.chromium.org/9008031 ) On Sun, Dec 25, 2011 at 9:31 AM, Axel Rauschmayer a...@rauschma.de wrote: Is there a list somewhere of ECMAScript.next features that have already been implemented in Firefox? Thanks! Axel -- Dr. Axel Rauschmayer a...@rauschma.de twitter.com/rauschma Home: rauschma.de Blog: 2ality.com ___ 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 object extension
First, if obj already has a non-configurable property 'a', this will throw I don't think object extension on a non configurable properties should be a no op. Your basically saying extend obj with { a: 1 } unless doing so would throw an error, in which case fail silently Personally I don't like silent failure points. Another feature which could be handy is extending an object with another already existing object (aka mixins?). Having some kind build in API to mixin / extend objects would indeed be helpful ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: On object extension
Current proposal would turn a configurable non-writable property into a writable property which is not a silent error, but rather a big mistake. If that is the case then I agree that would be bad. Whether we want to throw an error or silently do a no-op is another discussion. Given that it would throw if any of the 3 (or n) properties your trying to extend fails it would make more sense to have a silent no-op as a default. This way the other property extensions succeed. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: why not new instead of constructor?
[snip] let Point = class { x: 0, //not really needed unless defining an object exemplar y: 0, new(x,y) { this.x = x; this.y=y; } }; Yes this is better, could we go one step further and allow for Point.new(1,2) to work instead of new Point(1,2). If we just make the new method property create an instance of Point and pass that in as the this value then it would solve the need for having new ObjectExemplar. This would behave similarly to selfish's .new function. The only issue is that all code that checks obj.constructor for the link will break because we no longer link the constructor anymore. It is shorter to type, reads better, and is much more suggestive of its direct relationship with the new operator. The only real issue I can think of is that in ES5 unquoted new is a valid property name in an object literal. However, in this case we are using it in a new syntactic context (a concise method property) that doesn't exist in ES5. Whether or not we also let gave new this meaning in a propertyAssignment form (a breaking change) can be a secondary design decision to be considered. Related would be concern that there are frameworks that actually use obj.new() as an idiom. We probably would need to be careful to not break those, but I think that is also doable. There are various semantic details that need to be specified, but none of them seem difficult. Before getting into them, I'm more interested in what is essentially a bikesheding questions: is this a direction that we shoud consider? allen ___ 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
default this binding for ES-next strict mode.
Currently in ES5 strict mode the value of `this` is `undefined` by default. function foo() { return this; } foo(); // undefined function foo() { return (function () { return this; }()); } foo.call(o); // undefined Since the default value of `this` is always undefined, the `var that = this;` or `var self = this;` pattern has occurred. An alternative to this pattern is using .bind on a function. var Obj = { method: function () { var that = this; el.addEventListener(click, function () { that.doSomethingElse(); }); } } Basically whenever a javascript developer want's to do an asynchronous operation using a closure inside a method he has to keep a handle on the value of `this` because the value of `this` inside the closure is useless. This is more common in environments where asynchronous operations are more common, like node.js. What if we changed the value of `this` inside local function declarations to be the value of this in the outer function. That would mean function foo() { return (function () { return this; }()); } foo.call(o); // o Pros: - Removes the majority of the use-cases for `var that = this` - Puts a value of `this` to good use rather then being `undefined`. Cons: - Makes `this` more confusing - Breaks ES5 strict code that assumes `this === undefined` Personally I say that value of `this` is undefined in ES5 strict. So nobody uses it. So this is an optional addition that would make life easier for people who want to use it. Optional: Change the value of `this` to be the outer function `this` in non-strict mode (breaking a large amount of code. I don't think we can get away with that). ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: default this binding for ES-next strict mode.
On Fri, Nov 18, 2011 at 9:30 PM, Axel Rauschmayer a...@rauschma.de wrote: What if we changed the value of `this` inside local function declarations to be the value of this in the outer function. I’d love this to work! Alas, the value of `this` has to be determined dynamically. Mark Miller gave a good example why that’s bad (when I recently suggested the same thing): http://www.mail-archive.com/es-discuss@mozilla.org/msg11194.html I don't think that's neccessarily a bad thing. If you ask me, it's a poor counter example because innerPoint should not be defined inside Outer. I defiantly see the problem with the value of `this` leaking through any closures you return. I'm not sure whether this is particularly bad. It's just something people need to be aware of. Of course this adds two more cons Cons: - outer value of `this` leaks through returned closures - code that used to throw an error, will now work with unexpected side effects. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: The class operator: a bridge between object and function exemplers
5 Let *proto* be the value of the [[Prototype]] internal property of *obj*. 6 Return the result of evaluating this algorithm using the value of *proto* as the value of *UnaryExpression* * * What is the point of calling class recursively on the [[Prototype]] if the object does not have constructor or [[ctor]] ? Other then that, this solves the issue in an intuitive way. On Thu, Nov 17, 2011 at 5:04 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: OK, I have a fix for the missing constructor problem. See: http://wiki.ecmascript.org/doku.php?id=strawman:class_operator#missing_constructors Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: The class operator: a bridge between object and function exemplers
On Thu, Nov 17, 2011 at 11:39 PM, Brendan Eich bren...@mozilla.com wrote: On Nov 17, 2011, at 3:31 PM, Allen Wirfs-Brock wrote: We can debate whether Default Constructors should do a: if (super.constructor isnt Object) super.constructor() but that is a more basic question about whether constructors (default or otherwise) should always do implicit super calls. We should debate. What do you think? Personally I cannot think of any examples where this functionality would be unwanted. This debate will probably depend on the counter examples where invoking the super constructor implicitly is unwanted behavior. An argument for doing this is that you can use initialize or some other name for constructor like functions that don't implicitly make super calls. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: r-proto-class
Anyway, once again, the main point I wanted to note, is that we _already_ may have more-less good classes via libs with more-less acceptable convenient super-calls. The standardized version should be better that all the libs. I.e.: (1) not to have the issue you describe and (2) which IMO even more important -- to be _really_ a sugar, but not syntactically odd stuff. Correct, we can implement these patterns, we just need a standardization mechanism, so that we no longer have hundreds of versions of this pattern. I too believe that class is only sugar, however we do want to add new syntax to object literals. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: r-proto-class
Even with adding properties to objects (which is a no-no for ES.next), dynamic super is never particularly elegant. This was the best solution I could come up with and it’s not pretty: https://gist.github.com/1331748 If we could get away with manipulating the prototype chain at run time then super can be implemented as https://gist.github.com/1367167 The idea of temporarily plucking the current [[Prototype]] out of the chain, is how I envision super should work. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: The class operator: a bridge between object and function exemplers
*UnaryExpression* : *class* *UnaryExpression* ... The semantics are: 1. if *UnaryExpression* is undefined or null, return the value of * UnaryExpression*. 2. Let *obj* be ToObject(*UnaryExpression*) 3. Return the result of calling the [[Get]] internal method of *obj* with argument 'constructor' Interesting, so 'constructor' will inherit from Object.prototype if missing from the exemplar. This means let Point = class { x:0, y,0 }; let p = new Point(1, 2); will result in p being constructed via the equivalent of new Number(1). When you create a function, it has an automatically created prototype object who has a constructor property defaulted to the original function. Why would it be bad to augment the UnaryExpression after the class keyword so that it has an empty constructor if it doesn't exist? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: The class operator: a bridge between object and function exemplers
The whole concept is great. What class does for the JS community is give everyone a standardized way to write classes. The simplest way to have a class is to call ObjectLiteral.constructor and that's exactly what this class syntax does. This also means that it's very easy to adapt to using this. This class proposal is also orthogonal to object exemplars. Apart from setting `obj.constructor.prototype = obj` in the background when you declare an object literal and making function | object work, we don't actually need to augment new and instanceof to work with objects. On Mon, Nov 14, 2011 at 8:16 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: (I'm going to write this up as a strawman, this list gets first shot at it...) Introduction [snip] ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
Neither of them are fit for standardization. Selfish and Prototype are both incapable of correctly deep copying arrays or objects, Why does it matter that they don't deep copy? Deep copying is a difficult problem that needs to be standardized separately. I've personally avoided deep copying for this reason and don't use it anymore. One can accept that an extend is merely a shallow copy properties by reference, because this (although limited) behavior is easy to understand. I have a version of Object.extendhttps://github.com/Raynos/pd/blob/master/src/pd.js#L82 that is a shallow own merge. However having a deep copy mechanism that works without obscure edge-cases would be great. Of course it would be nice if we had the choice of deep vs shallow copy within the API. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
Should `extend' copy all the properties? Only the own properties? I feel `own' properties make more sense. I agree own makes more sense, we also want to specify whether we want to extend enumerable properties. Your example does not. - Defining new objects that extends on the [[Prototype]], which is basically Object.create followed by copying the properties of one or more objects over to the new instance. (Object.clone? Object.inherit? I never felt `extend' quite says it all) Object.prototype.clone(Object parent, Object mixins...) → Object (Object.extend.apply(Object.**create(parent), mixins)) I've been referring to this method as Object.makehttps://github.com/Raynos/pd/blob/master/src/pd.js#L120 it's defiantly a useful method, however I don't think clone, inherit or make are correct names for it. clone is probably the most suitable name, especially if it's on Object.prototype var foo = Base | { #constant: 1, // or const @private_stuff: bar, // or private method1() { }, method2() { } get stuff() { } } Except I'm not sure the @private could be made to work without creating confusing semantics around it, so object literals would still be one step behind. As far as I understand @private_stuff would desugar into a name object only available in scope of the object literal. var o = { @private_stuff: bar; method1() { } } var o = (function () { var private_stuff = name.create(); var ret = { method1() { } } ret[private_stuff] = bar; })(); I personally don't find that confusing. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
However having a deep copy mechanism that works without obscure edge-cases would be great. Can you be specific? What obscure edge cases have you previously encountered? I don't have a list at hand, last time we talked about what it means to deep copy an arbitary ES-next structure we ran into questions of what it means to deep copy functions, closures and proxies. Deep copying data, i.e. anything that can be represented by JSON doesn't have too many edgecases. It would actually be nice to have an open lists of unsolved edge cases with generic deep copying. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
On Sun, Nov 13, 2011 at 4:51 PM, Rick Waldron waldron.r...@gmail.comwrote: On Nov 13, 2011, at 11:03 AM, Jake Verbaten rayn...@gmail.com wrote: However having a deep copy mechanism that works without obscure edge-cases would be great. Can you be specific? What obscure edge cases have you previously encountered? I don't have a list at hand, last time we talked about what it means to deep copy an arbitary ES-next structure we ran into questions of what it means to deep copy functions, closures and proxies. Can you point me to existing discussion threads? The only thing I can find is https://mail.mozilla.org/pipermail/es-discuss/2011-October/017337.html This particular thread talked about | and how to make it work on object references rather then object literals. Since | returns a new object it would have to clone the object reference in some correct manner. Deep copying data, i.e. anything that can be represented by JSON doesn't have too many edgecases. It would actually be nice to have an open lists of unsolved edge cases with generic deep copying. This would definitely be useful. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist (why) classes ?
Let's argue about specifics or we'll get nowhere. Do you think Irakli's selfish.js extend ( https://github.com/Gozala/selfish/blob/master/selfish.js) is the way to go, or Prototype's quite different form? I'd personally prefer Prototype's extend because it actually extends an object rather then creating a new object whom's [[Prototype]] is the extended object. Even though the latter may be useful, I'd rather have an Object.make or Object.createSimple for that. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Subclassing an array and array methods
In es-next we should be able to subclass an array function createArraySubclass(proto, ...values) { return proto | [...values]; } However when we call `instanceOfSubArray.filter(...)` this method returns a new Array rather then a new SubArray. It would seem frustrating to have to overwrite all array methods that return arrays and make them return subarrays. Can we have array methods returning new instance of [[Prototype]] to make it easier to overwrite the build in? However this should only apply to true array subclasses. In the above example I would assume the [[Class]] of the object is Array. It should not apply to [].slice.call(arrayLikeObject) Do we have other situations where it would make sense to return an instance of whatever prototype your operation on rather then a hardcoded new X ? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: What do we still need from a class-like abstraction (was: `this`: methods versus functions)
The only value prototype inheritance gives is the fact you can change the prototype and changes are reflected. If you do not want that feature then use mixins. On Thu, Nov 10, 2011 at 4:56 PM, Andreas Rossberg rossb...@google.comwrote: I wholeheartedly agree that mixin composition is superior to both prototype and class-based inheritance. I'm not sure I entirely follow your point regarding `this', though. (TBH, I'd prefer not having a `this' keyword at all, because not being alpha-convertible, it doesn't really compose with nested definitions, and invites subtle mistakes -- a lightweight syntax for binding an arbitrary identifier to self seems better.) The traits proposal currently is nice indeed, but also quite heavy on going through reflective meta levels. It will require significant work to make that efficient. But I believe there is potential for VMs optimizing e.g. nested closure creation for certain patterns. Though obviously, implementers currently have other priorities (like catching up with ES6 features first :) ). /Andreas On 10 November 2011 16:59, Mark S. Miller erig...@google.com wrote: Note that the traitsjs library provides: 1) all the safety of the objects-as-closure pattern you show below (and more because it takes care of the needed freezing). 2) still allows intuitive use of this to refer to the instance itself, bound not lexically, but rather at object instantiation time. This enables 3) a superset of conventional oo inheritance and override patterns, where the lookup of this.getX() is determined by the concrete subclass, rather than either the lexical occurrence of this or self (as below) nor by the client (as in JS prototypal inheritance). I say superset because it also provides 4) an understandable alternative to multiple inheritance: symmetric traits composition with explicit conflict resolution. TraitsJS also has the same problems that presently deter people from using objects-as-closures: 5) Without VM support, it costs at least an allocation per method per instance, making it much too expensive. (See micro benchmarks in http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/en/us/pubs/archive/37485.pdf .) 6) It is observably different than simply being sugar for JS's prototypal inheritance, introducing a non-uniformity when linked with libraries using prototypal inheritance. I think I am satisfied at this point that prototypes as classes has made a plausible enough start on addressing point #6 in its own way, without introducing an explicitly class-like abstraction, that we may not need classes-as-sugar for prototypal inheritance. This leaves #5 as *the* pressing problem for use of either safe pattern: objects-as-closures (as below) or traits (as in traitsjs or possibly eventually class-like sugar for them as previously proposed). My previous proposal for class-like sugar for traits composition was not popular. Whereas, in the absence of problem #5, I suspect the traitsjs library would be. As previously observed on this list, traitsjs is more JavaScripty. Ideal would be for JSVMs to magically make traitsjs efficient without requiring any language changes. If this is infeasible, perhaps we should instead be looking for the minimal language change that would enable a revision of traitsjs to run efficiently on ES-nest-next JSVMs. I say ES-next-next because it is too late to consider any such language change for ES-next. However, implementation experiments need not wait. On Thu, Nov 10, 2011 at 7:19 AM, Andreas Rossberg rossb...@google.com wrote: [...] No, that's how it works right now. The alternative is to lexically close all methods over self at construction time: function Point(x, y) { var self = this self.x = x self.y = y self.move = function(dx, dy) { self.x += dx; self.dy += dy } } function ColorPoint(x, y, color) { var self = this Point.call(self, x, y) self.color = color self.recolor = function(c) { self.color = c } } As said, this doesn't play well with prototype inheritance. You have to put all methods that refer to self on the object itself. But inner constructors are straighforward and safe. -- 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: for..in, hasOwnProperty(), and inheritance
Whats wrong with enumeration over own properties? Object.keys() gets all enumerable own properties in a for .. in loop. for .. in gets all enumerable properties in prototype chains. I personally think it's bad practice to have code that enumerates over properties in the prototype chain. I can't see any good use case for it On Tue, Nov 8, 2011 at 7:59 AM, Felipe Gasper fel...@felipegasper.comwrote: Hi everyone, There is a widespread practice of doing this: - for (key in obj) { if (obj.hasOwnProperty(key)) { … } } - The oft-stated purpose for this pattern is to weed out code that comes from Object.prototype. The result, though, is that we prevent iteration through *any* inherited properties, which seems like overkill for handling the original problem. (Incidentally, I’m surprised that augmenting Object.prototype isn’t warned/deprecated in ES5 Strict. It seems far easier to get people to stop augmenting Obj.pro, which is likely to break all kinds of things, than to get everyone to filter every for..in loop. But, anyway.) It’s especially unproductive because it works against prototypal inheritance patterns. e.g.: - var dog = { speak: function() { return arf! } }; var beagle = Object.create(dog); beagle.colors = [white,black,brown]; var my_dog = Object.create(beagle); my_dog.name = Chip; - Note that filtering via hasOwnProperty() will prevent a for..in iteration from seeing either colors or speak. Another example: in YUI, it’s impossible to do this would-otherwise-be-useful pattern: - var base_config = { width: 600px }; … var my_config = Object.create(base_config); my_config.visible = false; var widget = new Y.Widget(my_config); - In the example above, YUI will not see the “width” property because YUI rejects all inherited properties when it iterates through the configuration hash. So, a solution I am considering for my own work defines two methods: Object.gave(giver, key, obj) Function.prototype.gave(key,**obj) They do what they look like: Object.gave checks if the “giver” really “gave” the “key”ed value to the “obj”ect. The Function.prototype version does the same but assigns the function’s prototype as “giver”. (The original Object.gave() offloads to the prototype method if called with just two args.) Thus: -- var HOP = Object.prototype.**hasOwnProperty.call.bind(**Object.prototype.* *hasOwnProperty); Object.gave = function(giver,key,obj) { if (arguments.length === 2) { Function.prototype.gave.apply(**this,arguments); } var last_prototype; while ( obj !== giver ) { if (HOP(obj,key) || (obj === last_prototype)) return false; last_prototype = obj; obj = Object.getPrototypeOf(obj); } return true; }; Function.prototype.gave = function(key,obj) { return Object.gave( this.prototype, key, obj ); }; -- Then, we can do: -- for (var key in obj) { if (Object.gave(key,obj)) { … } } -- …which will still filter out anything in Object.prototype, but will allow iteration through inherited properties. This seems to me far more useful in general than the hasOwnProperty() check. Thoughts? -Felipe Gasper cPanel, Inc. __**_ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: for..in, hasOwnProperty(), and inheritance
You shouldnt store properties on the prototype chain like that. Your abusing Object.create as a shallow copy. Use a real shallow copy method. On Nov 8, 2011 7:07 PM, Felipe Gasper fel...@felipegasper.com wrote: On 11/8/11 12:37 PM, Axel Rauschmayer wrote: What’s the use case? I thought I gave a pretty reasonable one before, but just in case: In YUI, it’s impossible to use this otherwise-useful pattern: - var base_config = { width: 600px }; … var my_config = Object.create(base_config); my_co... Don’t forget that whenever you set a property, you only ever modify the first object in the prot... Right…that’s why gave() walks the prototype chain unless it finds the property *on* the object itself. The “own property” debate mainly exists, because objects are (ab)used as dictionaries. Then ... I disagree. That’s actually the crux of what I’m getting at. IMO, you actually do want “inherited entries”; what you don’t want are specifically those things inherited from Object.prototype. Weeding out *all* inherited properties assumes that there is no legitimate use case for objects inheriting from other objects…which defeats the whole purpose of stuff like Object.create(). -FG ___ es-discuss mailing list es-discuss@mozilla.org http... ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: for own(...) loop (spin-off from Re: for..in, hasOwnProperty(), and inheritance)
On Tue, Nov 8, 2011 at 11:36 PM, Brendan Eich bren...@mozilla.com wrote: Ignoring performance, a lot of stylish JS hackers use Object.keys(o).forEach. How many run into the wrong |this| (arguments/break/continue/return)? Not clear. Something to study. /be I personally use `Object.keys()` on all my objects just because it's a neater construct. I havn't really run into much problems with the `this` value. None more then I would be forgetting it on any other inner function. As an aside `break and continue` are emulated using `Object.keys(o).any`. But that is rarely done. Trying to access outer arguments or returning from inside the loop is also rare. the former is gaurded by unpacking arguments at the top of the function and the latter is gaurded by using `.any` again and propagating the return value. (Most of the time if I return from a loop it's a boolean) However on average a lot more people will use for ... in with hasOwnProperty because ES5 environments are rare and a lot of people avoid the ES5-shim ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: for own(...) loop (spin-off from Re: for..in, hasOwnProperty(), and inheritance)
In the real world IE9 still accounts for almost 50% of browsers. Then there's another 6% for FF3.6 and another 3% for opera. As much as I like promoting that you should ignore legacy browsers, for most people 50% market share is a good enough reason to support them. On Wed, Nov 9, 2011 at 2:03 AM, Quildreen Motta quildr...@gmail.com wrote: On 08/11/11 23:59, Jake Verbaten wrote: However on average a lot more people will use for ... in with hasOwnProperty because ES5 environments are rare and a lot of people avoid the ES5-shim Do you mean `rare' as in they have to work with the lowest common denominator (IE)? Because ES5-not-so-fully-but-somewhat-**there-for-most-common-stuff environments are the majority, afaik. __**_ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Yet another class declaration proposal
I like this one mainly for the line class declarations and object literals should have the same features However if they have the same features then why bother with class at all. Why not just have let Monster = Being | { ... } This way we don't introduce the class keyword which is confusing and loaded with assumptions about what it does and means. On Thu, Nov 3, 2011 at 4:14 PM, Axel Rauschmayer a...@rauschma.de wrote: FWIW: I’ve picked what I like from the various proposals. https://gist.github.com/1336846 -- Dr. Axel Rauschmayer a...@rauschma.de home: rauschma.de twitter: twitter.com/rauschma blog: 2ality.com ___ 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: Loyal Opposition to Const, Private, Freeze, Non-Configurable, Non-Writable...
I don't think I've ever heard an active JavaScript developer, who has been programming in JavaScript longer than 6 months, ask for private class or instance variables. Your own code: https://github.com/mikeal/npmjs.org/commit/c0d9cc77e79504b9a7c23b4fac735dde97444054#L3R10 Line 35, you define the function stopBuffering (keeping only relevant parts): function File (options) { var stopBuffering = function () { // ... } } Why didn't you do this.stopBuffering = function(){}? Maybe you used the keyword var, but you effectively created a private method of your File class. With a class syntax, you would have used the private keyword to achieve the same thing. Maybe you don't call it this way, but you use (and de facto ask for) privacy. I think making such broad statements as every local variable is actually a 'private' variable is just plain silly. To me that looks like a utility method for code organisation points. private means its a private method/data that's used in other methods of an object. That particular function is not used in any method. And no, with class syntax it would not be private, it would still be a utility function inside the constructor. I personally second that we don't need private or instance variables. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Minimalist Classes
Why isn't the |super| lookup-point |this.getPrototypeOf()| Assume |super| is |this.getPrototypeOf()| Let F be a class, let f be an instance of the class. inside f you have access to a method defined on F. If you call a method defined on F from f and that method calls super, you would be invoking getPrototypeOf(this) which is just F (since this is f, and the prototype of f is F). So you would then end up calling the same method again and recurse endlessly. Basically because you apply methods with a value of this then if super were tied to this you would get infinite super recursion if you chained super calls. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: On class literals possibly not making it into ECMAScript.next
On Sun, Oct 30, 2011 at 11:45 AM, Rick Waldron waldron.r...@gmail.comwrote: On Oct 30, 2011, at 5:58 AM, David Bruant bruan...@gmail.com wrote: Le 30/10/2011 02:35, Quildreen Motta a écrit : (...) Are we overthinking classes? Perhaps the reason for all this thinking about classes come from the role constructor functions take in the language? I'm a bit sceptical on constructors and constructor's own properties being that important, though. I agree. Has anyone used constructor properties for static properties? Just considering the DOM, constants are put on the prototype and everyone sounds happy with it so far. In jQuery, John/we put static methods and properties on the jQuery() function - this practice is used for anything that is not a selector match operation. This includes Ajax and Deferred (among others). Considering jQuery is used on 26.6million websites, it's safe to bet that practice is in common use. Would there be anything wrong with placing these static methods on the prototype? I presume there is also nothing wrong with placing DOM constants on the prototype? Rick 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 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: More thoughts on Allen’s class definition pattern
the only possible hazard that is left is function exemplar code trying to access ObjectExamplar.prototype Could you illustrate where a function exemplar may try to access an ObjectExemplar.prototype property? Would this be old code that accepts an exemplar as input but expects it to be a function exemplar? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: On class literals possibly not making it into ECMAScript.next
Whilst on the topic of object literal extensions, did we make any progress on supporting what allen calls exemplarshttps://mail.mozilla.org/pipermail/es-discuss/2011-October/017369.html ? let Employee = Person | { constructor(name, title) { super(name); this.title = title; }, describe() { return super.describe(this) + ( + this.title + ); } }; On Sat, Oct 29, 2011 at 4:23 AM, Axel Rauschmayer a...@rauschma.de wrote: http://brendaneich.com/2011/10/jsconf-eu/ I’d be sad not to have class literals in JavaScript. However, with the new object literal extensions, things are still much better than in ES5. Compare: The ES5 version is clumsy. // Super function Person(name) { this.name = name; } Person.prototype.describe = function() { return Person called +this.name; }; // Sub function Employee(name, title) { Person.call(this, name); this.title = title; } Employee.prototype = Object.create(Person.prototype); Employee.prototype.constructor = Employee; Employee.prototype.describe = function() { return Person.prototype.describe.call(this)+ (+this.title+); }; The ES.next version is quite nice: // Super function Person(name) { this.name = name; } Person.prototype .= { describe() { return Person called +this.name; } } // Sub Person | function Employee(name, title) { super(name); this.title = title; } Employee.prototype .= { describe() { return super.describe(this)+ (+this.title+); } }; This is not bad at all, quite teachable! Having a single construct instead of piecing things together via multiple assignments might be a problem in some cases. Then you could use the latest incarnation of Allen’s class pattern: Person | function Employee(name, title) { super(name); this.title = title; }.={ prototype.={ describe() { return super.describe(this)+ (+this.title+); } } // “class” variables go here } [I’m using the destructive version of the extension operator, as shown in Brendan’s blog post] -- Dr. Axel Rauschmayer a...@rauschma.de home: rauschma.de twitter: twitter.com/rauschma blog: 2ality.com ___ 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: More thoughts on Allen’s class definition pattern
Personally I'd ask whether there is a good reason to have class properties on the constructor. //class (ie, constructor) properties You could have them on the prototype instead and then you can access these class properties through all your instances. Also you could just re-order the assignment like so : const className = superClass | function(/*constructor parameters */) { //constructor body super.constructor(/*arguments to super constructor */); this.{ //per instance property definitions }; }.{ //class (ie, constructor) properties }.prototype.{ //instance properties defined on prototype }; On Sun, Oct 30, 2011 at 12:34 AM, Axel Rauschmayer a...@rauschma.de wrote: http://wiki.ecmascript.org/doku.php?id=harmony:object_extension_literal_class_pattern const className = superClass | function(/*constructor parameters */) { //constructor body super.constructor(/*arguments to super constructor */); this.{ //per instance property definitions }; }.prototype.{ //instance properties defined on prototype }.constructor.{ //class (ie, constructor) properties }; The main problem is that obj.prototype.{...} does not evaluate to obj, then one could chain additions to the function. With custom Function.prototype.* methods, that can be easily achieved: const className = superClass | function(/*constructor parameters */) { //constructor body super.constructor(/*arguments to super constructor */); this.{ //per instance property definitions }; }.proto({ //instance properties defined on prototype }).class({ //class (ie, constructor) properties }); But what if one could write a function like an object literal? const className = superClass | function { (/*constructor parameters*/): { //constructor body super(/*arguments to super constructor*/); this.{ //per instance property definitions }; }, prototype: { } //class (ie, constructor) properties }; -- Dr. Axel Rauschmayer a...@rauschma.de home: rauschma.de twitter: twitter.com/rauschma blog: 2ality.com ___ 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: More thoughts on Allen’s class definition pattern
class-specific constants such as Point.ZERO. Why can't this be on the prototype? Why do we even pass the constructor function around as an object? I agree we need a better way of writing this, I think the flaw lies in passing constructor functions around everywhere. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Terminology: types, constructors, classes, …
I believe the community just says A inherits B even thought they mean that A.prototype.[[Prototype]] == B.prototype. On Oct 23, 2011 7:24 PM, Axel Rauschmayer a...@rauschma.de wrote: - What about primitives?Are there primitive types and object types? Is the union of the two calle... Yes that is probably the most elegant way of defining the term. Afterwards, one can go on and describe how primitives work. - If instance factory B inherits from instance factory A, is B a subclass of A? B a subtype of ... B.prototype inherits A.protoype. A.prototype is a prototype of B. prototype (ugh). -- Dr. Axel Rauschmayer a...@rauschma.de home: rauschma.de twitter: twitter.com/rauschma blog: 2al... ___ 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: Protocol for new and instanceof?
As for xmlhttprequest not working, I get DOM object constructor cannot be called as a function This basically means xmlhttprequest is a host object which does not want to behave normally. Maybe with some very subtle tricks you can get it to subclass but I recommend not subclassing host objects. I also have a feeling axel means defining a meta object with behaviour for instanceof and new then having every other class-like object inherit it as a base class. As an aside if we allow overloading of new and instanceof, can we overload every operator? On Oct 21, 2011 7:49 PM, John J Barton johnjbar...@johnjbarton.com wrote: On Fri, Oct 21, 2011 at 9:36 AM, Axel Rauschmayer a...@rauschma.de wrote: In a vein similar to... More entirely unsubstantiated personal opinion based on a few days experience: Gonzala's https://github.com/Gozala/selfish does this now and with nicer syntax. One subtle point I missed about his approach: instance (member) variables are created in initializers, not as literals, unless you intend to make the variable part of a prototype. This could be stumbling block for Java converts, who expect declarative members. Only bump so far: XMLHttpRequest.apply fails and you can't run XMLHttpRequest.prototype.addEventListener unless you run XMLHttpRequest() on the object. So I could not figure out how to inherit from XMLHttpRequest. jjb ___ 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: new Object
I do the same with Object.prototype.new = function () { var o = Object.create(this); o.constructor o.constructor.apply(o, arguments); return o; } However rather then calling proto.new(); I would like var o = new proto(); and o instanceof proto to work On Oct 17, 2011 9:17 AM, Irakli Gozalishvili rfo...@gmail.com wrote: I think we should just forget about new keyword, prototype property all togather and move towards something more simple: var proto = { method: function() { }, new: function() { var self = Object.create(this); this.initialize.apply(self, arguments); return self; }, initialize: function(someValue) { this.things = someValue } } var o = proto.new(someValue); Of course with a help of library that would not require as much boilerplate: https://github.com/Gozala/selfish Regards -- Irakli Gozalishvili Web: http://www.jeditoolkit.com/ Address: 29 Rue Saint-Georges, 75009 Paris, France http://goo.gl/maps/3CHu On Tuesday, 2011-10-11 at 20:53 , Jake Verbaten wrote: is there any kind of proposal for syntax that is like : var proto = {method: function(... ___ 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: Exemplar forms
On Mon, Oct 17, 2011 at 11:19 AM, Axel Rauschmayer a...@rauschma.de wrote: [cc-ing es-discuss] On Oct 17, 2011, at 11:31 , Jake Verbaten wrote: If we could find a way to mark methods as constructors (e.g. by prefixing an @, but we are heading into Grawlix territory then), we could do the following: var Point = { @constructor(x, y) { this.x = x; this.y = y; } @zero() { this.constructor(0, 0); } } let p1 = new Point(5, 6); let p2 = new Point.zero(); How is that different from zero() { return new this(0, 0); } Works just as well (because JS engines optimize away the unused instance that is created via new), but I like the elegance of distinguishing between instantiation and initialization. Why do we want named constructors? To better distinguish between several constructors. Does not happen often, but when it happens, it is handy to have. Example: Array (which will be fixed in a different manner, via Array.of(), so this is just for illustrative purposes): new Array(2,3,4) is the same as [2,3,4] new Array(2,3) is the same as [2,3] new Array(2) is the same as an empty array of length 2. With named constructors: new Array(2,3,4) new Array.sized(2) Not surprisingly, I like oExemplars. They almost look like class literals, too. I’m a bit skeptical about having two competing exemplars (more than one way of achieving something leads to confusion, in my experience). I would feel better if oExemplars were the preferred one and fExemplars there for legacy compatibility. I would agree fExemplars should be there for legacy compatibility and that we should encourage oExemplars. If the oExemplars are not the preferred one then we shouldn't be implementing them and should just continue using fExemplars Right, which aren’t too bad with class literals or one of the class definition patterns. This might be a good point to mention that class literals desugaring to oExemplars might be nice. I think there's a stronger 1-1 relation between oExemplars and class literals. Doing this would also make oExemplars the preferred use because the new class syntax would encourage them. -- Dr. Axel Rauschmayer a...@rauschma.de twitter.com/rauschma home: rauschma.de blog: 2ality.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Inner functions and the value of this.
An inner function is a function declaration or expression inside a function. Currently the default value of this is either the global object or undefined for strict mode. (When invoked normally). Would it be possible to have the value of this default to the value of this in the outer function, i.e. the function it was declared in. For example: method: function _method() { var cb = after(n, function() { // this is the value of this inside _method }); } This would basically solve the var that = this and .bind(this) patterns used on anonymous functions. I believe coffeescript has sugar for functions like this with =. Justification: this === undefined is not very helpful. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Inner functions and the value of this.
Im suggesting the rule is value of this binds at location of function instantation. I would expect an invocation of the function elsewhere to still have the this value of the other function (o1 not o2). As long as people understand and follow the rule set it shouldnt be too confusing. Basically a function declaration/expression is automatically soft bound to the outer this. On Oct 15, 2011 2:52 PM, Xavier MONTILLET xavierm02@gmail.com wrote: Well the spec tends to move the other way by removing arguments.callee, caller and so on for security reasons... Plus in your example is given as a callback... If you do this : var o1 = { m1: function ( ) { // here, this is o1 o2.m2( function ( ) { // this function is declared in a function where this is o1 and invoked in a function where this is o2... } ); } }; var o2 = { m2: function ( f ) { // here, this is o2 f( ); } }; o1.m1(); I'm quite sure some people would expect one behavior and others would expect the other one... but it is sure that would be a source of hard-to-track bugs. On Sat, Oct 15, 2011 at 2:54 PM, Jake Verbaten rayn...@gmail.com wrote: An inner function is a ... ___ 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: Exemplar forms (was Your search - | - did not match any documents)
I agree having two types of examplers is sensible. For examples sake let fExemplar be an exemplar constructed with new Function and les oExemplar be the other one. Now, I'm worried about magically making fExemplar | oExemplar work, would oExemplar have fExemplar or fExemplar.prototype in it's [[Prototype]]? How do I tell the prototype of operator to treat fExemplar as a function and not an exemplar. same issues apply to oExemplar | fExemplar. If you do any magic to make inheritance work across exemplar types then I would need a way to tell the prototype of operator that they are just objects functions, not exemplars. however we can already make the two work together like such fExemplar.prototype | oExemplar and var sub = oExemplar.constructor | fExemplar sub.prototype = Object.create(oExemplar); sub.prototype.constructor = fExemplar The fact that the latter is verbose and a pain doesnt matter, because thats old style exemplars inheriting from new style exemplars. However having new style exemplars in inheriting from old style exemplars is less painful. Yes we have the issue of the exemplars not being equal but I dont want you to add magic to prototype of to fix that. However it is reasonable to suggest a new operator for exemplar inheritance that does do magic [snip] I want to compose objects: var result = cookUpTheBehavior(goodies, stuff) | initializeTheState(args); You want something else, then. Just because you want B does not mean A is useless or less useful or not JavaScripty. With a decent Object.extend() we'd have a clean way to build objects without having to look up Crockford's web pages every time we try a different variation. Object.extend is on the agenda. It's not the same as |. Two different tools for two or more different jobs. I want these two tools to work together! I want a standard property cloner and a composition operation that creates objects from a behavior object and data object. Wouldn't that be nice? I agree with this - at least in the sense that I think it might be an appropriate time to take a higher level perspective of all the aspects of JavaScript object definition and reuse. That seems to be a lot of what is being discussed now from class literals to the | operator to new Object to traits. I understand the value of decomposing these ideas down into orthogonal part which can be used independently and combined to create a variety of useful abstractions. However, I think that creating something cohesive is really important, and in the end we will want to provide a clear path for the common cases. I find it a problem that there is a standard pattern in JavaScript for creating classes but there isn't a real name for it. We have constructor functions and prototypes. Even the Rhino book is forced to say, For lack of a better term, I will use the word class informally in this chapter. Then if you want to extend one of these things, you'll have to basically resort to a library or some recipe of your own. It's black magic. And worse, all the built-ins use the pattern, so we're basically going to have it around forever. I understand that this is sort of what | is for, and it is potentially what class literals are for, I guess my point is just that I think it should be a high priority for es.next to result in some definitive way of saying: 1. create a thing Foo, including its constructor and at the very least methods (including get/set methods) 2. create a Bar that extends Foo, including its constructor... This is what Coffeescript provides with class and extend. I get the feeling that using class would be too loaded. If class is going to be used it sounds like people would like more than to have sugar for the existing pattern, they would like more and they don't want to harm future proposals. I think this is fair so I would say take the word class off the table. This is the reason I had previously proposed | as more of a generic extension operator. It's already doing a lot of magic when it comes to functions and arrays. I'm not sure exactly what the answer is, I'll try to think of something better to propose, I just feel like hashing out the individual pieces like | and .{ and Object.extend etc. are all discussions that are worse off for not discussing how they should all work together. - Russ Let me take a crack at tying to tie together all the pieces we have been talking about. To start, I want to introduce a new term that I will use to describe an program construct that defines the common characteristics that are shared by a probably open ended set of similar objects. I want to avoid common terms like class and prototype for such entities because they carry preconception baggage that I want to avoid for now. Instead, I'm going to use the term exemplar. While there has been some limited usage of the term exemplar in computer science, it doesn't have any broadly accepted meaning or carry significant connotations.
Re: Your search - | - did not match any documents
The difference is that object.extend returns objects where as object.make returns things with the same type as the second operand. So object.extend (obj, someFunction) is easy. where as object.make(obj, someFunction) returns a function. Now clearly its a new function so it doesnt share closure state. But then how can you say the returned function is the same as someFunction? This is just one of the edge cases. I would love an object.make as well. But I cant tell you how to handle all the edgecases. On Oct 14, 2011 3:48 AM, John J Barton johnjbar...@johnjbarton.com wrote: On Thu, Oct 13, 2011 at 6:08 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote:On Oct 13, 2... I have not said it did; in fact I said it did not. Mutating [[Prototype]] is not the issue; Literal RHS is the issue. but I'll assuming that for 1 you want to compose the behaviors into a prototype and that for 2 ... Sure we can, using way less than ES5, because we already do all of this hackery. And obviously a good definition of object cloning would be needed for Object.extend() and i... You lost me here. I should have objected to the requirement of a object cloning definition I guess. The particular variant of Object.extend() I use does not overwrite the LHS. It creates a new object, copies the LHS into it, then the RHS, then returns it. So the LHS can be a literal, for example to override some functions in the RHS. I think of it as a function representing binary operator. (Other versions extend() do other things, exactly why a standard would be good, but leave that for now). Now let's invent Object.make(protoLink, props) (or createSimple()...). Let's cause make() to give the same result as | for any pair of values valid for |. Now when props is an object expression, what is the result of Object.make(protoLink, props)? I would want var a1 = Object.make(Object.prototype, a) to be the same structure as var a2 = Object.extend({}, a); This is what I meant by obviously a good definition ... would be needed for extend and it would answer you second objection: whatever rules apply to the RHS in extend() should apply to the RHS in make(). And of course I would like this to be true for | as well. jjb ___ 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: Exemplar forms (was Your search - | - did not match any documents)
To expand on inheritance operator, I would treat es:h classes as declarative sugar for exemplars. Therefore it would make sense to have the extends keyword work on exemplars. We could use oExemplar extends fExemplar and have that make inheritance work as expected On Oct 14, 2011 8:38 AM, Jake Verbaten rayn...@gmail.com wrote: I agree having two types of examplers is sensible. For examples sake let fExemplar be an exemplar constructed with new Function and les oExemplar be the other one. Now, I'm worried about magically making fExemplar | oExemplar work, would oExemplar have fExemplar or fExemplar.prototype in it's [[Prototype]]? How do I tell the prototype of operator to treat fExemplar as a function and not an exemplar. same issues apply to oExemplar | fExemplar. If you do any magic to make inheritance work across exemplar types then I would need a way to tell the prototype of operator that they are just objects functions, not exemplars. however we can already make the two work together like such fExemplar.prototype | oExemplar and var sub = oExemplar.constructor | fExemplar sub.prototype = Object.create(oExemplar); sub.prototype.constructor = fExemplar The fact that the latter is verbose and a pain doesnt matter, because thats old style exemplars inheriting from new style exemplars. However having new style exemplars in inheriting from old style exemplars is less painful. Yes we have the issue of the exemplars not being equal but I dont want you to add magic to prototype of to fix that. However it is reasonable to suggest a new operator for exemplar inheritance that does do magic [snip] I want to compose objects:var result = cookUpTheBehavior(goodies, s... ___ 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: JsDoc based type guards
Why have this be part of the language? You can write code by contract libraries (I have one : https://github.com/Raynos/contract ). And you can write a javascript to javascript compiler that parses jsDoc comments and generates code that interacts with a code by contract library automatically. Yes there would be value in having such a compiler but building it into the language is overkill. Not to mention that jsDoc is not a good thing to standardize as it's a port from javaDoc. If we were to do this we should use something designed for javascript. On Fri, Oct 14, 2011 at 1:23 PM, Peter Dekkers pe...@jbaron.com wrote: All, I'm new on this list, so please forgive me if this subject has already been discussed in the past (I could't find a reference to that, but perhaps looked in the wrong places) . I saw that some form of type guards are on the agenda and was wondering if anyone looked at using JsDoc as a basis for that. I noticed that nowadays already some IDE's take advantage of JsDoc to assist the developer in code completion. And this same mechanism could be also used by the JavaScript VM. Running the VM in some kind of development mode, would generate some pre- and post-conditions assertions based on the JsDoc for that particular function. This would aid the developer during his tests. In normal production mode this additional code would not have be be generated. Much like some systems that support pre- and post-conditions (contracts) use to work. Additional benefit is that it can later be easily extended to more real pre- and post-conditions if ever required (hereby already my vote for at a notNull pre-and post-condition check ;) Some of the advantages I could see: 1. JsDoc becomes a standard part of Language. This has to be a good thing even without using it is as basis for stronger typing: a uniform way of documenting code. 2. No new language constructs are required. 3. Relatively simple to implement (I would assume). 4. Even more IDE's will start using this to assist developers with things like code completion. 5. Code that uses this mechanism can still run on older VM's that don't support this. They are just normal comments for those VM's. regards, Peter ___ 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: JsDoc based type guards
On Fri, Oct 14, 2011 at 2:44 PM, Peter Dekkers pe...@jbaron.com wrote: True of course that JS is a dynamic language by nature and it is not my suggestion/intention to make it more typed. I strongly believe the prototype part of JS is one of its main selling points. However a function expects certain type(s) of input parameters in order to work properly. My suggestion is just to formalize this a bit in order assist the developer how he should use that function. I guess it could also be done with just tooling. But as long as there is no standard way supported by both tools and libraries used, this won't fly. And I just thought of using the spec as a vehicle to achieve that. But perhaps too much ambition. The standard way to do this is to create the tool then use it. I think the entire proposal based on auto generating gaurds from documentation is not that useful. It forces you into a type of documentation. I want to choose my documentation, I dont want these choices forced onto me. However having a mechanism of syntax to deal with gaurding can be done. And there is a strawman on that. As brendan mentioned, there is more experimenting to do with that strawman. Just my 2 cents. regards, Peter On Fri, Oct 14, 2011 at 3:25 PM, Quildreen Motta quildr...@gmail.com wrote: 2011/10/14 Peter Dekkers pe...@jbaron.com Some of the advantages I could see: 1. JsDoc becomes a standard part of Language. This has to be a good thing even without using it is as basis for stronger typing: a uniform way of documenting code. I fail to see why One True Way for everything would be a good thing. It's true that this aids community grow, but the JS dev community is already too heterogeneous for that to work. See the endless discussions about Yay! Semicolons vs Yay! ASI, braces, indentation style, documentation style, object definition style, etc, etc, etc. 2. No new language constructs are required. That doesn't really make it an advantage. Unless the thing happens to be a de-facto standard, which I'd argue it isn't. I think my major pet-peeve against using strict types for contracts is: 1.) JS is not a statically typed language, it's an overtly dynamic language with prototypical OO. Using it as the former -- contracts as a way of enforcing is-a relationships -- is just ditching the whole language already. For this to really work, we'd need ways to define abstract types, interfaces, etc, etc, etc. Otherwise it's just bothersome with no added benefits. 2.) What you proposed is better delegated to being supported by tooling alone, as Jake mentioned. ___ 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: JsDoc based type guards
On Fri, Oct 14, 2011 at 2:59 PM, Quildreen Motta quildr...@gmail.comwrote: 2011/10/14 Brendan Eich bren...@mozilla.com On Oct 14, 2011, at 9:25 AM, Quildreen Motta wrote: I think my major pet-peeve against using strict types for contracts is: 1.) JS is not a statically typed language, it's an overtly dynamic language with prototypical OO. Using it as the former -- contracts Contracts are not necessarily static. In many languages they are dynamic. The disnetdev.com/contracts.coffee/ work is a case in point. That's true. We've discussed contracts.coffee in the guards thread before too -- whose syntax I'm particularly keen to, only not in JS. I wasn't saying that contracts must be about static typing though, but that I got the impression that his post was hinting at using a is-a relationship to define contracts for certain functions. Nevertheless, guards are a strawman because having a single, extensible syntax for contracts, runtime checks, etc., could be useful to enough of the diverse JS community that standardization is worth the costs. We need more experience with this proposal, so I encourage people to implement it with a transpiler and experiment. Yes, guards are an interesting addition to the language. Not only for type safety (would we also be able to get multiple dispatch on type pattern matching then?), but for documentation. I personally like the optional typing in Dart, even though I'm a static-typing-hater (and the devs have already said they won't support type inference directly in the language), they're valuable as code intention annotations. This is a very useful construct, I find that not having some kind of annotating on my function parameters makes it hard to read (isolated) code. I've personally started using jsDoc style comments to indicate type which is an ugly solution to this issue. I don't actually want to know the type as much as I want to know what [[Prototype]]'s I expect the parameters to have /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: Grawlix
I would like to argue the other side. For my coffeescript vs javascript is big enough to be happy. I am happy writing javascript and coffeescript irritates me to no end. On Fri, Oct 14, 2011 at 5:50 PM, Jorge jo...@jorgechamorro.com wrote: On 13/10/2011, at 19:05, Russell Leggett wrote: Is coffeescript vs. javascript big enough to be the difference between being happy or not? I think that depends on the person, but based on its popularity, I would say for some people it is. Based on its popularity, instead of for some people it is, I would say for most people it isn't. (I see the glass almost empty). -- Jorge. ___ 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: Exemplar forms (was Your search - | - did not match any documents)
On Fri, Oct 14, 2011 at 5:54 PM, John J Barton johnjbar...@johnjbarton.comwrote: On Thu, Oct 13, 2011 at 4:14 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: Let me take a crack at tying to tie together all the pieces we have been talking about. Allen, I really appreciate your synthesis, thanks. I am able to follow some of it because of my recent Q/A with the group. I think many more people would be able to follow it if the approximate semantics of new features where readily accessible. Maybe just an parenthetical explanation and a link to the strawman page (these are pretty daunting however). I believe the following links may aid in explaining some of the content - ES:Harmony Object Literals syntaxhttp://wiki.ecmascript.org/doku.php?id=harmony:object_literals - Axel's prototypes as classes articlehttp://www.2ality.com/2011/06/prototypes-as-classes.html lots of interesting text elided This is a more complicated tory then simply having a traditional class model such as Dart is using. However, we have an existing language with existing featuures with a wide range of usages patterns so whatever we do with classes we still have to accommodate what currently exists in JS. We are never going to have as simple a story as a do-over language such as Dart. But I do think we can craft a understandable story where all the pieces fit together relatively nicely. I really like this perspective, with two caveats: 1) To achieve the goal of Keep the language pleasant for casual developers., the correspondence between JS and traditional class models needs to be real, clear, and communicated well. Points of disconnect need to be ironed out. The danger of saying class and meaning something different are great but the dangers of saying Grawlix include no one caring about the meaning. 2) Your proposal is dominated by declarative syntax for objects, in contrast to practice which uses functions to construct objects. Of course it is possible that your new features would obsolete that practice, but I doubt it. By design the declarative syntax creates limits on objects that are simple to overcome with direct manipulation. I believe the use of declarative syntax is to get semantics across in a terse well specified manner. All of his declarative syntax has existing alternatives available we can use currently using methods. I don't think any of the declarative syntax has limits. jjb ___ 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: Exemplar forms (was Your search - | - did not match any documents)
One thing that worries me about the fsubo example is that oExemplar.constructor.prototype does not exist. How is that circular relation ship between .constructor and .prototype magically fixed? the other issue of fixing | for oExemplar | fExemplar (and vica versa) is does it break oObject | fExemplar, where oObject looks like an exemplar but isnt used as one. If you can make it just work without leaking then that would be great On Oct 14, 2011 7:09 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: On Oct 14, 2011, at 12:38 AM, Jake Verbaten wrote: I agree having two types of examplers is sensi... We've already started down this path in the | proposal where it treats: var subclass = Function | {prototype: sup | {/*methods*/} } | function() {/*...*/}; differently from: var protoExtendedFunction = Function.prototype | {/*methods*/} | function() {/*...*/} The subclass expression overrides the [[Prototype]] of both the subclass and subclass.prototype object. The other expression just overrides the [[Prototype]] of the function object and protoextendedFunction.prototype still have Object.prototype as its [[Prototype]] however we can already make the two work together like such fExemplar.prototype | oExemplar... var oSubf = fExemplar.prototype | { /*an oExemplar }; var fSubo = oExemplar.constructor | function () {/* a fExempar */}; is all that is needed to do the cross-over without any additional changes to |. The reason I mentioned the possibility of extending the current definition to make the explicit property qualification unnecessary is that in past discussions about mixing prototypal and class inheritance patterns there were concerns raised about the verbosity of having to say .prototype and .constructor. There is also a issue of wanting to be able to to do exemplar refinement without having to know if your are dealing a fExemplar or a oExemplar. Consider, a function such as: function addMyDebugMethods(exmplr) { return exmplr | {/* a bunch of methods */}; } You might like to be able to call it with both a fExemplar and oExemplar. I don't know if I really like pushing that far. It might be better to keep it simpler. But I think it is plausible that we could make this work. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Your search - | - did not match any documents
Whilst mentioning Object.createSimple, is there any plan for having matching functions for all this declaritive syntax? On Oct 13, 2011 8:17 AM, Jay Skeer j...@seanet.com wrote: ** On 10/12/2011 07:57 PM, John J Barton wrote: On Wed, Oct 12, 2011 at 5:52 PM, Allen Wirfs-Brock ... I agree, and the current Object.create should be Object.createFromPropertyDescriptors. But I could settle for newHeir or makeHeir. It suggests pronouncing it as prototype of. However, in most conversations I've been in we'v... I think of it as the (make/new) heir operator, and read that code nObj gets p's (new) heir the object with name 'foo' Array.create=function(proto,props) {return Object.defineProperties(proto | [ ], props)};... proto's new heir the empty array let subclass = superclass | function () {}; 'superclass overwritesThePrototypeIn an ano... let subclass be superclass' heir, an empty function. Jay ___ 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 subclassing and class declarations
This expresses an issue I have as well. the es:harmony proposal for classes just vaguely states it desugars into es5 things. We may need more clarification on exactly what it desugars to and how you can interact with a class object outside the declarative class expressions. On Oct 13, 2011 1:03 AM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: Alex, Erik, and I had a twitter conversation that eventually ran into the inevitable limit of effective communications using 140 character messages. This seems like a better place to capture and discuss the issues... The conversation started about the new DOM API that Dart is proposing and my question of why a new language is need to prototype such an interface. Why not just develop it in JavaScript. Erik mentioned that Proxies are needed and I replied that experimental implementations are available. Alex also mentioned that a use strict for the DOM is needed, but we didn't follow up on that. I'd like to know more about what that meant. Finally Alex said that he needs extensible Array types and said that the committee hasn't moved quickly on that . A subsequent message clarified that we was talking about subclassing Array. I said that | supports array subclassing (in fact, this was the original use case that gave rise to |) and Alex asked to be reminded how that would work and what about the length property. I responded: function createArraySubclass(proto, ...values) { return proto | [...values]; } If I'd had more characters I would have said that this creates a new object whose [[Prototype]] is proto and that the object has all the special characteristics of an array object. In particular Object.isArray will report true for it and the object has the special behavior of automatically updating the length property when elements are added past the end. It really is an array object, just one with a different [[Prototype]]. If you want it to also inherit from Array prototype you can define proto such as: var proto = Array.prototype | {/* additional subclass methods */}; Alex respond that new and instance of didn't work. (using new to create DOM nodes is one of the characteristics of the Dart DOM design). It took me three tries to get all the typos out, but I showed how new could be made to work: var SubArray = Array | function(...values) { return Object.getPrototypeOf(this) | [...values]; } /* add subclass methods */ SubArray.prototype.method1 = function() {...}; SubArray.prototype.method2 = function() {...}; /*or stache it: SubArray.prototoype.{method1() {..}, method2() {}}; */ then you can say: var s = new SubArray(1,2,3); console.log(s.length); //3 s[3] = 4; console.log(s.length); //4 console.log(Object.isArray(s)); //true console.log(s instanceof SubArray); // true console.log(s instanceof Array); //true Alex responded that the proposed class syntax class NodeList extends Array { ... } would also do the trick. I respond does class extend as proposed, propagate over-ridden [[internal methods]]? Don't think so? Alex that I was being class syntax hostile...Why the hate? I plead 140-char terseness. However, as I then pointed out, this is one of my issues with the class proposals. They have never been completed to the level of specifying how things like subclassing array should be handled. Alex apparently thought that class NodeList extends Array { } would automatically mean that NodeList instances would have full array instance semantics. I don't see how that would work. Would class ExtendedNodeList extends NodeList { ...} also result in a class whose instances had array instance semantics? How about in function makeClass(sup) { class newClass extends sup {...}; return newClass }; var c1 = makeClass(Array); var c2 = makeClass(c1); var c3 = makeClass(RegExp); I just don't see how the class declaration would know when it did or didn't have to create special instance objects. On a related matter, would you define a class whose instances are Proxy instances. The most recent discussions I followed seem to preclude using the trick I used above for arrays, something like: class P extends Object{ constructor () { return Proxy.create(myHandler,Object.getPrototypeOf(this)); } } because they disallow explicit returns from within constructors. Even if this was allowed what would happen for class Q extends P {...} Is there anyway to subclass a proxy-based class and automatically get the proxy based behavior in the subclass instances? We pretty much concluded with Alex asserting that the class declarations would provide a place to hang whatever (language design) hacks are needed to resolved such issues. And I asserted that I was more interested in making sure we had the primitive in the language that could be sugared (by library designers into these sorts of abstractions). Nothing new in that basic disagreement about approach. Something we didn't get into, was the issue of how much of existing
Re: Grawlix
As for shooting down the useful ness of - I personally find that one line functions are ugly. So: someObject.method = function () { doSomething(...); } is ugly because it doesn't follow my `{ \n` convention for readability and code organization. However I'd be happy to make an exception in my _style guide_ for someObject.method = () - { doSomething(...); } My reason for wanting - or some other short hand is to allow an exception in my javascript style guide for one line functions with the understanding that javascript authors don't abuse - to make unreadable code. Generally it's not about function being a long keyword, but about allowing a shorthand for the function keyword that makes one line functions more readable On Thu, Oct 13, 2011 at 10:32 AM, Joe Developer joe.d.develo...@gmail.comwrote: On Thu, Oct 13, 2011 at 11:18 AM, Juan Ignacio Dopazo dopazo.j...@gmail.com wrote: On Thu, Oct 13, 2011 at 12:23 AM, Joe Developer joe.d.develo...@gmail.com wrote: I was very close to mentioning in my response to Brendan that the first thing that came to mind regarding deep nesting and closure reliance was the context of exactly 'JS as a target for other languages' - but I was concerned that it could serve as an unnecessary distraction. The particular example of legibility of Monadic parsers ( or indeed parsers as a whole ) doesn't strike me as particularly important in the relative scheme of things - on one hand because it is a relatively rare use case ( to put it mildly ) - on the other, because I imagine that they tend to themselves to be best suited as artifacts of code generation ( and this would hold true irrespective of nesting concerns alone ) - generated code would likely only hold interest in educational and debugging contexts of the parsers - situations where proficiency / attention-span is either a desired outcome or already acquired. I have greater sympathy with the Promises use case - I tend to prefer events myself, which I regard as allowing greater flexibility - with the trade-off of less explicit conventions to be followed. Event constructs could be abused to be overly reliant on closures, but I generally find little reason to - prior art endows us with a rich pattern library. I chose that example because it stayed with me because of how interesting it is and because it was brought up in es-discuss sometime ago. *Obviously *writing parsers has nothing to do with more common usages for JavaScript like UI development. The point was that there are some cases in which the verbosity of function gets in the way. That one is particularly noisy visually. Still, even ignoring callback nesting, I love the prospect of arrow functions, specially for doing operations on arrays. I find array.filter((x) - !!x).map((x) - x * x) a lot easier to read an understand than array.filter(function(x) { return !!x }).map(function(x) { return x * x }); Juan Whereas, in many contexts, I would much prefer ( assuming that there weren't crossbrowser concerns, and that I actually found this particular functionality attractive ): /** * Processes an array of values, attempting to square truthy items. * Note that item values of 0 will be excluded from the returned set and non numeric but truthy entities will yield NaN * @param {array} arr Array of items to attempt square for truthy values * @return {array} Resultant array from attempts at squaring truthy items in passed array. * @testParam arr = [not ok, -2, 3 ,4, 0, 1] * @testReturn [NaN, 4, 9, 16, 1] */ var arraySquared = function (arr) { var result = []; arr arr.forEach arr.forEach( function( item ){ !!item result.push(item * item);}); return result}; And if I wanted to be edgy and sacrifice the element of least surprise for convenience I could then do something lame : Array.prototype._square = arraySquared; Array.prototype.square = function(){return this._square(this)}; For: [not ok, -2, 3 ,4, 0, 1].square(); Truthfully the - arrow construct is one that I have an aversion to which borders ( I'll admit ) on the irrational, while it is 'pretty' and serves the aesthetic focus of coffeescript well, I have a hard time seeing the inclusion of such a construct in javascript as anything but pandering. If anyone is seriously writing production code where 'function' is meaningful percentage of source then I would suggest that it is indicative of fundamental problems with their approach rather than the language itself. I would probably feel comfortable arguing that language designers enabling that kind of behavior are ultimately doing users a disservice. Even accepting that function constitutes a significant percentage of words typed in best practice apps by the intended audience and hence could do with a shorthand alternative - which I will assume plays a part in motivations for supporting the - construct - this particular key combo seems to require a wider range of
Re: Your search - | - did not match any documents
Could the problem of mutating the [[Prototype]] not be solved by returning a new object with the [[Prototype]] set as the LHS and having the same [[Class]] and own properties as the RHS. I would change the semantics slightly. The only forseeable issue is how to handle closures. On Thu, Oct 13, 2011 at 5:08 PM, Brendan Eich bren...@mozilla.com wrote: On Oct 13, 2011, at 3:59 AM, Jake Verbaten wrote: Whilst mentioning Object.createSimple, is there any plan for having matching functions for all this declaritive syntax? We do not want functions that mutate the [[Prototype]] internal property of existing objects. See https://mail.mozilla.org/pipermail/es-discuss/2011-May/014387.html Quote (with correction, s/can/cannot/): Another difference from the function approach is that the function can* not* assume it is being passed a new object or even any object of the kind it is expect. The | ooperator is syntactically required in the current proposal to have a literal form as its right operand so both implementations and human code readers can determine by examination what [[Class]] of object is being created. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Harmony transpilers
One of the reasons traceur is not suitable is that it's a product of google and thus not neutral. I've actually asked traceur whether they intent to become a full es harmony compliant transpiler but there was no response. And another reason would be that it currently implements some strawmans that conflict with harmony proposals. For example it's class mechanism is not loyal to the _current_ es harmony proposal, another example would be traceur generators not using the `function*` notation. On Tue, Oct 11, 2011 at 4:42 PM, John J Barton johnjbar...@johnjbarton.comwrote: On Tue, Oct 11, 2011 at 6:41 AM, Juan Ignacio Dopazo dopazo.j...@gmail.com wrote: Hi! Is there anyone working on a Harmony transpiler besides Traceur? I'd like to understand why Traceur is not suitable. As far as I understand it was written to study new directions in JS. jjb It'd be really useful to have a transpiler that justs desugars (what's possible to desugar) without using a library like Closure, the way CoffeeScript is working nowadays. Thanks, Juan ___ 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: Harmony transpilers
On Tue, Oct 11, 2011 at 7:40 PM, John J Barton johnjbar...@johnjbarton.comwrote: On Tue, Oct 11, 2011 at 11:14 AM, Brendan Eich bren...@mozilla.comwrote: On Oct 11, 2011, at 1:47 PM, John J Barton wrote: On Tue, Oct 11, 2011 at 10:08 AM, Brendan Eich bren...@mozilla.comwrote: On Oct 11, 2011, at 12:49 PM, John J Barton wrote: We don't know what the standard will be so we need some why to try out different features. That's not how the committee has worked since 2008, and even before then (pre-Harmony), with a split committee, we still had two groups working on consensus by drafting proposals and prototyping them. The way we try to work is to propose before implementing, including prototype features. Individual vendors don't deviate from proposals unilaterally and silently. If old proposals were implemented, and then the proposals changed, we may have some work to do adjusting implementations (certainly true of SpiderMonkey, and we will do it). But we do not go off on our own, as individual vendors, and try out features never proposed on the wiki. You're making something out of nothing. Somehow I suspect the shoe would be on the other foot if other vendors did likewise. But I'm tired of arguing in favor of keeping consensus. If it's not important, let's all go off and run our own experiments and see what happens. Biggest company wins, best two out of three in case of a order-of-magnitude market cap tie :-P. That will be fun. If you have a beef with how Google works with the committee, then contact a Google rep on the committee and complain to them. I already have, but that's not the topic here: you just wrote We don't know what the standard will be so we need some why to try out different features (cited above) and I wrote back arguing with you, not with anyone else. But don't paint the Traceur project as some weird plot to derail your work. I never said anything like that (weird plot -- come on!). I don't know why Traceur was developed the way it was, and then abandoned (I have some theories, but really, who cares?). Maybe it's someone else's turn to maintain Traceur, and Google has done its fair share. The problem is no one else knows the code and Jake said he got no response when he asked (but maybe he asked in the wrong channel or something). It's hard for others to pick up where things left off. I have quite a lot of first hand experience in picking up where things left off. No question it's hard, but you may get further by building on Traceur rather than starting over. It's just like a thousand other open source projects, a risky labor of love, a gift to the community of engineers. There is a lot of abandon-ware in open source, but that's a very low bar to meet. Well we don't have a Mark and Tom for Traceur. We just have some great source code. If anyone here wants to try to match Traceur up to Ecma consensus, please step up. So you, another Googler, exhort anyone, or Jake, to fix it and step up (but thanks for the please the second time :-/). I think it's fair to ask why anyone would do that, instead of choosing to work on other projects that seem to have active maintainers and open source communities going back to their genesis. Juan asked about Traceur. Advocates for other projects can reply if they like. Beyond this, I'm still picking a fight with your We don't know what the standard will be so we need some why to try out different features line, which you have not defended. But we can table that, or forget about it if you prefer. Well we don't know what the standard will be, that's just a fact. I happen to think that one needs to gain experience with language features by trying them out. I know you have a lot of experience so perhaps you don't need this step. I totally don't understand why you want to prevent Juan or Jake from trying out ideas related to JS. Something's wrong here. Jake cited specific concerns about Traceur and got a lecture to be grateful for it being open source, and to get to work fixing it. Is that really the best answer? I'm sorry if I came across as lecturing. I was taken aback by Jake's puzzling comments. I was just trying to being things back to reality. Traceur seems like a useful bit of code; it does not look like it will be maintained by the original authors. I was trying to encourage Jake and Juan to participate in taking it forward. +1 for encouraging participation, traceur may be good starting point. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: new Object
On Tue, Oct 11, 2011 at 8:11 PM, Axel Rauschmayer a...@rauschma.de wrote: *From: *Jake Verbaten rayn...@gmail.com *Subject: **new Object* *Date: *October 11, 2011 20:53:58 GMT+02:00 *To: *es-discuss es-discuss@mozilla.org is there any kind of proposal for syntax that is like: [...] var o = new proto(someValue); There has been a long discussion here, a few months ago. I’ve tried to summarize it here: http://www.2ality.com/2011/06/prototypes-as-classes.html The discussion ended with the following conclusion: - Pro: Yes, it would make things simpler. I would even argue that new-style classes being able to extend old-style classes would be enough. Furthermore, Python has successfully switched from one style of class to another one. - Contra: It would introduce a second protocol for inheritance and it would probably not find universal acceptance (some people find prototypes-as-classes more elegant, others like constructor functions). Furthermore, class literals practically look and feel like prototypes-as-classes, so that it’s a good enough solution for me. I dont think having both new Object and new Function in the language will cause any conflicts. It's the same as claiming that having both declarative class and new Function would cause confusion. class literals look the same but literal declaration are a right pain for any kind of meta programming. I can't take an existing object and turn it into a class without using eval. Axel -- Dr. Axel Rauschmayer a...@rauschma.de twitter.com/rauschma home: rauschma.de blog: 2ality.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: new Object
On Tue, Oct 11, 2011 at 8:58 PM, Axel Rauschmayer a...@rauschma.de wrote: I dont think having both new Object and new Function in the language will cause any conflicts. It's the same as claiming that having both declarative class and new Function would cause confusion. I wouldn’t mind either, but there *will* be two ways of doing things then (and that’s only a positive in the Perl world ;-). class literals look the same but literal declaration are a right pain for any kind of meta programming. I can't take an existing object and turn it into a class without using eval. Can you elaborate? Let's say I have object/class A and object/class B, I want a new class that is the union of A and B. (basically a mixin). There is no way of saying C = union(A,B) without using your standard functions and function.prototype. Where as with prototypes as classes it would be as simple as saying var C = Object.extend({}, A, B) (for some value of Object.extend) There are other examples of meta programming you cannot do with class declaration (without using eval. You can do anything with eval) Not to mention that es:h classes desugar to functions as classes rather then prototypes as classes (the latter doesn't exist yet). I'd just think implementing prototypes as classes has very little to loose as long as we dont go and fix all the existing objects (Object.prototype, Function.prototype, String.prototype, etc) It don’t think, it is that bad: Currently, you have a clear separation of concerns between the prototype and the constructor. However, these things are cumbersome: 1. Assembling a class 2. Subclassing 3. Constructor chaining, super method calls 4. Instanceof works with a name of an entity that only existed at instantiation time and is only weakly connected to an instance after that. Sect. 3 in [1] goes into more detail on how prototypes-as-classes would automatically make these things simpler. But in ECMAScript.next, class literals and super references fix 1-3 (and #4 is not that hard to live with). Superficially, things will be easy to handle. Under the hood, it’s a little more complicated, but it should help to concentrate on what role the constructor function plays and what role the prototype. [1] http://www.2ality.com/2011/06/prototypes-as-classes.html -- Dr. Axel Rauschmayer a...@rauschma.de twitter.com/rauschma home: rauschma.de blog: 2ality.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: new Object
Yes the prototypes are still there. But that means im just using es3 constructs. Es:harmony class literals only offer declarative sugar. I'm not proposing we change any of the existing Class.prototype.* code. I just propose that rather then throwing an error on new Object we make it work. This basically means we have three constructs for doing classes. we can even have declarative desugar to prototypes as classes, but thats optional. We basically give people more choice. I'd say it's worth implementing merely for having classes desugar to something with a more sensible 1-1 mapping. On Oct 11, 2011 9:22 PM, Axel Rauschmayer a...@rauschma.de wrote: class literals look the same but literal declaration are a right pain for any kind of meta progr... It will be more work, but the prototypes are still there and can be combined as you describe above. I don’t think you need eval(). Not to mention that es:h classes desugar to functions as classes rather then prototypes as class... The under-the-hood manipulations will be a bit more complicated, but the end result will always have the clear separation of responsibilities between constructor and prototype. I'd just think implementing prototypes as classes has very little to loose as long as we dont go... I guess that is the rub, reworking the standard types and all the code that uses Class.prototype.* instead of Class.*. It would have to be done to make things clean again and it would be too much work. -- Dr. Axel Rauschmayer a...@rauschma.de twitter.com/rauschma home: rauschma.de blog: 2ality.co... ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: new Object
Agreed. all of these can live side by side. There is no reason for new Object to compete declarative classe s. I merely caused confusion using the phrase prototypes as classes instead of new Object. as a side note whislt you mentioned .{ and | I would like to have programmatic, non declaritive alternatives for those as well. This might warrant another thread. On Oct 11, 2011 11:12 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: On Oct 11, 2011, at 1:46 PM, Jake Verbaten wrote: Yes the prototypes are still there. But that m... I agree that new object would be a useful feature for ES developers who want to create prototypal inheritance based abstractions. And along with super support in ES.next it really enables true self-style programming. However, I think that talking about such abstractions as classes creates confusions and a unwarranted sense of competition with class declarations. t isn't an either/or situations* *where we have to choose between primitive compositional operators or declarative syntax for the most common class abstraction patterns. ES objects, new object, new function, object literals, |, and .{ would provide a core set of primitives that can be used support of metaprogramming implementations of a wide spectrum of object abstraction and composition models. This is a good think and arguably an important aspect of using ES as the foundation language of the web platform. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: new Object
Point.zero = function () { return (new Point).{ x: 0, y: 0 }; } why are factory methods special? they are just methods. On Oct 11, 2011 11:26 PM, Axel Rauschmayer a...@rauschma.de wrote: I absolutely love it for its conceptual beauty, but the primary goal should be to establish a single dominant way of doing inheritance in JavaScript. One feature that doesn’t yet fit into my pure OO universe are factory functions/methods (I used frequently used factory methods in Java): 1. They give better names to constructors. 2. They allow one to return an instance of a subclass. Example of #1: new Point.zero() Example of #2: Expression.parse() How would you add that to JavaScript? On Oct 12, 2011, at 0:12 , Allen Wirfs-Brock wrote: On Oct 11, 2011, at 1:46 PM, Jake Verbate... -- Dr. Axel Rauschmayer a...@rauschma.de twitter.com/rauschma home: rauschma.de blog: 2ality.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: new Object
As for expression.parse, any constructor or initializer is still a function therefore it can return an object thats not this. This would be a good usecase for overwriting the [[Prototype]] with a new value. I dont know what sugar or syntax other languages with factory methods offer which makes the ordeal significantly more elegant. On Oct 11, 2011 11:38 PM, Axel Rauschmayer a...@rauschma.de wrote: If they are just a different way of initializing, then I love Smalltalk’s approach of separating instantiation and initialization. E.g. new Point.zero() would actually mean (note: in normal JS, I always write parens after a new-invoked function, but here it works well) (new Point).zero() (new Point) just creates an empty instance. Several initialization methods set them up correctly. What is missing from this approach is how to encapsulate the use of a subclass (as in Expression.parse which might return an instance of any subclass of Expression, depending on what is parsed – a literal, a binary operator, etc.). But maybe that should just be a function, e.g. parseExpression(). On Oct 12, 2011, at 0:29 , Jake Verbaten wrote: Point.zero = function () { return (new Poi... ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: new Object
So basically your saying that the only function that can alter an object before its frozen is the constructor, thats why we need multiple constructors? You'll have to subclass with another constructor or come up with syntax for multiple constructors. On Oct 11, 2011 11:46 PM, Kevin Reid kpr...@switchb.org wrote: On Oct 11, 2011, at 18:29, Jake Verbaten wrote: Point.zero = function () { return (new Point)... I agree with things should be just methods, but this particular pattern doesn't work for always-frozen types. -- Kevin Reid http://switchb.org/kpreid/ ___ 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: traits feedback
Object.create does indeed require propertydescriptors as the second argument. This is the easiest way to send meta-data like read-only. However it's verbose and the defaults are restrictive. I've written a small library (github.com/Raynos/pd) to make it less verbose, you might find it useful. On Oct 5, 2011 11:59 PM, John J Barton johnjbar...@johnjbarton.com wrote: On Tue, Oct 4, 2011 at 8:56 PM, John J Barton johnjbar...@johnjbarton.com wrote: In trying to ... Ok that was a quick experiment. I completely misunderstood Object.create(). I imagined that Object.create(a,b) returned an object with the properties of b and a __proto__ of a. Unfortunately the second argument is some kind of meta object. So to get {p:42} you have to write { p: { value: 42, writable: true, enumerable: true, configurable: true } }. Oy vey. jjb ___ 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
Function.create
There is no standardized way to create a new function with a prototype which is not Function.prototype. I propose Function.create /* Creates a new function whose prototype is proto. The function body is the same as the function fbody. The hash of propertydescriptors props is passed to defineproperties just like Object.create does. */ Function.create = (function() { var functionBody = function _getFunctionBody(f) { return f.toString().replace(/.+\{/, ).replace(/\}$/, ); }; var letters = abcdefghijklmnopqrstuvwxyz.split(); return function _create(proto, fbody, props) { var parameters = letters.slice(0, fbody.length); parameters.push(functionBody(fbody)); var f = Function.apply(this, parameters); f.__proto__ = proto; Object.defineProperties(f, props); return f; }; })(); This is the same as Object.create except the second parameter is a function. It will create a new function whose function body is the same as the function passed in. I don't believe this is possible to do in ES5 without __proto__ jsfiddle showing an example. http://jsfiddle.net/8CrqR/ Related stackoverflow questionhttp://stackoverflow.com/questions/7539148/how-do-i-inherit-functions ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Function.create
On Sat, Sep 24, 2011 at 5:03 PM, David Bruant david.bru...@labri.fr wrote: - Show quoted text - I defiantly like this `|` operator. I would happily have this instead. I'm a big fan of the proto operator proposal, however, as raised previously this operator relies on the object being created to have an intialisation syntax. This prevents, for instance, Date objects to have a custom prototype with this method. I am not very familiar with it yet, but I think that if they ever came to life, ParallelArrays [2] would suffer from the same problem. By the way, could someone add this concern as a note (open issue or limitation or something like this) in the proto operator page, please? I don't understand the limitation for `Date`. var d = proto | new Date(); That would appear to just work for me. Of course it would be sensible that proto has Date.prototype somewhere in the chain One even more generic way which would work even for objects that have no initialization syntax would to standardize one of [3] or [4]. Is there a wiki page mentionning these two functions somewhere? If not, may it be added and linked in some way to the proto operator? Personally I would be tempted to say that making mutating the prototype chain of an object after creating leads to black magic and abuse. David [1] http://wiki.ecmascript.org/doku.php?id=harmony:proto_operator [2] https://github.com/RiverTrail/RiverTrail/blob/15ae7f6f77d9d2842d9d75458017efd9fe0fbee7/jslib/ParallelArray.js#L29 [3] https://mail.mozilla.org/pipermail/es-discuss/2011-March/013141.html [4] https://mail.mozilla.org/pipermail/es-discuss/2011-March/013154.html ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Using function.prototype.bind without breaking function.prototype.apply
var f = function() { return this; } var g = f.bind(???); g.apply({ foo: bar }).foo // expect bar Function.prototype.bind set's the thisArg to a certain value. Is there any way to leave it flexible to be overwritten using `.call` and `.apply` later on? Is there any ES:Harmony/strawman proposal for this? If there is not I propose using `undefined` to tell Function.prototype.bind to leave thisArg flexible. The use case would be using .bind to curry parameters without effecting this. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss