Support for basic linear algebra on Array's

Jussi Kalliokoski jussi.kalliokoski at gmail.com
Mon Nov 19 01:55:31 PST 2012


I think it's a good time for me to point out the DSP API [1] again, which
is designed for fast vector math. There's already a partial node.js
implementation [2] by me and Jens Nockert is working on a SpiderMonkey
implementation, which is more complete atm.

Cheers,
Jussi

[1] http://people.opera.com/mage/dspapi/
[2] https://github.com/jussi-kalliokoski/node-dsp

On Mon, Nov 19, 2012 at 11:15 AM, Alex Russell <alex at dojotoolkit.org> wrote:

> 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 <brendan at mozilla.com> wrote:
>
> > Oliver Hunt wrote:
> >> On Nov 18, 2012, at 6:17 PM, Matt Calhoun<calhoun137 at gmail.com>  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
> >>> es-discuss at mozilla.org
> >>> https://mail.mozilla.org/listinfo/es-discuss
> >>
> >> _______________________________________________
> >> es-discuss mailing list
> >> es-discuss at mozilla.org
> >> https://mail.mozilla.org/listinfo/es-discuss
> >>
> > _______________________________________________
> > es-discuss mailing list
> > es-discuss at mozilla.org
> > https://mail.mozilla.org/listinfo/es-discuss
>
> --
> Alex Russell
> slightlyoff at google.com
> slightlyoff at chromium.org
> alex at dojotoolkit.org BE03 E88D EABB 2116 CC49 8259 CF78 E242 59C3 9723
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20121119/54ac9830/attachment-0001.html>


More information about the es-discuss mailing list