[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.
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). 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).
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
Luke
à
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
Perl 6 has already set the precedent of the presence or absence of
whitespace being syntactically important (as opposed to Python, where the
amount and type of whitespace is syntactically important). As such, I'd
have no problem with this.
=====
Jonathan "Dataweaver" Lang
__________________________________
Do you Yahoo!?
Yahoo! Hotjobs: Enter the "Signing Bonus" Sweepstakes
http://hotjobs.sweepstakes.yahoo.com/signingbonus
> -----Original Message-----
> From: Larry Wall [mailto:la...@wall.org]
> 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
If only from a syntax-highlighting point of view, this is a horrible
proposal. Make it die.
=Austin
How is this any worse than syntax-highlighting a full »« construct?
Incidently, it might make matters easier if you forbid whitespace between
the »« operator modifier and its operator. Indeed, you might want to look
into including a trait for operator declarations which allows you to
modify the importance of whitespace - something like:
sub circumfix:»« (&o is infix) is whitespace(forbidden) {...}
sub prefix:» (&o is postfix|infix) is whitespace(forbidden) {...}
sub postfix:« (&o is prefix|infix) is whitespace(forbidden) {...}
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.
%-)
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
à
This shouldn't be a problem. The whitespace rule changes I
believe should be avoided (Abigail does have a point there) is if
whitespace between composite constructs were to be disallowed. I
don't see required whitespace being a problem outside golf/obfu.
That said, I'm not sure how keen I am on the idea of "one-sided"
vector operators. It seems to me that this is too big a
semantic choice to make merely by omission of a single (and quite
dainty) character. I'd rather express this by forcing a context
on the operand. The precedent so far also seems to be a
rule-of-thumb that "I have to write more when I want to be
explicit".
--
Regards,
Aristotle
"If you can't laugh at yourself, you don't take life seriously enough."
This would be relatively straightforward for syntax highlighters,
I think. But Perl 6 will throw other curves at highlighters that
will be much more difficult to solve, such as the fact that any
C<use> potentially changes the subsequent syntax. Even an operator
declaration changes the subsequent syntax. Making things easy for
syntax highlighters is not a primary design goal for Perl 6--in this
Perl will remain the AntiLisp.
If the proposal dies, it'll be on semantic and/or psychological grounds.
(Not counting the psychological grounds of it being hard to get used to. :-)
Larry
But I would argue that it's the vectorization of the argument that
is special, and that's precisely why it should only be used on the
argument that is to be considered "plural". The underlying psychology
here is that most people assume that all these operators take scalar
(singular) arguments.
Now, a mathematician might assume otherwise, but said mathematician
will probably put "use vectorops" at the front and leave out all the
"dainty" characters from the get-go.
Larry
LW> This would be relatively straightforward for syntax highlighters,
LW> I think. But Perl 6 will throw other curves at highlighters that
LW> will be much more difficult to solve, such as the fact that any
LW> C<use> potentially changes the subsequent syntax. Even an operator
LW> declaration changes the subsequent syntax. Making things easy for
LW> syntax highlighters is not a primary design goal for Perl 6--in this
LW> Perl will remain the AntiLisp.
and don't forget that since p6 will use the <perl> grammar to parse
perl, that will be available to syntax highlighters. no more wacko
heuristics and broken colors (i don't use them anyway. i can parse code
just fine with b&w :) depending on what the <perl> grammar produces
there might be some extra processing needed.
as for use changing the subsequent syntax, run the grammar with a -c
like option so those modules will get loaded and affect the generated
syntax tree.
another benefit of using the perl rules is that when changes are made to
the <perl> grammar, all highlighter which use it will be automatically
upgraded. they may have to add stuff for things which have new 'syntax
categories'.
uri
--
Uri Guttman ------ u...@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
> -----Original Message-----
> From: Larry Wall [mailto:la...@wall.org]
Perhaps the right way to vectorize the arguments is to delimit them with
vectorization markers?
@a + >>$b<<
=Austin
>>>>>> "LW" == Larry Wall <la...@wall.org> writes:
>
> LW> This would be relatively straightforward for syntax highlighters,
> LW> I think. But Perl 6 will throw other curves at highlighters that
> LW> will be much more difficult to solve, such as the fact that any
> LW> C<use> potentially changes the subsequent syntax. Even an operator
> LW> declaration changes the subsequent syntax. Making things easy for
> LW> syntax highlighters is not a primary design goal for Perl 6--in this
> LW> Perl will remain the AntiLisp.
>
> and don't forget that since p6 will use the <perl> grammar to parse
> perl, that will be available to syntax highlighters. no more wacko
> heuristics and broken colors (i don't use them anyway. i can parse code
> just fine with b&w :) depending on what the <perl> grammar produces
> there might be some extra processing needed.
I think you're only going to get truly accurate syntax highlighting
for all Perl in an image based IDE implemented in Perl since such an
editor will always know what grammar rules are in scope for a given
chunk of code. And once you go to an image based IDE and have access
to the bytecode of the code you're writing there's all *sorts* of
interesting things you can do. And that's before one starts to imagine
attaching the IDE/debugger to a running process...
--
Beware the Perl 6 early morning joggers -- Allison Randal
or @a + @$b even!
--
Justice is when you get what you deserve.
Law is when you get what you pay for.
Good point; however, this means different way to think of the
vector ops than we had so far. Basically, we're moving from the
realm of vector ops to that of vectorized operands.
In light of this, I think Austin's proposal of marking the
operands as vectorized makes a lot of sense. It was an unexpected
that had me taken aback for a moment, but I like it more the more
I think about it. It *feels* right to emphasize vectorization as
something that happens to an operand, rather than something
that's a property of the operation.
$smalltalkometer++ ? :)
* A. Pagaltzis <paga...@gmx.de> [2004-01-22 03:55]:
> Good point; however, this means
a
> different way to think of the vector ops than we had so far.
> Basically, we're moving from the realm of vector ops to that of
> vectorized operands.
>
> In light of this, I think Austin's proposal of marking the
> operands as vectorized makes a lot of sense. It was an
> unexpected
twist
I think some people will want to think of it one way, while others
will want to think of it the other way. If that's the case, the
proper place to put the marker is between the operand and the operator.
You might argue that we should force people to think of it one way or
the other. But there's a reason that some people will think of it
one way while others will think of it the other way--I'd argue that
vectorization is not something that happens to *either* the operand
or the operator. Vectorization is a different *relationship* between
the operator and the operand. As such, I still think it belongs
between.
Plus, in the symmetrical case, it *looks* symmetrical. Marking the
args in front makes everything look asymmetrical whether it is or not.
Larry
%languageometer.values »+=« rand;
Not to be confused with
%languageometer.values »+= rand;
which would presumably add the *same* number to all languageometers.
Larry
> -----Original Message-----
> From: Larry Wall [mailto:la...@wall.org]
> Sent: Thursday, January 22, 2004 12:50 PM
> To: Language List
> Subject: Re: Semantics of vector operations
>
>
In reverse order:
> %languageometer.values »+= rand;
This is the same as
all( %languageometer.values ) += rand;
right?
And is this
> %languageometer.values »+=« rand;
the same as
all( %languageometer.values ) += one( rand );
?
=Austin
> -----Original Message-----
> From: Larry Wall [mailto:la...@wall.org]
> Sent: Thursday, January 22, 2004 12:39 PM
> To: Language List
> Subject: Re: Semantics of vector operations
>
>
> On Thu, Jan 22, 2004 at 03:53:04AM +0100, A. Pagaltzis wrote:
> : Good point; however, this means different way to think of the
> : vector ops than we had so far. Basically, we're moving from the
> : realm of vector ops to that of vectorized operands.
> :
> : In light of this, I think Austin's proposal of marking the
> : operands as vectorized makes a lot of sense. It was an unexpected
> : that had me taken aback for a moment, but I like it more the more
> : I think about it. It *feels* right to emphasize vectorization as
> : something that happens to an operand, rather than something
> : that's a property of the operation.
>
> I think some people will want to think of it one way, while others
> will want to think of it the other way. If that's the case, the
> proper place to put the marker is between the operand and the operator.
>
How do you handle operator precedence/associativity?
That is,
$a + $b + $c
If you're going to vectorize, and combine, then you'll want to group. I
think making the vectorizer a grouper as well kills two birds with one
stone.
$a + >>$b + $c<<
vs.
$a +<< ($b + $c)
> You might argue that we should force people to think of it one way or
> the other. But there's a reason that some people will think of it
> one way while others will think of it the other way--I'd argue that
> vectorization is not something that happens to *either* the operand
> or the operator. Vectorization is a different *relationship* between
> the operator and the operand. As such, I still think it belongs
> between.
>
> Plus, in the symmetrical case, it *looks* symmetrical. Marking the
> args in front makes everything look asymmetrical whether it is or not.
Just a refresher, what *exactly* does vectorization do, again? I think of
it as smart list-plus-times behavior, but when we go into matrix arithmetic,
that doesn't hold up. Luke?
=Austin
It's the same as
$r = rand;
$_ += $r for %languageometer.values
Your junction looks like it should work but I think you're really
adding the random number to the junction, not the elements that compose
the junction thus none of %languageometer.values are modified.
> And is this
>
> > %languageometer.values ?+=? rand;
>
> the same as
>
> all( %languageometer.values ) += one( rand );
I don't think so. It's like:
$_ += rand for %languageometer.values
perhaps if you had:
$j |= rand for (0..%languageometer.values)
any(%languageometer.values) += $j;
Though I'm not sure what that would mean.
I don't think junctions apply at all in vectorization. They seem to
be completely orthogonal.
-Scott
--
Jonathan Scott Duff
du...@lighthouse.tamucc.edu
Me? I handle it by making it an adverb on the base operator. :-)
: That is,
:
: $a + $b + $c
:
: If you're going to vectorize, and combine, then you'll want to group. I
: think making the vectorizer a grouper as well kills two birds with one
: stone.
:
: $a + >>$b + $c<<
Er, pardon me, but bletch.
: vs.
:
: $a +<< ($b + $c)
That's much clearer to me. (Ignoring the fact that you can't add
references. :-)
: > You might argue that we should force people to think of it one way or
: > the other. But there's a reason that some people will think of it
: > one way while others will think of it the other way--I'd argue that
: > vectorization is not something that happens to *either* the operand
: > or the operator. Vectorization is a different *relationship* between
: > the operator and the operand. As such, I still think it belongs
: > between.
: >
: > Plus, in the symmetrical case, it *looks* symmetrical. Marking the
: > args in front makes everything look asymmetrical whether it is or not.
:
: Just a refresher, what *exactly* does vectorization do, again? I think of
: it as smart list-plus-times behavior, but when we go into matrix arithmetic,
: that doesn't hold up. Luke?
It really means "please dereference this scalar in an intelligent
fashion for this particular operator". The exact behavior is
allowed to depend on the operator and the types of both arguments
(if both sides are vectorized). That is, it's probably a multimethod
in disguise.
Actually, it's a bit misleading to call it a vectorizing operator.
It's really a dwim operator that will commonly be used for vectorizing
in the case of one-dimensional lists. For higher dimensional beasties,
it means "make these conform and then apply the operator in some kind
of distributed fashion, with a bias toward leaf operations".
I don't think that »X« means "Do whatever the mathematicians want X
to do." Unicode operators have to be good for something, after all.
So perhaps its best to call » and « "distribution modifiers" or
some such.
Larry
Well, yes. It's also the same as each of:
any( %languageometer.values ) += rand;
none( %languageometer.values ) += rand;
one( %languageometer.values ) += rand;
Since the junctions aren't yet being evaluated in boolean context, the
type of the junction doesn't matter. Which is why making junctions
applicable lvalues might be a bad idea. I'm not sure, but this looks
like a potential confuser.
> It's the same as
>
> $r = rand;
> $_ += $r for %languageometer.values
>
> Your junction looks like it should work but I think you're really
> adding the random number to the junction, not the elements that compose
> the junction thus none of %languageometer.values are modified.
Hmm... that depends on whether junctions hold references, or what they
do in lvalue context, and a whole bunch of other, undecided things.
> > And is this
> >
> > > %languageometer.values »+=« rand;
> >
> > the same as
> >
> > all( %languageometer.values ) += one( rand );
No, what you just wrote is the same as:
all( %languageometer.values ) += rand;
> I don't think so. It's like:
>
> $_ += rand for %languageometer.values
Sortof. I think Larry was implying that rand returned an infinite list
of random numbers in list context. If not, then what he said was wrong,
because it would be sick to say that:
(1,2,3,4,5) »+« foo()
Calls foo() 5 times.
> perhaps if you had:
>
> $j |= rand for (0..%languageometer.values)
> any(%languageometer.values) += $j;
>
> Though I'm not sure what that would mean.
Nonononono! Don't do that! That adds *each* of the random numbers to
*each* of the values. That is, each of the values would increase by
approximately %languageometer/2.
> I don't think junctions apply at all in vectorization. They seem to
> be completely orthogonal.
I'd be happy if that were the case.
Luke
à
> -----Original Message-----
> From: Luke Palmer [mailto:fibo...@babylonia.flatirons.org]
> Sent: Thursday, January 22, 2004 3:52 PM
> To: Austin Hastings; Larry Wall; Language List
> Subject: Re: Semantics of vector operations (Damian)
>
>
> Jonathan Scott Duff writes:
> > On Thu, Jan 22, 2004 at 01:10:23PM -0500, Austin Hastings wrote:
> > > In reverse order:
> > >
> > > > %languageometer.values »+= rand;
> > >
> > > This is the same as
> > >
> > > all( %languageometer.values ) += rand;
> > >
> > > right?
>
> Well, yes. It's also the same as each of:
>
> any( %languageometer.values ) += rand;
> none( %languageometer.values ) += rand;
> one( %languageometer.values ) += rand;
>
> Since the junctions aren't yet being evaluated in boolean context, the
> type of the junction doesn't matter.
That is clear, once you've pointed it out, but really counterintuitive. Since all things are applicable, though, I don't object too much -- it's like "and" vs. "but" in English, I guess.
> Which is why making junctions applicable lvalues might be a bad idea. I'm not sure, but this
> looks like a potential confuser.
I think I disagree. With the caveat that there may be something to be said for discriminating between assigning TO a junction variable and assigning THROUGH one, I think that the presence or absence of assignment-operators is still the (obvious, sufficient) indicator that an assignment is taking place.
all(%languageometer.values) + 6
doesn't look like (and shouldn't be) an assignment.
all(%languageometer.values) += 6;
does.
> > It's the same as
> >
> > $r = rand;
> > $_ += $r for %languageometer.values
> >
> > Your junction looks like it should work but I think you're really
> > adding the random number to the junction, not the elements that compose
> > the junction thus none of %languageometer.values are modified.
>
> Hmm... that depends on whether junctions hold references, or what they
> do in lvalue context, and a whole bunch of other, undecided things.
>
> > > And is this
> > >
> > > > %languageometer.values »+=« rand;
> > >
> > > the same as
> > >
> > > all( %languageometer.values ) += one( rand );
>
> No, what you just wrote is the same as:
>
> all( %languageometer.values ) += rand;
So the vectorization op is providing the "call once per element" distribution service.
Which takes vectorization out of the MTOWTDI category and into the somewhat-orthogonal functionality category.
Vectorized operator: %languageometer.values »+=« rand;
Vectorized "sides": %languageometer.values »+=« rand;
Alt. Vectorized "sides": all(%languageometer.values) +=« rand;
Vectorized operands: »%languageometer.values« += »rand«;
Alt. Vectorized operands: all(%languageometer.values) += »rand«;
I withdraw my aesthetic objection: if vectorizing the operator isn't going to work, I don't like *any* of them very much.
> > I don't think so. It's like:
> >
> > $_ += rand for %languageometer.values
>
> Sortof. I think Larry was implying that rand returned an infinite list
> of random numbers in list context. If not, then what he said was wrong,
> because it would be sick to say that:
>
> (1,2,3,4,5) »+« foo()
>
> Calls foo() 5 times.
Why would it be sick, and in what context?
With Larry's new "vectorized sides" suggestion, putting a guillemot on the right side of the operator vectorizes the right side operand, which *should* call foo() five times.
(1,2,3,4,5) »+ foo() # do { my $x=foo(); (1+$x, 2+$x, 3+$x, 4+$x, 5+$x); }
(1,2,3,4,5) »+« foo() # (1+foo(), 2+foo(), 3+foo(), 4+foo(), 5+foo())
(1,2,3,4,5) +« foo() # Maybe the same as above? What does infix:+(@list,$scalar) do?
(1,2,3,4,5) + foo() # foo() in list context? What does infix:+(@list, @list2) do?
=Austin
I wouldn't, because if I did I'd should've been talking to Guido
rather than you in the first place. :-)
And because I'm talking to you, I'll wonder whether maybe we
ought to have both options.
> I'd argue that vectorization is not something that happens to
> *either* the operand or the operator. Vectorization is a
> different *relationship* between the operator and the operand.
> As such, I still think it belongs between.
That makes a lot of sense; consider me convinced.
Even if I agree after all though, that doesn't make me like the
way »+ and particularly +« look any more than I liked them
before. I usually scoff at "line noise" remarks, but in this case
I'd feel forced to mutter it myself -- it just continues to feel
like too big a change in behaviour dictated by a single "magic
character".
While »+« is a little ugly as well, it does stand out boldly,
something that could not IMHO be said about the one-sided
variants. I'd argue that we really should use something more
visually prominent for the one-sided case.
Maybe »»+ and +«« or something? But the non-Unicode variant would
be, uh, less than pretty.
> Plus, in the symmetrical case, it *looks* symmetrical. Marking
> the args in front makes everything look asymmetrical whether it
> is or not.
I was actually thinking something like
»$a« + »$b«
in which case asymmetry would not be an issue.
I have to agree with Larry here, the latter is much cleaner.
I'm actually starting to like this proposal. I used to shiver at the
implementation of the old way, where people used the operator to group
arbitrary parts of the expression. I wouldn't even know how to parse
that, much less interpret it when it's parsed.
Now, we have a clear way to call a method on a list of values:
@list ».method
And a clear way to call a list of methods on a value:
$value.« @methods
It's turning out pretty nice.
> > You might argue that we should force people to think of it one way or
> > the other. But there's a reason that some people will think of it
> > one way while others will think of it the other way--I'd argue that
> > vectorization is not something that happens to *either* the operand
> > or the operator. Vectorization is a different *relationship* between
> > the operator and the operand. As such, I still think it belongs
> > between.
> >
> > Plus, in the symmetrical case, it *looks* symmetrical. Marking the
> > args in front makes everything look asymmetrical whether it is or not.
>
> Just a refresher, what *exactly* does vectorization do, again? I think of
> it as smart list-plus-times behavior, but when we go into matrix arithmetic,
> that doesn't hold up. Luke?
Well, for being called "vector operators", they're ending up pretty
useless as far as working with mathematical vectors. As a
mathematician, I'd want:
@vec1 »*« @vec2
To do an inner or an outer product (probably outer, as it has no
implicit connotations of the + operator). That is, it would come out
either a matrix or a scalar.
But there are other times when I'd want that to call the operator
respectively. Then you get this for the inner product:
sum(@vec1 »*« @vec2)
Which isn't so bad, after all.
Hmm, but if it does give an outer product, then a generic tensor product
is as easy as:
reduce { $^a »+« $^b } @A »*« @B
And nobody can fathom how happy that would make me.
Also, you'd get the nice consistency that:
@A »+« @B
Is the same as both:
map { @A »+ $^b } @B
map { $^a +« @B } @A
Which is undoubtedly what the mathematician would expect (It's very
reminiscent of how junctions currently work).
But then there's the problem of how you express the oft-wanted:
map -> $i { @A[$i] + @B[$i] } 0..^min(+@A, +@B)
(Hopefully when @A and @B are of equal length).
Maybe there's a way to do it so that we can both be happy: one syntax
that does one thing, another that does the other. Like:
@A »+« @B # One-at-a-time
@A «+» @B # Outer product
Or something. Hmm, then both:
@A »+ $b
@A «+ $b
Would mean the same thing.
Luke
à
I think that one is:
do { my @x=foo(); (1+@x[1], 2+@x[2], 3+@x[3], 4+@x[4], 5+@x[5]) }
We've forgotten that foo() could return a list in list context. :-)
> (1,2,3,4,5) +« foo() # Maybe the same as above? What does infix:+(@list,$scalar) do?
Well, what does a list return in scalar context? In the presence of the
C comma, it returns 5 for the last thing evaluated. In its absence, it
returns 5 for the length.
> (1,2,3,4,5) + foo() # foo() in list context? What does infix:+(@list, @list2) do?
Same deal, 5 + $(foo())
Luke
à
And of course I forgot to read you comments. So you want to add two
lists, as in:
[1,2,3,4,5] + [foo()]
Well, that's an error, I think. That or it adds the lengths.
Luke
à
Which is why I suggested calling them distributors or some such.
: As a
: mathematician, I'd want:
:
: @vec1 »*« @vec2
:
: To do an inner or an outer product (probably outer, as it has no
: implicit connotations of the + operator). That is, it would come out
: either a matrix or a scalar.
:
: But there are other times when I'd want that to call the operator
: respectively. Then you get this for the inner product:
:
: sum(@vec1 »*« @vec2)
:
: Which isn't so bad, after all.
Yes, and I think we have to stick with the naive view of what »*« would
do, since there are times you simply want to do a bunch of multiplications
in parallel.
: Hmm, but if it does give an outer product, then a generic tensor product
: is as easy as:
:
: reduce { $^a »+« $^b } @A »*« @B
:
: And nobody can fathom how happy that would make me.
I'd think it would make you even happier to just use the appropriate
Unicode operators directly (presuming there are such).
: Also, you'd get the nice consistency that:
:
: @A »+« @B
:
: Is the same as both:
:
: map { @A »+ $^b } @B
: map { $^a +« @B } @A
:
: Which is undoubtedly what the mathematician would expect (It's very
: reminiscent of how junctions currently work).
:
: But then there's the problem of how you express the oft-wanted:
:
: map -> $i { @A[$i] + @B[$i] } 0..^min(+@A, +@B)
:
: (Hopefully when @A and @B are of equal length).
Yes, though in fact »« is supposed to do max() rather than min() here.
Which, in the case of arrays of equal length, comes out to the same
thing...
: Maybe there's a way to do it so that we can both be happy: one syntax
: that does one thing, another that does the other. Like:
:
: @A »+« @B # One-at-a-time
: @A «+» @B # Outer product
:
: Or something. Hmm, then both:
:
: @A »+ $b
: @A «+ $b
:
: Would mean the same thing.
Which says to me that outer product really wants to be something like
X or ✕ or even ∘ (shades of APL). In the for-what-it's-worth department,
it looks like Python might be using @ for that.
Larry
Does that mean it should get the colon? :)
> I don't think that ?X? means "Do whatever the mathematicians want X
> to do." Unicode operators have to be good for something, after all.
>
> So perhaps its best to call ? and ? "distribution modifiers" or
> some such.
Could someone put the non-unicode variants up there so those of us
with unicode-ignorant MUAs can know what exactly we're talking about?
Or alternatively (and certainly better), could someone clue me on how
to make mutt unicode-aware?
thanks,
Only if all adverbs in English end in -ly.
Of course, my name ends -ly in Japan--I had to learn to answer to "Rally"
when I was there. So maybe I still get the colon... :-)
: > I don't think that ?X? means "Do whatever the mathematicians want X
: > to do." Unicode operators have to be good for something, after all.
: >
: > So perhaps its best to call ? and ? "distribution modifiers" or
: > some such.
:
: Could someone put the non-unicode variants up there so those of us
: with unicode-ignorant MUAs can know what exactly we're talking about?
Those are just the German/French quotes that look like >> and <<.
: Or alternatively (and certainly better), could someone clue me on how
: to make mutt unicode-aware?
Modern versions of mutt are already unicode aware--that's what I'm using.
Make sure .muttrc has
set charset="utf-8"
set editor="vim" (or any editor that can handle utf-8)
set send_charset="us-ascii:iso-8859-1:utf-8"
The main thing is you have to make sure your xterm (or equivalent)
unicode aware. This starts a (reversed video) unicode terminal on
my machine:
LANG=en_US.UTF-8 xterm \
-fg white -bg black \
-u8 \
-fn '-Misc-Fixed-Medium-R-Normal--18-120-100-100-C-90-ISO10646-1'
I'm also using gnome-terminal 2.4.0.1, which knows how to do utf-8
if you tell it in the preferences.
Of course, this is all from the latest Fedora Core, so your software
might not be so up-to-date. And other folks might prefer something
other than en_US. It's the .UTF-8 that's the important part though.
I run some windows in ja_JP.UTF-8. And, actually, my send_charset is
set send_charset="us-ascii:iso-8859-1:iso-2022-jp:utf-8"
because I have Japanese friends who prefer iso-2022-jp because they
don't know how to read utf-8 yet.
Larry
I just realized a potential flaw here. Consider the code
$a >>= 1;
Will this right-shift the value of $a one bit and assign the result to $a
(the current meaning)? Or will it assign the value 1 to each element in the
array referenced by $a (as suggested by the new syntax). Both of these are
perfectly valid operations, and I don't think its acceptable to have the
same syntax mean both. I'm aware that using "»=" instead of ">>=" will
eliminate the inconsistency, but not everyone has easy access to Unicode
keyboards.
Joe Gottman
There is a page you may find inspiring:
http://www.ritsumei.ac.jp/~akitaoka/index-e.html
Sorry, I could not resist. :) The one-sided operators make sense to me
but combining this with both « and » seems hard on the eyes.
That being said I really like the general direction that Perl 6 is
going and I'm looking forward to using it. You're all doing great
work!
back to lurking-mode
-Edwin
Well,
$a >>=<< 1
would still presumably be unambiguous, and do the right thing, albeit
with run-time dwimmery. On the other hand, we've renamed all the
other bitwise operators, so maybe we should rename these too:
+< bitwise left shift
+> bitwise right shift
which also gives us useful string bitshift ops:
~< stringwise left shift
~> stringwise right shift
as well as the never-before-thought-of:
?< boolean left shift
?> boolean right shift
Those last would be a great addition insofar as they could always
participate in constant folding. Er, unless the right argument is 0,
of course... :-)
Ain't orthogonality wonderful...
Larry
I could have sworn we already did that. I thought they were:
+<<
+>>
But I guess that's an extra unneeded character.
Luke
> which àlso gives us useful string bitshift ops:
Yeah, I kinda wondered if we'd done that already. But hey, if I
don't remember what I already said, how can I get mad when other
people don't remember. :-)
For historical reasons it would be better to stick with the long
versions, even if that does engender the occasional 4-character
+<<= operator. (Not to mention the 6-character »+<<=« operator.
(Not to mention the 8-character >>+<<=<< operator.)) Though I guess
that would make >>+<< ambiguous again, sigh...
Which probably means we have to force bitshifts to +< and +>, so
we can tell the difference between >>+< and >>+<< and >>+<<<. It's
almost getting to the point where we want to allow disambiguating
underscores in operators: >>_+<_<<. Alternately we give up on <<>>
as a qw// replacement and allow spaces: >> +< <<.
But we also have the ambiguity with <<'' and friends, so maybe the real
problem is trying to make the << and >> workarounds look too much like
« and ». Maybe they should be :<< and :>> or some such. Maybe we
should be thinking about a more general trigraph (shudder) policy.
Or some other kind of "entity" policy. Though I don't think people
would be terribly pleased when they see things like:
@a »+<<« @b
Particularly since the "r" one goes on the left, and the "l" on goes
on the right. Still, it's potentially a lot less ambiguous, and puts
people into the "preprocessing" frame of mind, and would certainly
motivate people to move toward editors and terminals that can display:
@a »+<<« @b
And we wouldn't have to define yet another arbitrary list of mappings.
On the other hand, we'd probably have to require a () on the &foo()
notation to distinguish it from an &foo; entity.
As a half-measure, we could allow << and >> for most purposes and
only require the entities when ambiguous. That might be the best
approach.
Larry
All of these are getting pretty huge an unwieldy. We do reward the
people with UTF-8 terminals, but oh how we punish those without.
Perhaps that's not the best way to go.
What about >: and :< ? This doesn't visually interfere quite as much,
because we won't be seeing a distributed : or :: operator. It's still
not terribly pretty on things like >:+<<:<, but it's more managable than
>>+<<<<, and not nearly as ambiguous :-)
Luke
> Particularly since the "r" one goes on the left, and the "l" on goes
> on the right. Still, it's potentially a lot less ambiguous, and puts
> people into the "preprocessing" frame of mind, and would certainly
> motivate people to move toward editors and terminals that can display:
>
> @a 損+<<束 @b
@a \C[leach] + \C[reach] @b
Not mnemonic in a visual sense, but extendable to all sorts of trigraph
contexts. Indeed, if we had a "this is an operator" operator, we could give
every symbol a textual name:
$a \op[assign] $b \op[plus] $c;
@a = @b \op[leach plus reach] @c;
Dave.
"Luke Palmer" <fibo...@babylonia.flatirons.org> wrote in message
news:20040123212...@babylonia.flatirons.org...
> Larry Wall writes:
> > On Thu, Jan 22, 2004 at 07:03:26PM -0700, Luke Palmer wrote:
> > : Larry Wall writes:
> > : > On the other hand, we've renamed all the
> > : > other bitwise operators, so maybe we should rename these too:
> > : >
> > : > +< bitwise left shift
> > : > +> bitwise right shift
> > :
> > : I could have sworn we already did that. I thought they were:
> > :
> > : +<<
> > : +>>
> > :
> > : But I guess that's an extra unneeded character.
> >
> > Yeah, I kinda wondered if we'd done that already. But hey, if I
> > don't remember what I already said, how can I get mad when other
> > people don't remember. :-)
> >
> > For historical reasons it would be better to stick with the long
> > versions, even if that does engender the occasional 4-character
> > +<<= operator. (Not to mention the 6-character ?+<<=? operator.
> > (Not to mention the 8-character >>+<<=<< operator.)) Though I guess
> > that would make >>+<< ambiguous again, sigh...
> >
> > Which probably means we have to force bitshifts to +< and +>, so
> > we can tell the difference between >>+< and >>+<< and >>+<<<. It's
> > almost getting to the point where we want to allow disambiguating
> > underscores in operators: >>_+<_<<. Alternately we give up on <<>>
> > as a qw// replacement and allow spaces: >> +< <<.
> >
> > But we also have the ambiguity with <<'' and friends, so maybe the real
> > problem is trying to make the << and >> workarounds look too much like
> > ? and ?. Maybe they should be :<< and :>> or some such. Maybe we
> > should be thinking about a more general trigraph (shudder) policy.
> > Or some other kind of "entity" policy. Though I don't think people
> > would be terribly pleased when they see things like:
> >
> > @a »+<<« @b
>
> All of these are getting pretty huge an unwieldy. We do reward the
> people with UTF-8 terminals, but oh how we punish those without.
> Perhaps that's not the best way to go.
>
> What about >: and :< ? This doesn't visually interfere quite as much,
> because we won't be seeing a distributed : or :: operator. It's still
> not terribly pretty on things like >:+<<:<, but it's more managable than
> >>+<<<<, and not nearly as ambiguous :-)
>
> Luke
>
> > Particularly since the "r" one goes on the left, and the "l" on goes
> > on the right. Still, it's potentially a lot less ambiguous, and puts
> > people into the "preprocessing" frame of mind, and would certainly
> > motivate people to move toward editors and terminals that can display:
> >
> > @a ?+<<? @b
Luke Palmer also responded to my message and said I would be horrified to learn that >>*<< was being called a "vector" operation rather than a "list" operation. I am horrified. Computer scientists have already usurped the terms "real", "kilo", and others and given them non-standard meanings. Please don't do the same with "vector" and "matrix". And forget I ever mentioned quaternion, tensor, and rotor.
I am a physicist and mathematician who uses perl5 extensively for the likes of preparing CAD data for printed circuit board fabrication and creating AutoDesk files in DXF format from mathematical calculations. I even plot data on my web site using perl to create .SVG files. I learned to code when FORTRAN didn't have any version number and I still think I might be happy with pure assembly in parrot but when I want to do vectors or complex numbers I end up in Waterloo Maple for the solutions and M$ Excel for the arithmetic. Perl 6 would sure be nice for once-in-a-while vector operations that are not worth the programming time for an array of 1024 Mac G5's.
This whole thread worrying about semantics of obscure operators for things that are not even going to be real vector or matrix operations worries me. Just who do you think is going to use them? Multiplying elements of an array by each other to get another array is not a vector product and it is not an inner product. It is useless to me regardless of the operator syntax you choose. Ditto for multiplication of lists of lists, also called matrices, where all you do is provide piece by piece multiplication of elements.
In FORTRAN I learned that names that begin with IJKLMN were integers and further that if only a single letter is used it will be assigned to a hardware register. Those letters are what you now call a sigl and I'll bet I spelled it wrong.
Why can't you assign a sigl to things that are to be vectors or matrices and let that determine what the standard operators do? Context could distinguish the inner product from the vector product. typedef? Those of us who actually use vector arithmetic wouldn't mind a special identifier that's not an $, @, or %. Other users need not know about it until they find it useful. If absolutely necessary to comply with modern terminology you could call vectors and matrices members of a class and overload the operators but my experience is that such things just cloud the underlying arithmetic process that needs to be foremost while solving a problem.
The KISS principle is important. Please reconsider your "vector" operations before you go off the deep end with syntax that won't ever be used. And yes, I have some time and would like to help. But it will take hours to learn about the C++ stuff in CVS files. I have Linux and Mac OS neXt available.
Douglas P. McNutt PhD
The MacNauchtan Laboratory
7255 Suntide Place
Colorado Springs CO 80919-1060
voice 719 593 8192
dmc...@macnauchtan.com
http://www.macnauchtan.com/
--
--> There are 10 kinds of people: those who understand binary, and those who don't <--
That's an interesting idea, but I'd prefer to generalize it to the
notion of how you interpolate a macro call that may be ambiguous
with its surroundings. Then you can set up any text you want.
In the unambiguous cases you can leave out the disambiguating syntax.
That is, suppose you have:
macro leach () { return "»" }
macro reach () { return "«" }
You could unambiguosly write
leach+reach
but (assuming spaces not allowed within distributed operators) you can't
write
leacheqreach
But if instead you could write something like
:leach()eq:reach()
then you can still do it even when it'd be ambiguous. But I can think
of prettier ways to disambiguate:
{leach}eq{reach}
[leach]eq[reach]
(leach)eq(reach)
<leach>eq<reach>
Unfortunately, all the good brackets are taken. Hey, we could use
those weird French quotes:
«leach»eq«reach»
Oh, wait...nevermind...
Larry
Appreciate that...
: Luke Palmer also responded to my message and said I would be horrified
: to learn that >>*<< was being called a "vector" operation rather
: than a "list" operation. I am horrified. Computer scientists have
: already usurped the terms "real", "kilo", and others and given them
: non-standard meanings. Please don't do the same with "vector" and
: "matrix". And forget I ever mentioned quaternion, tensor, and rotor.
Sorry, I was just copying the designers of supercomputers in my
terminology. So you can really blame Seymour Cray for misappropriating
the term. On a Cray, "vector processing" is just operations applied
in parallel to two one-dimensional lists. Unfortunately, I don't
think you'll be able to get an apology from Seymour Cray these days...
: I am a physicist and mathematician who uses perl5 extensively for the
: likes of preparing CAD data for printed circuit board fabrication and
: creating AutoDesk files in DXF format from mathematical calculations. I
: even plot data on my web site using perl to create .SVG files. I
: learned to code when FORTRAN didn't have any version number and I
: still think I might be happy with pure assembly in parrot but when
: I want to do vectors or complex numbers I end up in Waterloo Maple
: for the solutions and M$ Excel for the arithmetic. Perl 6 would sure
: be nice for once-in-a-while vector operations that are not worth the
: programming time for an array of 1024 Mac G5's.
I'd like the program running on the array of 1024 Mac G5's to be in
Perl too. :-)
: This whole thread worrying about semantics of obscure operators for
: things that are not even going to be real vector or matrix operations
: worries me. Just who do you think is going to use them? Multiplying
: elements of an array by each other to get another array is not a vector
: product and it is not an inner product. It is useless to me regardless
: of the operator syntax you choose. Ditto for multiplication of lists
: of lists, also called matrices, where all you do is provide piece by
: piece multiplication of elements.
The so-called vector operations in Perl 6 are not really aimed at
mathemeticians. They're aimed more at the image processing and
finite-state automata folks, who often want to do the same thing in
parallel to a bunch of different array elements. This is why they
may be applied to any operator, not just numeric operators, so that
people can do things like "append newline to every element of this
array" without writing explicit loop or map statements.
Not being a mathemetician myself, it has always been my intention to
let the mathemeticians define their own operators however they see fit.
That is why Perl 6 allows the definition of Unicode operators.
: In FORTRAN I learned that names that begin with IJKLMN were integers
: and further that if only a single letter is used it will be assigned
: to a hardware register. Those letters are what you now call a sigl
: and I'll bet I spelled it wrong.
:
: Why can't you assign a sigl to things that are to be vectors
: or matrices and let that determine what the standard operators
: do? Context could distinguish the inner product from the vector
: product. typedef? Those of us who actually use vector arithmetic
: wouldn't mind a special identifier that's not an $, @, or %. Other
: users need not know about it until they find it useful. If absolutely
: necessary to comply with modern terminology you could call vectors
: and matrices members of a class and overload the operators but my
: experience is that such things just cloud the underlying arithmetic
: process that needs to be foremost while solving a problem.
You are precisely right: "Other users need not know about it until
they find it useful." In this case, I'm one of those other users. :-)
That is why, not being omniscient, I will leave it to the
mathemeticians to define their own sigils. Unfortunately, most of
ASCII is used up, so you'll have to pick your sigils from Unicode.
But part of the design of Perl 6 is that the language be mutable
enough to make this trivially easy. A single declaration can turn
Perl into Swahili, as far as I'm (un)concerned. "All is fair if
you predeclare."
: The KISS principle is important. Please reconsider your "vector"
: operations before you go off the deep end with syntax that won't
: ever be used.
I believe they will be used, but maybe not in your realm of endeavor.
The entire universe does things in parallel, so I think it behooves
Perl to provide some way to specify that without iterative constructs.
I really only care about the concept--I don't give a rip about the
word "vector". I can let it go at the drop of a hat. Because of the
confusion engendered by overloaded use of the term "vector", I've
recently taken to calling them "distributed" operations instead.
But that's a mouthful. Maybe we need to make up a new word.
But "dwimops" is a bit too general. Parops, genops, hmm... Maybe we
should go back to "hyper ops".
On the other hand, we could teach the mathemeticians not to assume
that their usage of a word is the only usage. :-)
And many people do think vector is the opposite of scalar...
: And yes, I have some time and would like to help. But
: it will take hours to learn about the C++ stuff in CVS files. I have
: Linux and Mac OS neXt available.
It would be useful to me to find out which Unicode characters a typical
mathemetician would actually find useful. I don't actually know,
for example, what the preferred operator for outer product would be.
APL used the circle operator, but there are a number of multiplicative
operators defined in Unicode, most of which seem pretty abstruse.
Eventually I'd like general feedback from the viewpoint of the
mathemeticians on the design of overloading, multimethods, and various
forms of syntactic relief. Up till now I really only have the input
of the PDL folks in RFCs 202..207 (available on dev.perl.org), and
some of the design has been influenced by those RFCs already (such
as syntax of slicing). But a lot of this feedback will have to wait
for Apocalypse 9, which will come out sometime after Apocalypse 12,
which will come out sometime...soon...
Larry
But, presumably, you could write a macro that has a whitespace-eater encoded
somehow. That is,
macro leach() { chomp_trailing_whitespace; return "»" }
macro reach () { chomp_leading_whitespace; return "«" }
then the macro magic would expand "leach eq reach" as "»eq«" (which,
hopefully, it then re-parses as a single token^Woperator). This doesn't
solve the generalized problem of disambiguating, though I could see a "_"
operator defined as a macro that eats all its surrounding whitespace.
Dave.
...making it a "nospace" character (or is that a "no_space" character?
Same thing?)
You wouldn't be able to say "chomp_trailing_whitespace" if you did this,
though.
=====
Jonathan "Dataweaver" Lang
__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free web site building tool. Try it!
http://webhosting.yahoo.com/ps/sb/