I like this as a rough solution. Assuming we get Array sub-typing done in a similar timeframe, it might all fold into a nice tidy package.
On Nov 19, 2012, at 3:08 AM, Brendan Eich <[email protected]> wrote: > Oliver Hunt wrote: >> On Nov 18, 2012, at 6:17 PM, Matt Calhoun<[email protected]> wrote: >> >>> I believe that having a concise notation for linear algebra is an important >>> feature of a programming language that can dramatically improve code >>> readability, and furthermore that linear algebra is a powerful tool that >>> has many applications in java script. I would like to make the following >>> two suggestions: >>> >>> 1. Extend the "+" operator to work on Array's of numbers (or strings). >>> >>> 2. Allow for scalar multiplication of Array's which contain only numbers. >>> >>> Although there are many problems with a simple linear algebraic solution >>> which arise in contexts where java script is a natural language of choice >>> (for example WebGL), there are no simple ways to express these solutions in >>> java script because the language itself creates a barrier to even basic >>> operations such as subtracting two vectors, in the sense that the amount of >>> writing it takes to express these operations obscures their mathematical >>> content. For more complicated linear algebraic work, the problem is quite >>> severe. >> >> Changing the behaviour of any of the basic operators on builtin/pre-existing >> types is essentially a non-starter. + already has sufficiently, errr, >> "sensible" behaviour to be widely used on arrays. Other operators don't >> really have any such "sensible" use cases, but changing their semantics on >> one kind of object vs. other kinds would be highly worrying. >> >> (2) would also be a non-starter i feel: JS implicitly converts to number in >> all other cases, and if we made operator behaviour dependent on content type >> (in a nominally untyped language) I suspect we would very rapidly end up in >> a world of semantic pain, and another WAT presentation. > > I think we could actually reduce the WAT effect in JS with *opt-in* operators > for value objects. This is on the Harmony agenda: > > http://wiki.ecmascript.org/doku.php?id=strawman:value_objects > http://wiki.ecmascript.org/doku.php?id=strawman:value_proxies > > I've implemented int64 and uint64 for SpiderMonkey, see > https://bugzilla.mozilla.org/show_bug.cgi?id=749786, where in the patch > there's a comment discussing how the operators for these new value-object > types work: > > /* > * Value objects specified by > * > * http://wiki.ecmascript.org/doku.php?id=strawman:value_objects > * > * define a subset of frozen objects distinguished by the JSCLASS_VALUE_OBJECT > * flag and given privileges by this prototype implementation. > * > * Value objects include int64 and uint64 instances and support the expected > * arithmetic operators: | ^ & == < <= << >> >>> + - * / %, boolean test, ~, > * unary - and unary +. > * > * != and ! are not overloadable to preserve identities including > * > * X ? A : B <=> !X ? B : A > * !(X && Y) <=> !X || !Y > * X != Y <=> !(X == Y) > * > * Similarly, > and >= are derived from < and <= as follows: > * > * A > B <=> B < A > * A >= B <=> B <= A > * > * We provide <= as well as < rather than derive A <= B from !(B < A) in order > * to allow the <= overloading to match == semantics. > * > * The strict equality operators, === and !==, cannot be overloaded, but they > * work on frozen-by-definition value objects via a structural recursive strict > * equality test, rather than by testing same-reference. Same-reference remains > * a fast-path optimization. > * > * Ecma TC39 has tended toward proposing double dispatch to implement binary > * operators. However, double dispatch has notable drawbacks: > * > * - Left-first asymmetry. > * - Exhaustive type enumeration in operator method bodies. > * - Consequent loss of compositionality (complex and rational cannot be > * composed to make ratplex without modifying source code or wrapping > * instances in proxies). > * > * So we eschew double dispatch for binary operator overloading in favor of a > * cacheable variation on multimethod dispatch that was first proposed in 2009 > * by Christian Plesner Hansen: > * > * https://mail.mozilla.org/pipermail/es-discuss/2009-June/009603.html > * > * Translating from that mail message: > * > * When executing the '+' operator in 'A + B' where A and B refer to value > * objects, do the following: > * > * 1. Get the value of property LOP_PLUS in A, call the result P > * 2. If P is not a list, throw a TypeError: no '+' operator > * 3. Get the value of property ROP_PLUS in B, call the result Q > * 4. If Q is not a list, throw a TypeError: no '+' operator > * 5. Intersect the lists P and Q, call the result R > * 6. If R is empty throw, a TypeError: no '+' operator > * 7. If R has more than one element, throw a TypeError: ambiguity > * 8. If R[0], call it F, is not a function, throw a TypeError > * 9. Evaluate F(A, B) and return the result > * > * Rather than use JS-observable identifiers to label operator handedness as > * in Christian's proposal ('this+', '+this'), we use SpecialId variants that > * cannot be named in-language or observed by proxies. > * > * To support operator overloading in-language, we need only provide an API > * similar to the one Christian proposed: > * > * function addPointAndNumber(a, b) { > * return new Point(a.x + b, a.y + b); > * } > * > * Function.defineOperator('+', addPointAndNumber, Point, Number); > * > * function addNumberAndPoint(a, b) { > * return new Point(a + b.x, a + b.y); > * } > * > * Function.defineOperator('+', addNumberAndPoint, Number, Point); > * > * function addPoints(a, b) { > * return new Point(a.x + b.x, a.y + b.y); > * } > * > * Function.defineOperator('+', addPoints, Point, Point); > */ > > > This is all experimental and not for ES6, but it does not increase the WAT > effects, quite the contrary. int64, uint64, decimal, bignum, complex, and > even vector and matrix value object types for linear algebra and graphics > applications need operators and literal syntax for usability. Requiring > method-based or functional APIs is just user-hostile and drives developers > back toward binary double. See > > http://www.jroller.com/cpurdy/entry/the_seven_habits_of_highly1 > > especially the first comment. > >> Also anytime i've seen someone propose * operating on arrays it rapidly >> becomes a flamewar between element-by-element multiplication and >> n-dimensional-dot-product. > > I agree that * or other operators should not be naively supported on arrays, > which are not value objects in any case. Any vector or matrix value object > would want sweet literal syntax, but it wouldn't be array literal syntax, > exactly. > > The use-cases want opt-in operators/literals via modules, with a principled > approach to avoiding adding support for * to arbitrary other code. Lexically > scoped operators, perhaps as hygienic macros a la a future sweetjs.org > approach (infix operator macros are on the agenda there, not yet supported), > is the way to go. > > Anyway, Matt's request is reasonable in my view, when phrased in terms of > well-scoped opt-in extensions rather than magic new-default behavior for > arrays. > > /be > >> >> ES6 provides comprehensions however that might make the world nicer for a >> lot of your use cases. >> >> --Oliver >> >>> _______________________________________________ >>> 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 >> > _______________________________________________ > es-discuss mailing list > [email protected] > https://mail.mozilla.org/listinfo/es-discuss -- Alex Russell [email protected] [email protected] [email protected] BE03 E88D EABB 2116 CC49 8259 CF78 E242 59C3 9723 _______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

