I meant "statically compiled" in the sense of AOT compiled, in the veins of C++, Java, TypeScript, etc.
On Wed, Aug 5, 2015, 14:04 Brendan Eich <[email protected]> wrote: > Missing reply text? Your message which you cited in full made it to the > list. > > BTW "statically compiled" doesn't make sense -- did you mean "statically > typed", or "with fully static name binding"? JS does lack those, > although strict mode gets close to fully static name binding (the global > object can still sprout new properties that may be referenced via free > variables). > > /be > > Isiah Meadows wrote: > > > > > > > > On Wed, Aug 5, 2015, 04:29 Isiah Meadows <[email protected] > > <mailto:[email protected]>> wrote: > > > > Good point. I did make most of the natives identity functions > > returning the object itself for most cases with the prolyfill, > > which engines should easily detect at run time and inline into > > nothingness. But I do see your point. As proposed, I know it's > > still incomplete in its core functionality (pattern matching on > > array literals would be a bit more interesting), but the other > > core problem is this: JavaScript isn't statically compiled. Nearly > > every language with patten matching is. It's much easier to > > optimize this into something decently performant in a static > > context (TypeScript as an example). > > > > > > On Wed, Aug 5, 2015, 04:19 Andreas Rossberg <[email protected] > > <mailto:[email protected]>> wrote: > > > > On 5 August 2015 at 09:27, Isiah Meadows <[email protected] > > <mailto:[email protected]>> wrote: > > > > Damnit...forgot to fix the subject. > > > > On Wed, Aug 5, 2015 at 3:20 AM, Isiah Meadows > > <[email protected] <mailto:[email protected]>> wrote: > > > > Wait...this got me thinking... The proposal itself > > doesn't bring along a lot of merits, but it seems like > > it could be a great stepping stone to a limited > > pattern matching syntax. This would probably be a > > little more justifiable IMHO than merely a custom > > destructuring syntax. Maybe something like this: > > > > > > I intentionally did not bring up pattern matching. That indeed > > is what views are usually wanted for. But then you need to be > > much more careful in designing a mechanism that avoids > > re-transforming the scrutinee for every tested case! Because > > that would be very costly. For that reason, I fear that the > > feature as proposed would interact badly with any future > > pattern matching mechanism, in the sense that it would > > encourage very costly usage that cannot be optimised. > > > > /Andreas > > > > > > > > ```js > > Type[Symbol.pattern] = (obj) => { > > return [obj.a, obj.b]; > > } > > > > const Other = { > > [Symbol.pattern]: obj => obj, > > } > > > > class None { > > static [Symbol.pattern](obj) { > > return obj > > } > > } > > > > // Pattern matching, signaled by `in` here > > switch (object) in { > > case Type([a, b]): return a + b > > case Other({a, b}): return a * b > > case None: return undefined // Special case, no > > identifier initialized > > } > > > > // Extensible destructuring, easy to implement with > > the pattern > > // matching > > let Type([a, b]) = object > > let Other({a, b}) = object > > ``` > > > > In the destructuring phase for both, I was thinking > > about the following semantics to assert the type, > > based on `typeof` and the prototype. This will help > > engines in optimizing this as well as some type safety > > for all of us. > > > > ```js > > function _checkProto(object, Type) { > > // Note: Type[Symbol.pattern] must be callable > > if (typeof Type[Symbol.pattern] !== 'function') > > throw new TypeError() > > if (typeof Type === 'function') { > > if (type === Array) { > > return Array.isArray(object) > > } else { > > return object instanceof Type > > } > > } else { > > return Object.prototype.isPrototypeOf.call(Type, > > object) > > } > > } > > > > function isInstance(object, Type) { > > switch (typeof object) { > > case 'object': return obj != null && > > _checkProto(object, Type) > > case 'function': return Type === Function > > case 'boolean': return Type === Boolean > > case 'number': return Type === Number > > case 'string': return Type === String > > case 'symbol': return Type === Symbol > > case 'undefined': return false > > } > > } > > ``` > > > > Finally, get the result and do a basic variable > > pattern assignment, LHS being the operand, and RHS > > calling `Type[Symbol.pattern]`. > > > > The `switch` statement example would (roughly) desugar > > to the following: > > > > ```js > > switch (true) { > > case isInstance(object, Type): > > let [a, b] = Type[Symbol.pattern](object) > > return a + b > > > > case isInstance(object, Other): > > let {a, b} = Other[Symbol.pattern](object) > > return a * b > > > > case isInstance(object, None): > > return undefined > > } > > ``` > > > > The destructuring examples would (roughly) desugar to > > this: > > > > ```js > > if (!isInstance(object, Type)) throw new TypeError() > > let [a, b] = Type[Symbol.pattern](object) > > if (!isInstance(object, Other)) throw new TypeError() > > let {a, b} = Other[Symbol.pattern](object) > > ``` > > > > The type assertions will help engines in optimizing > > this, and it'll also make this safer. It also just > > makes sense for pattern matching. > > > > As a side effect, you can get the value without > > destructuring (i.e. the literal result of > > `Symbol.pattern`) via this: > > > > ```js > > let Map(m) = someMap > > let m = Map[Symbol.pattern](someMap) > > ``` > > > > I, myself, came up with a Scala-inspired case class > > concept > > <https://gist.github.com/impinball/add0b0645ce74214f5aa> > > based on this, and used it to make try-catch handling > > a little more Promise-like, which I know quite a few > > TypeScript users would eat up in a hurry > > <https://github.com/Microsoft/TypeScript/issues/186> > > (particularly the sum type implementation). I also > > created a little toy Option/Maybe implementation > > <https://gist.github.com/impinball/4833dc420b60ad0aca73> > > using pattern matching to ease `null`/`undefined` > > handling. > > > > And also, check out my gist > > <https://gist.github.com/impinball/62ac17d8fa9a20b4d73d> > > for a proposed `Symbol.pattern` prolyfill for the > > primitive types. That would allow for things like this: > > > > ```js > > switch (list) in { > > case Array([a, b, c]): return doSomething(a, b, c) > > case Map({a, b, c}): return doSomethingElse(a, b, c) > > default: return addressBadType(list) > > } > > ``` > > > > > ---------- Forwarded message ---------- > > > From: Andreas Rossberg <[email protected] > > <mailto:[email protected]>> > > > To: "Samuel Hapák" <[email protected] > > <mailto:[email protected]>> > > > Cc: es-discuss <[email protected] > > <mailto:[email protected]>> > > > Date: Tue, 4 Aug 2015 14:26:45 +0200 > > > Subject: Re: Extensible destructuring proposal > > > On 31 July 2015 at 20:09, Samuel Hapák > > <[email protected] > > <mailto:[email protected]>> wrote: > > >> > > >> So, do you still have objections against this > > proposal? Could we summarize them? > > >> > > >> @Andreas, do you still think that there is category > > error involved? > > > > > > > > > If you want to overload existing object pattern > > syntax, then yes, definitely. I strongly disagree with > > that. It breaks regularity and substitutability (you > > cannot pass a map to where a generic object is expected). > > > > > > As for a more Scala-like variant with distinguished > > syntax, I'm fine with that semantically. But I still > > don't buy the specific motivation with maps. Can you > > give a practical example where you'd want to create a > > map (immutable or not) for something that is just a > > record of statically known shape? And explain _why_ > > you need to do that? Surely it can't be immutability, > > since objects can be frozen, too. > > > > > > To be clear, I wouldn't reject such a feature > > outright. In fact, in a language with abstract data > > types, "views", as they are sometimes called in > > literature, can be valuable. But they are also > > notorious for a high complexity cost vs minor > > convenience they typically provide. In particular, it > > is no longer to write > > > > > > let {a: x, b: y} = unMap(map) > > > > > > as you can today, then it would be to move the > > transformation to the pattern: > > > > > > let Map({a: x, b: y}) = map > > > > > > So I encourage you to come up with more convincing > > examples in the JavaScript context. Short of that, I'd > > argue that the complexity is not justified, at least > > for the time being. > > > > > > /Andreas > > > > > > -- > > Isiah Meadows > > > > > > > > > > -- > > Isiah Meadows > > > > _______________________________________________ > > es-discuss mailing list > > [email protected] > > https://mail.mozilla.org/listinfo/es-discuss >
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

