On Wed, Mar 19, 2014 at 2:24 PM, Nathaniel Smith <njs@pobox.com> wrote:
On Tue, Mar 18, 2014 at 9:14 AM, Robert Kern <robert.kern@gmail.com> wrote:
> On Tue, Mar 18, 2014 at 12:54 AM, Nathaniel Smith <njs@pobox.com> wrote:
>> On Sat, Mar 15, 2014 at 6:28 PM, Nathaniel Smith <njs@pobox.com> wrote:
>>> Mathematica: instead of having an associativity, a @ b @ c gets
>>> converted into mdot([a, b, c])
>> So, I've been thinking about this (thanks to @rfateman for pointing it
>> out), and wondering if Mathematica's approach is worth following up
>> more. (It would need to make it past python-dev, of course, but worst
>> case is just that they say no and we're back where we are now, so we
>> might as well think it through.)
> I predict with near-certainty that this will be rejected,

I guess that's what everyone thought about @ too? ;-)

> but that
> doesn't prevent it from derailing the discussion. This proposal is
> unlike anything else in Python. Chained comparisons are *not* similar
> to this proposal. The chaining only happens at the syntax level, not
> the semantics. `a < b < c` gets compiled down to `a.__lt__(b) and
> b.__lt__(c)`, not `do_comparison([a, b, c], [lt, lt])`.

Yes, the syntax is the same as chained comparisons, and the dispatch
is a generalization of regular operators. It is unusual; OTOH, @ is
unusual in that no other operators in Python have the property that
evaluating in the wrong order can cost you seconds of time and
gigabytes of memory. Perhaps.

> We have approval for a binary @ operator. Take the win.

We have approval, and we have a request: that we figure out how @
should work in detail to be most useful to us. Maybe that's this
proposal; maybe not. Ultimately rejected-or-not-rejected comes down to
how strong the arguments for something are. And while we can make some
guesses about that, it's impossible to know how strong an argument
will be until one sits down and works it out. So I still would like to
hear what people think, even if it just ends in the conclusion that
it's a terrible idea ;-).

What happens if you have 5 @ in a row? 

My head hurts if I had to think about what would actually be going on.
and don't forget, the sparse matrix is stuck in the middle.

But I would be happy to have a optimizing multi_dot or chain_dot function when it feels safe enough.


As for arguments against the "grouping" semantics, I did think of one
another case where @ is not associative, though it's pretty weird:

In [9]: a = np.arange(16, dtype=np.int8).reshape((4, 4))

In [10]: np.dot(a, np.dot(a, a.astype(float)))
array([[  1680.,   1940.,   2200.,   2460.],
       [  4880.,   5620.,   6360.,   7100.],
       [  8080.,   9300.,  10520.,  11740.],
       [ 11280.,  12980.,  14680.,  16380.]])

In [12]: np.dot(np.dot(a, a), a.astype(float))
array([[ 1680.,  1940.,  2200.,  2460.],
       [-1264., -1548., -1832., -2116.],
       [ 1936.,  2132.,  2328.,  2524.],
       [-1008., -1100., -1192., -1284.]])

(What's happening is that we have int8 @ int8 @ float, so (int8 @
int8) @ float has overflows in the first computation, but int8 @ (int8
@ float) does all the computations in float, with no overflows.)

That's similar to my example before that mixes in some scalar *.

I thought of it as an argument for same-left



Nathaniel J. Smith
Postdoctoral researcher - Informatics - University of Edinburgh
NumPy-Discussion mailing list