Front page | perl.perl6.language |
Postings from January 2004
Re: Semantics of vector operations
Thread Previous
|
Thread Next
From:
Luke Palmer
Date:
January 21, 2004 02:05
Subject:
Re: Semantics of vector operations
Message ID:
20040121100449.GA10574@babylonia.flatirons.org
Warning: spacey, tangential semi-argument ahead.
Larry Wall writes:
> 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".
Touché.
> : 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...
Oh, right. I forgot that vector operators generalize based on the
dimension of their arguments. In that case, 0 dimensions is clearly a
valid generalization.
However, I'm not sure I want it to generalize... it gives me the same
heebie-jeebies as the Q::S-style junction semantics, but to a lesser
extent.
As a vague correlation, I've found infinite use in the [ @$list ] shallow
copy. I've never needed deep copy. I'm not sure I'd know what module
to look in if I did. Vector operators at the moment are doing "deep"
operations.
In order to really see what's best, though, I think some concrete
applications are in order. I'm a tensor algebra sort of guy, so let's
do some of that.
Inner product of matrix $A and vector $b:
map -> $i { reduce { $^a + $^b } $A[$i] »*« $b } 0..^$A
(You'll see the use of my very favorite operator above, ..^)
Inner product of matrix $A and matrix $B:
map -> $i {
map -> $j {
$A[$i][$j] * $B[$j][$i]
} 0..^$B
} 0..^$A
Hmm, vector operators really helped out there... :-)
Well, hmm, those examples didn't accomplish much. It's clear that
multidimensionality didn't make anything easier, but it didn't make
anything harder either.
Keep in mind that:
$A »*« $B
Is a mathematically useless operation for two matrices, save for a
slight use or two in image processing. At the moment, I can't think of
anything you could substitute for C<*> to make it useful.
In summary, I'm not sure what I'm arguing anymore. One way is going to
end up being better than the other, but I don't know which one that is.
%-)
> : 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;
I don't think this buys us anything. It makes it look less like » is a
meta-operator acting on += and more like »+= is an operator in and of
itself. Something I'd rather not do, but opinion-driven once again.
But does this really say anything more than:
@foo »+=« +@foo
? Even if @foo happens to be spelled with 50 characters?
> 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"...)
I wonder who that would be... :-p
> 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.
I think I see where this is going. After all,
@foo »= $bar
Is certainly cleaner than the current alternative:
@foo »=« $bar xx @foo
But you're right, it would take some getting used to, for sure.
> Note that if we do take this approach, we'll have to require the
> space after = in
>
> @list = «a b c d e»;
Meh. No problem.
Luke
à
Thread Previous
|
Thread Next