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 Ã