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 Â+=Â [EMAIL PROTECTED]

?  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

Ã

Reply via email to