Front page | perl.perl6.language | Postings from January 2004

## Re: Semantics of vector operations

From:
Larry Wall
Date:
January 20, 2004 16:43
Subject:
Re: Semantics of vector operations
Message ID:
20040121004312.GA27628@wall.org
```On Tue, Jan 20, 2004 at 01:54:33AM -0700, Luke Palmer wrote:
: A thought occurred to me.  What should this return:
:
:     [1,2,3] »+« [4,5,6]
:
: At first glance, one might say [5,7,9].  But is that really the best
: way to go?  I'm beginning to think that it should be the same as
: whatever [1,2,3]+[4,5,6] is, hopefully an error.

Doing what you expect at first glance is also called "not violating
the principle of least surprise".

: Here's my reasoning.  Substitute \$a = [1,2,3] and \$b = [4,5,6].  Those
: are list I<references>, after all.  So now it becomes:
:
:     \$a »+« \$b
:
: That might just be okay, since they're both listrefs, and you shouldn't
: expect a vector on two scalars to do much besides dereference its
: arguments.  But now, instead of \$a, use the real list (1,2,3):
:
:     (1,2,3) »+« \$b
:
: That looks extremely different from before.  That looks like it's adding
: \$b to each of (1,2,3).

But the programmer probably knows whether \$b contains a list ref or
a scalar.  This is primarily a problem to the reader of the code.

And what if the programmer wants it to do the Right Thing regardless
of whether \$b is a scalar or a list?  I suspect that there are
mathematical operations that should generalize down to 0 dimensions,
not just 1 dimension...

: Not only that, but say you have:
:
:     \$x »+« \$y
:
: \$x is a number, and \$y is a listref.  Extrapolating from before, you'd
: think that this should add \$x to each of \$y's elements.  But this is
: starting to feel like run-time DWIMmery, which is almost always a Bad
: Idea (favoring syntactic DWIMmery).

Well, you can say that, but the whole notion of method dispatch is
based on the idea that run-time dwimmery is better than syntactic
dwimmery.  But see below for a syntactic proposal.

: So I'm going to argue that:
:
:     [1,2,3] »+« [4,5,6]
:
: either give an error because you can't add listrefs, or give a "useless
: use of vector operation on two scalars" error.  And if you want what
: we originally thought, use:
:
:     (1,2,3) »+« (4,5,6)
:     @\$a »+« @\$b
:     \$x »+« @\$y

On the other hand, it's possible that we should extend the visual metaphor
of »« and apply it asymmetrically when one of the arguments is expected to
be scalar.  That would mean that your last three lines would be written:

(1,2,3) »+« (4,5,6)
\$a »+« \$b
\$x +« \$y

What's more, a unary vector op would then just be

-« @bar

This also lets us use an array in its scalar sense for its length:

@foo »+ @bar

So to add the length of an array to each of its elements, you'd be
able to say:

@foo »+= @foo;

It might take some getting used to, but I kind of like this idea,
especially if you pronounce » and « as "each".  (Doubtless some
joker will propose that we pronounce them "leach" and "reach"...)
So

@foo »= 0;

unambiguously means "@foo each equals 0".  You can still say

@foo »=« 0;

but then you're relying on the dwimmery to realize that the thing
on the right is a scalar value.  So the difference between

@foo »= \$bar

and

@foo »=« \$bar

is that the second one has to look at \$bar at runtime to see if it
"does" the list thing, and if not, listify it.

Note that if we do take this approach, we'll have to require the
space after = in

@list = «a b c d e»;

Larry

```