reduce metaoperator

7 views
Skip to first unread message

Larry Wall

unread,
May 4, 2005, 8:36:51 AM5/4/05
to perl6-l...@perl.org
I propose that reduce become a metaoperator that can be applied to
any binary operator and turns it syntactically into a list operator.
I am currently thinking that the metaoperator is a prefix spelled \\
(though there are certainly lots of other possibilities that I've laid
awake all night thinking about). There are the usual suspects like:

$sum = \\+ @array;
$fact = \\* 1..$num;

Then there are some rather interesting ones like:

$firsttrue = \\|| @args;
$firstdef = \\// @args;
@sumrows := \\+« @rows;

I particularly want this to replace the semantically ugly "dim" operator
(used to be "semi") in multidimensional subscripts:

@foo[0..9; \\;(@dims); 0..9]

Also, by the way, infix:<;> now only creates arrays of lists only in
contexts bound to something like

Array *@array
Lazy *@array
Eager *@array

This is how the parameters to a subscript are declared, so they
automatically get a list of lists, even if there are no semicolons
in the subscript. This gets rid of the "retroactive semicolon"
problem once and for all.

In ordinary list context, infix:<;> is just a list-op-ending "big comma",
but is otherwise treated like an ordinary comma (but only if the
list is in some kind of brackets, of course).

Now here's the interesting part. The same critera apply to extra
lists added with <== or ==>. In other words, a function may be be
declared to recognize multiple input pipes as separate lists just
like a subscript recognizes multiple dimensions of slices. But the
default is to flatten all input pipes into a single input stream.

The new semicolon semantics are relatively non-negotiable, but feel
free to hash out the reduce metaoperator. Perhaps \\ is the ASCII
version, and people will prefer to write something with less visual
confusion and more mnemonic power:

$sum = ®+ @array;
$fact = ®* 1..$num;
$firsttrue = ®|| @args;
$firstdef = ®// @args;
@sumrows := ®+« @rows;
@foo[0..9; ®;(@dims); 0..9]

Hmm, that kind of says that the ASCII workaround should be:

$sum = (R)+ @array;
$fact = (R)* 1..$num;
$firsttrue = (R)|| @args;
$firstdef = (R)// @args;
@sumrows := (R)+« @rows;
@foo[0..9; (R);(@dims); 0..9]

Which does have the benefit of not letting people confuse \\ with //
semantically or visually. I guess (R) would be a Texas reduce. :-)

Larry

Juerd

unread,
May 4, 2005, 8:53:54 AM5/4/05
to perl6-l...@perl.org
Are these equivalent? (Assuming reduce isn't going away)

Larry Wall skribis 2005-05-04 5:36 (-0700):


> $sum = \\+ @array;
> $fact = \\* 1..$num;

$sum = reduce &infix:<+>, @arrayd;
$fact = reduce &infix:<*>, 1..$num;

> $firsttrue = \\|| @args;
> $firstdef = \\// @args;
> @sumrows := \\+« @rows;

$firsttrue = reduce &infix:<||>, @args;
$firstdef = reduce &infix:<//>, @args;
@sumrows := map { reduce &infix:<+>, @$_ }, @rows;

> Now here's the interesting part. The same critera apply to extra
> lists added with <== or ==>. In other words, a function may be be
> declared to recognize multiple input pipes as separate lists just
> like a subscript recognizes multiple dimensions of slices. But the
> default is to flatten all input pipes into a single input stream.

Hm, if ==> and <== are made special syntax, maybe this would be
possible?

@foo ==> zip <== @bar

> $sum = (R)+ @array;

I like that.


Juerd
--
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html
http://convolution.nl/gajigu_juerd_n.html

Rob Kinyon

unread,
May 4, 2005, 8:59:04 AM5/4/05
to perl6-l...@perl.org
This may be a naive question, but what's wrong with just having a
keyword called reduce()? Why do we need an operator for everything?
I'm worried that the list of P6 operators is going to be as long as
the list of P5 keywords, with a lot of them looking something like:

<verb><direct object><indirect object>

I propose that if you're thinking of using 3+ ASCII characters for an
operator that it should just become a keyword. For one thing, it's
more maintainable that way. I can remap ^K in vi to be 'perldoc -f"
instead of 'man' and it will work for keywords, but not for Unicode
operators.

Rob

> $sum = (r)+ @array;
> $fact = (r)* 1..$num;
> $firsttrue = (r)|| @args;
> $firstdef = (r)// @args;
> @sumrows := (r)+« @rows;
> @foo[0..9; (r);(@dims); 0..9]

Juerd

unread,
May 4, 2005, 8:58:14 AM5/4/05
to perl6-l...@perl.org
Juerd skribis 2005-05-04 14:53 (+0200):

> @foo ==> zip <== @bar

Hmmmm...

@quux
||
||
\/


@foo ==> zip <== @bar

/\
||
||
@xyzzy

:)

Michele Dondi

unread,
May 4, 2005, 9:11:46 AM5/4/05
to Larry Wall, perl6-l...@perl.org
On Wed, 4 May 2005, Larry Wall wrote:

> I propose that reduce become a metaoperator that can be applied to
> any binary operator and turns it syntactically into a list operator.

I second that. By all means! (But I thin it would be desirable to have a
'plain' reduce operator as well)


Michele
--
The reason I want to do this is that I am drawing up legal documents,
and sometimes when I send out to a client I want to have a footnote to
explain some point of godawful convoluted legal prose (why don't I
just write it clearly in the first place??! Different topic....)
- "DrMemory" in comp.text.tex, "Re: Footnotes: turning them on/off"

Uri Guttman

unread,
May 4, 2005, 9:23:03 AM5/4/05
to Juerd, perl6-l...@perl.org
>>>>> "J" == Juerd <ju...@convolution.nl> writes:

J> Juerd skribis 2005-05-04 14:53 (+0200):


>> @foo ==> zip <== @bar

J> Hmmmm...

J> @quux
J> ||
J> ||
J> \/
J> @foo ==> zip <== @bar
J> /\
J> ||
J> ||
J> @xyzzy

you are brainfucking me! stop it now!!

:)

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

Larry Wall

unread,
May 4, 2005, 9:06:50 AM5/4/05
to Perl6 Language List
On Wed, May 04, 2005 at 09:00:46AM -0400, Aaron Sherman wrote:
: That said, let me try to be helpful, and not just complain:
:
: $sum = (+) @array;
:
: I've not thought through all of the implications to the parser, but I
: think this works, and it certainly ends up looking very mnemonic for
: what you're trying to do!

It's certainly one of the ones I considered, along with all the other
brackets, and |+|, plus variants It just seemed like it'd be a little
visually confusing where you want to turn the list op into a function

$sum = (+)(@array);

But maybe that's not a problem. But there are other potential
ambiguities besides visual, I suspect.

Larry

Uri Guttman

unread,
May 4, 2005, 9:18:46 AM5/4/05
to perl6-l...@perl.org
>>>>> "LW" == Larry Wall <la...@wall.org> writes:

LW> I propose that reduce become a metaoperator that can be applied to
LW> any binary operator and turns it syntactically into a list operator.
LW> I am currently thinking that the metaoperator is a prefix spelled \\
LW> (though there are certainly lots of other possibilities that I've laid
LW> awake all night thinking about). There are the usual suspects like:

LW> $sum = \\+ @array;
LW> $fact = \\* 1..$num;

shouldn't that be s/fact/prod/ ? sure the input makes it a factorial but
the general case would be a product. not that what var names you choose
matters but i think it would be clearer if used as a real example in
some future docs.

Rob Kinyon

unread,
May 4, 2005, 9:16:22 AM5/4/05
to perl6-l...@perl.org
Using that argument, every keyword is really an operator/macro.
Instead of sub/method/multimethod, we could use a special character.

sub foo { ... }

becomes

&&& foo { ... }

A method is >&&, a multimethod is *&&, and so on. (I don't have a
Unicode mail client or I'd look for a Unicode character.)

What I'm saying is that humans still have to read this language.
Humans read English, not a stream of characters that have modifying
effects on both their left and right hand sides. Streams of characters
that will parse different depending on what's happening around them.

Keywords are just a lot easier to work with.

Now, here's another possibility - have these operators live in
modules. If you really really want the (R) operator, then "use
Reduce::Operator;" and now I know when I read your code what
(R)+@array means, because it's documented somewhere.

But, don't put it in the core. I thought the core was supposed to be
sparse with modules to add the richness.

Rob

On 5/4/05, Larry Wall <la...@wall.org> wrote:

> On Wed, May 04, 2005 at 08:59:04AM -0400, Rob Kinyon wrote:
> : This may be a naive question, but what's wrong with just having a


> : keyword called reduce()? Why do we need an operator for everything?
>

> Because it's an operator/macro in any event, with weird unary or
> listop parsing:
>
> reduce(+) @array
>
> Larry
>

Juerd

unread,
May 4, 2005, 9:15:09 AM5/4/05
to perl6-l...@perl.org
Larry Wall skribis 2005-05-04 6:10 (-0700):

> On Wed, May 04, 2005 at 08:59:04AM -0400, Rob Kinyon wrote:
> : This may be a naive question, but what's wrong with just having a

> : keyword called reduce()? Why do we need an operator for everything?
> Because it's an operator/macro in any event, with weird unary or
> listop parsing:
> reduce(+) @array

That's ugly, but there's also the map-ish form, and I'd like that to
still be available.

reduce { $^a + $^b }, @array;
reduce &infix:<+>, @array;

Larry Wall

unread,
May 4, 2005, 9:02:42 AM5/4/05
to perl6-l...@perl.org
On Wed, May 04, 2005 at 02:53:54PM +0200, Juerd wrote:
: Hm, if ==> and <== are made special syntax, maybe this would be

: possible?
:
: @foo ==> zip <== @bar

It's already the case that <== binds tighter, so it should work the
same as

@foo ==> (zip <== @bar)

or

zip <== @bar <== @foo

or

zip(@bar; @foo)

Which, considering zip *is* going to care about multidimensional slices,
should do the right thing, presuming you really wanted @bar in front.
Ordinarily I'd write it

@foo ==>
zip <== @bar

to make it a little clearer.

You'll note that <== is really just a version of ; that doesn't
require brackets.

Larry

Larry Wall

unread,
May 4, 2005, 9:17:58 AM5/4/05
to perl6-l...@perl.org
On Wed, May 04, 2005 at 02:58:14PM +0200, Juerd wrote:
: Juerd skribis 2005-05-04 14:53 (+0200):

: > @foo ==> zip <== @bar
:
: Hmmmm...
:
: @quux
: ||
: ||
: \/
: @foo ==> zip <== @bar
: /\
: ||
: ||
: @xyzzy
:
: :)

That's actually...er, doable...in Perl 6...er...if you install a token
parse rule with whitespace in it to disambiguate from the shorter ops...
But perhaps Unicode operators would be more toward. Besides, then
you can have the diagonal arrows as well.

Larry

Larry Wall

unread,
May 4, 2005, 9:10:18 AM5/4/05
to perl6-l...@perl.org
On Wed, May 04, 2005 at 08:59:04AM -0400, Rob Kinyon wrote:
: This may be a naive question, but what's wrong with just having a

: keyword called reduce()? Why do we need an operator for everything?

Because it's an operator/macro in any event, with weird unary or
listop parsing:

reduce(+) @array

Larry

Juerd

unread,
May 4, 2005, 9:07:40 AM5/4/05
to Aaron Sherman, Perl6 Language List
Aaron Sherman skribis 2005-05-04 9:00 (-0400):
> > $sum = ®+ @array;
> I don't think you can do that workably. In the font I use, I was
> scratching my head asking "how does @ work there?!" Yep, I can't tell ®
> and @ apart without getting REAL close to the screen.

Perhaps this just means that the texas reduce is written @ instead.

> Are there any infix:op where there is also a standalone op that would
> confuse usage inside ()? If so, would it be too big a deal to
> special-case those?

Maybe x?

Aaron Sherman

unread,
May 4, 2005, 9:00:46 AM5/4/05
to Larry Wall, Perl6 Language List
On Wed, 2005-05-04 at 08:36, Larry Wall wrote:
> I propose that reduce become a metaoperator that can be applied to
> any binary operator and turns it syntactically into a list operator.

Sounds very cool! I like it... but...

> $sum = ®+ @array;

I don't think you can do that workably. In the font I use, I was
scratching my head asking "how does @ work there?!" Yep, I can't tell ®
and @ apart without getting REAL close to the screen.

I also deeply dislike \\//, but I can't tell you why rationally. :-/

That said, let me try to be helpful, and not just complain:

$sum = (+) @array;

I've not thought through all of the implications to the parser, but I
think this works, and it certainly ends up looking very mnemonic for
what you're trying to do!

Are there any infix:op where there is also a standalone op that would


confuse usage inside ()? If so, would it be too big a deal to
special-case those?

--
Aaron Sherman <a...@ajs.com>
Senior Systems Engineer and Toolsmith
"It's the sound of a satellite saying, 'get me down!'" -Shriekback


Larry Wall

unread,
May 4, 2005, 9:26:12 AM5/4/05
to perl6-l...@perl.org
On Wed, May 04, 2005 at 09:18:46AM -0400, Uri Guttman wrote:
: >>>>> "LW" == Larry Wall <la...@wall.org> writes:
: LW> $fact = \\* 1..$num;

:
: shouldn't that be s/fact/prod/ ? sure the input makes it a factorial but
: the general case would be a product. not that what var names you choose
: matters but i think it would be clearer if used as a real example in
: some future docs.

If it made you think, maybe it was a good example. :-)

Larry

Larry Wall

unread,
May 4, 2005, 9:36:00 AM5/4/05
to perl6-l...@perl.org
On Wed, May 04, 2005 at 03:15:09PM +0200, Juerd wrote:
: Larry Wall skribis 2005-05-04 6:10 (-0700):

: > On Wed, May 04, 2005 at 08:59:04AM -0400, Rob Kinyon wrote:
: > : This may be a naive question, but what's wrong with just having a
: > : keyword called reduce()? Why do we need an operator for everything?
: > Because it's an operator/macro in any event, with weird unary or
: > listop parsing:
: > reduce(+) @array
:
: That's ugly, but there's also the map-ish form, and I'd like that to
: still be available.
:
: reduce { $^a + $^b }, @array;
: reduce &infix:<+>, @array;

Yes, we'll certainly have that form too. It's just a little cumbersome
to use that to interpolate multiple slices into a multidimensional
subscript.

@foo[0..9; reduce &infix:<;>, @array; 0..9];

But it can probably be made to work nonetheless, presuming the list
interpolator respects interpolated multidimensional lists somehow.
Perhaps the dimensions are separated internally by some kind of
() xx Omega value to turn them surreal for contexts that care.

Larry

Juerd

unread,
May 4, 2005, 9:40:08 AM5/4/05
to Uri Guttman, perl6-l...@perl.org
Uri Guttman skribis 2005-05-04 9:23 (-0400):

> you are brainfucking me! stop it now!!

+++++++[>++++++++++<-]>+++.<++++[>>++++++++<<-]>>.
<<++++++++[>++++<-]>-.-------.<+++++++[>+++<-]>.<+
++[>------<-]>+.>.<<+++[>+++<-]>.+.>.<<+++[>--<-]>
.-----.+.----.>.<<++++[>+++++<-]>++.<+++[>-----<-]
>.<+++[>--<-]>-.<++++[>++++<-]>+++.>.<+++++.------
----.++++++.>.<<+++[>---<-]>+.--------.----.<+++[>
++++<-]>+.<+++++++[>-----------<-]>.

Aaron Sherman

unread,
May 4, 2005, 9:34:28 AM5/4/05
to Larry Wall, Perl6 Language List
On Wed, 2005-05-04 at 09:06, Larry Wall wrote:
> On Wed, May 04, 2005 at 09:00:46AM -0400, Aaron Sherman wrote:
> : That said, let me try to be helpful, and not just complain:
> :
> : $sum = (+) @array;

> It's certainly one of the ones I considered, along with all the other


> brackets, and |+|, plus variants

I could see [], but the others don't have any mnemonic for
list-opification.

Hmmm...

$sum = [+] @array

Nice.

> It just seemed like it'd be a little
> visually confusing where you want to turn the list op into a function
>
> $sum = (+)(@array);

$sum = [+](1,2,3);

Not bad, not bad.

> But maybe that's not a problem. But there are other potential
> ambiguities besides visual, I suspect.

Juerd mentioned x, which is certainly one such. Any \w+ keyword is going
to be a problem, but I think you can make the case for any:

sub infix:foo($a,$b){...}

enforcing correct handling of:

sub list:[foo](*@list) {...}

Oh hey, I just made up "list:..." There's nothing for that listed in
A12, and that handy table from A12 doesn't show up in S12 or S13... is
that an oversight? Have new categories been added?

Larry Wall

unread,
May 4, 2005, 9:45:18 AM5/4/05
to Perl6 Language List
On Wed, May 04, 2005 at 09:34:28AM -0400, Aaron Sherman wrote:

: On Wed, 2005-05-04 at 09:06, Larry Wall wrote:
: > On Wed, May 04, 2005 at 09:00:46AM -0400, Aaron Sherman wrote:
: > : That said, let me try to be helpful, and not just complain:
: > :
: > : $sum = (+) @array;
:
: > It's certainly one of the ones I considered, along with all the other
: > brackets, and |+|, plus variants
:
: I could see [], but the others don't have any mnemonic for
: list-opification.
:
: Hmmm...
:
: $sum = [+] @array
:
: Nice.

I just thought that'd be visually confusing in a subscript:

@foo[0..9; [;]@array; 0..9]

But maybe it's not so bad.

: > It just seemed like it'd be a little


: > visually confusing where you want to turn the list op into a function
: >
: > $sum = (+)(@array);
:
: $sum = [+](1,2,3);
:
: Not bad, not bad.
:
: > But maybe that's not a problem. But there are other potential
: > ambiguities besides visual, I suspect.
:
: Juerd mentioned x, which is certainly one such. Any \w+ keyword is going
: to be a problem, but I think you can make the case for any:
:
: sub infix:foo($a,$b){...}
:
: enforcing correct handling of:
:
: sub list:[foo](*@list) {...}

Yes, but it is rather ambiguous for any unary that can take $_, like

[int]

but that's not an infix, and there isn't that much overlap, so it could
probably be made to work, and not be too confusing, at least until
someone adds an infix:<int> operator...

Larry

Larry Wall

unread,
May 4, 2005, 9:37:55 AM5/4/05
to Perl6 Language List
On Wed, May 04, 2005 at 09:34:28AM -0400, Aaron Sherman wrote:
: Oh hey, I just made up "list:..." There's nothing for that listed in

: A12, and that handy table from A12 doesn't show up in S12 or S13... is
: that an oversight? Have new categories been added?

List ops are probably just prefix: with a slurpy arg.

Larry

Aaron Sherman

unread,
May 4, 2005, 9:55:57 AM5/4/05
to Larry Wall, Perl6 Language List
On Wed, 2005-05-04 at 09:45, Larry Wall wrote:
> On Wed, May 04, 2005 at 09:34:28AM -0400, Aaron Sherman wrote:

> : Hmmm...
> :
> : $sum = [+] @array
> :
> : Nice.
>
> I just thought that'd be visually confusing in a subscript:
>
> @foo[0..9; [;]@array; 0..9]

Now, why did I think you wouldn't have already considered every
permutation? ;-)

> But maybe it's not so bad.

Yeah, it's confusing in some places, but I think they're mostly edges.

> Yes, but it is rather ambiguous for any unary that can take $_, like
>
> [int]
>
> but that's not an infix, and there isn't that much overlap, so it could
> probably be made to work, and not be too confusing, at least until
> someone adds an infix:<int> operator...

And they could get a warning that tells them of the potential conflict
when they do....

I don't think there's a perfect solution for what you want, but this is
pretty darned close.

Aaron Sherman

unread,
May 4, 2005, 9:51:20 AM5/4/05
to Uri Guttman, Perl6 Language List
On Wed, 2005-05-04 at 09:23, Uri Guttman wrote:
> >>>>> "J" == Juerd <ju...@convolution.nl> writes:
>
> J> Juerd skribis 2005-05-04 14:53 (+0200):
> >> @foo ==> zip <== @bar
>
> J> Hmmmm...
>
> J> @quux
> J> ||
> J> ||
> J> \/
> J> @foo ==> zip <== @bar
> J> /\
> J> ||
> J> ||
> J> @xyzzy
>
> you are brainfucking me! stop it now!!

Well, Befunge (http://en.wikipedia.org/wiki/Befunge) predates the very
poorly named brainfuck (what do you have to be on to think that's a good
name for even a joke language?!)

So I guess he's befunging you!

Larry Wall

unread,
May 4, 2005, 12:05:50 PM5/4/05
to Perl6 Language List
On Wed, May 04, 2005 at 09:55:57AM -0400, Aaron Sherman wrote:
: I don't think there's a perfect solution for what you want, but this is
: pretty darned close.

Yes, and I was always a little fond of the bracket solution since it
lets you visually distinguish

$x = [»+«] @foo;

$x = [+]« @foo;

In interests of simplification, it's vaguely possible we should
replace unary * with [,], which would let *x is always mean ::*x,
but probably not.

Larry

John Williams

unread,
May 4, 2005, 11:55:31 PM5/4/05
to Larry Wall, perl6-l...@perl.org
$sum = reduce(+) @array; # macro
$sum = reduce &infix:<+> @array; # regular sub
$sum = [+] @array; # meta operator
($sum = 0) >>+=<< @array; # hyper tricks

use My::Cool::Reduce::Mixin; # unless in core
$sum = @array.reduce(+); # macro-ey method

There can never be too many ways to do it, but as one who hasn't been able
to keep very current with perl6l lately, I think a particularly relevant
question we should be asking a lot is, "How long will it take someone
reading that code to figure out what it means?"

The nice thing about "reduce" is that it is easy to find in the index.
"[+]" will not be in the index, although I'm sure it would be the first
thing one would look for. I'm not sure how many other things a newbie
will try before looking up "metacircumfix:<[ ]>" or however that is
spelled.

Also in the same light, I am not convinced that reduce is used often
enough to deserve a shorter huffman encoding. Sure it makes that fancy
slice shorter, but how much headscratching is required for a human to
parse that shortness?

Personally, I think this would be more readable, in part because the
object paradigm is widely understood.

@foo[0..9; @array.reduce(&infix<;>) ; 0..9];
@foo[0..9; @array.reduce(;) ; 0..9];

I actually kinda like the idea, in spite of coming across as a naysayer
here. It just seems like an idea that should be in a module instead of in
core, which seems like an awful strange thing to say to $Larry.

~ John Williams

P.S. I like [+] better than \\+ because I cannot figure out what \\ would
be mnemonic for.

P.P.S. We can't use (R)+ ... it's already trademarked! :)

Luke Palmer

unread,
May 5, 2005, 1:58:59 AM5/5/05
to perl6-l...@perl.org
On 5/4/05, Larry Wall <la...@wall.org> wrote:
> [<] could mean "monotonically increasing".

Not unless we make boolean operators magic. There are arguments for
doing that, but I don't really want to think about how that would be
done at the moment. Reduce over a straight-up (or left) boolean
operator doesn't make much sense...

Luke

Larry Wall

unread,
May 5, 2005, 1:02:59 AM5/5/05
to perl6-l...@perl.org
On Wed, May 04, 2005 at 09:55:31PM -0600, John Williams wrote:
: $sum = reduce(+) @array; # macro

That one suffers the operator/term confusion I mentioned earlier.

: $sum = reduce &infix:<+> @array; # regular sub

That one's complicated enough that you actually installed a syntax error.

: $sum = [+] @array; # meta operator

That's rather pretty. :-)

: ($sum = 0) >>+=<< @array; # hyper tricks

That's rather ugly.

: use My::Cool::Reduce::Mixin; # unless in core


: $sum = @array.reduce(+); # macro-ey method

Macro methods are probably not going to be in anyone's Best Practices book.

: There can never be too many ways to do it, but as one who hasn't been able


: to keep very current with perl6l lately, I think a particularly relevant
: question we should be asking a lot is, "How long will it take someone
: reading that code to figure out what it means?"

It would be nice to have an easy-to-access "What's this?" interface
that could be stitched into your favorite editor to identify what's
under the cursor, or at least a command like:

p6explain '[+]'

: The nice thing about "reduce" is that it is easy to find in the index.


: "[+]" will not be in the index, although I'm sure it would be the first
: thing one would look for. I'm not sure how many other things a newbie
: will try before looking up "metacircumfix:<[ ]>" or however that is
: spelled.

I think a p6explain would be a rather popular program.

: Also in the same light, I am not convinced that reduce is used often


: enough to deserve a shorter huffman encoding. Sure it makes that fancy
: slice shorter, but how much headscratching is required for a human to
: parse that shortness?

That has to be balanced out against the probability that it will soon
be learned by the newbie, especially if it gets into popular idioms.
For instance, since ~@foo is going to install spaces between elements
just like "@foo", we might see frequently [~]@foo to do join('',@foo).
Sum of squares is now [+](@foo »*« @foo) or [+](@foo »**« 2).
We'll probably see [//] and [||] now and then. Lisp hackers will
probably like [=>] to turn a flat list into a car/cdr list. [<]


could mean "monotonically increasing".

: Personally, I think this would be more readable, in part because the


: object paradigm is widely understood.
:
: @foo[0..9; @array.reduce(&infix<;>) ; 0..9];
: @foo[0..9; @array.reduce(;) ; 0..9];

Well, we're also trying to give the mathematicians various kinds of
built-in syntactic relief where it doesn't greatly interfere with
one's sanity. The verbose approach would really turn off the PDLers.

: I actually kinda like the idea, in spite of coming across as a naysayer


: here. It just seems like an idea that should be in a module instead of in
: core, which seems like an awful strange thing to say to $Larry.

As I said in another message, I think this one is kind of a no-brainer
to teach to newbies, since like += it can be taught as a rewrite rule.
I would like it to be as much a part of core Perl as += is.

It also might be slightly easier to optimize something like [+] than
its less direct counterparts.

Larry

Damian Conway

unread,
May 5, 2005, 2:41:41 AM5/5/05
to perl6-l...@perl.org
Luke Palmer wrote:

But the comparators *are* magic in Perl 6. They're not binary, they're n-ary.
So, since:

[<] @vals

actually means:

@vals[0] < @vals[1] < @vals[2] < @vals[3]

we get the n-ary behaviour, which is true if those values *are* in that order.

Perhaps you're forgetting the difference between what "reduce" means
mathematically, and how its semantics are approximated in Perl 5 (in
List::Util). "Reduce" means "bung this operator in between each of the
elements of this list". But there's no way[*] to do that directly in Perl 5,
so we currently have to live with a pairwise binary approximation.

That's perhaps the nicest feature of Larry's proposed reduction operator: that
it will finally allow us to implement the real semantics of "reduce" and so
get all the handy metaoperators (sum, product, sum-of-squares, monotonicity,
first-true, first-defined) we've been missing to date.

Damian

[*] Okay, that's not strictly true. Evil Damian is already contemplating how
to implement n-ary reduction in Perl 5. Bwah-ha-ha-ha!

Larry Wall

unread,
May 5, 2005, 2:30:45 AM5/5/05
to perl6-l...@perl.org

It could be admitted under the rewrite rule as applied to chaining
comparison operators, such that

if [<](1,2,3) {...}

is the same as

if 1 < 2 < 3 {...}

Likewise, one could write [|] to mean "any" and [&] to mean "all",
but that'd be kind of silly.

On the other hand, I freely admit that those don't work under a recursive
binary view that artificially forces left-associativity.

Larry

Leopold Toetsch

unread,
May 5, 2005, 6:13:15 AM5/5/05
to Larry Wall, perl6-l...@perl.org
Larry Wall <la...@wall.org> wrote:

> It would be nice to have an easy-to-access "What's this?" interface
> that could be stitched into your favorite editor to identify what's
> under the cursor, or at least a command like:

> p6explain '[+]'

s:p5/nice to have/absolutely necessary/ unless $self ~~ @larry;

Could $EDITOR-p6explain use life information from the parser with the
current context of the requested token?

leo

John Williams

unread,
May 5, 2005, 2:28:39 PM5/5/05
to Larry Wall, perl6-l...@perl.org
On Wed, 4 May 2005, Larry Wall wrote:
> It would be nice to have an easy-to-access "What's this?" interface
> that could be stitched into your favorite editor to identify what's
> under the cursor, or at least a command like:
>
> p6explain '[+]'

That would make me extremely happy.

> : $sum = [+] @array; # meta operator

Another random thought which came to me (right after "\\+" could be
mnemonic for "return a function ref for this operator") was this:

How does [+] know you mean

reduce &infix:<+>, @array;

instead of

reduce &prefix:<+>, @array;

which is nonsense, but the [+] is in a prefix position.

With the hyper metaoperator, the real operator is always in the place
where it would normally be parsed. But this metaoperator pulls the real
operator out of its usual pre/in/post position.

I suppose users will need to know the answer when they start trying to
write their own metaoperators.

Maybe the metaoperator's function signature resolves that somehow?
But I haven't been following the function signature thread closely.

I can see how to ask for a binary (hence infix) operator, but how do I ask
for a prefix or postfix operator specifically, which +<< and >>+ do?
Maybe there are Operator::Prefix, etc, roles defined so you can ask for
them?

~ John Williams


A06 typo:

> infix:+( prefix:-($a), $b)
>
> [Update: That's now
>
> infix:<+>( prefix:-($a), $b)
>
> .]

The correction only corrected one of the errors:

infix:<+>( prefix:<->($a), $b)

John Williams

unread,
May 5, 2005, 2:55:30 PM5/5/05
to David Wheeler, Larry Wall, perl6-l...@perl.org
On Thu, 5 May 2005, David Wheeler wrote:

> > I can see how to ask for a binary (hence infix) operator, but how
> > do I ask
> > for a prefix or postfix operator specifically, which +<< and >>+ do?
> > Maybe there are Operator::Prefix, etc, roles defined so you can ask
> > for
> > them?
>

> Ask for them for what?

For negating all elements of an array:

@negatives = -« @positives;

> They should write them [metaoperators] only for infix operators.

The above example is in S03, so that is not an option.

> Because [] applies only to infix operators, as I understand it.

You understand it. I understand it. But how does the parser know the
difference between

@x = -<< @y;

and

@x = [+] @y;

or even

@x -= @y;

which shows that the position of metaoperator is not the distinguishing
factor.


Rob Kinyon

unread,
May 5, 2005, 3:03:22 PM5/5/05
to perl6-l...@perl.org
Can I put an operator in a variable and then use it in the []
reduce meta-operator? Something like:

$op = '+';
$x = [$op] @x;

Rob

John Williams

unread,
May 5, 2005, 3:28:27 PM5/5/05
to David Wheeler, Larry Wall, perl6-l...@perl.org
On Thu, 5 May 2005, John Williams wrote:
> or even
>
> @x -= @y;

Doh! That should be C< $x -= $y; > of course.

Larry Wall

unread,
May 5, 2005, 3:13:45 PM5/5/05
to perl6-l...@perl.org
On Thu, May 05, 2005 at 03:03:22PM -0400, Rob Kinyon wrote:
: Can I put an operator in a variable and then use it in the []

: reduce meta-operator? Something like:
:
: $op = '+';
: $x = [$op] @x;

Nope. That would be parsed as a list of one element, followed by a
syntax error. You'll have to use the long form with &infix:{$op} for
that sort of run-time indirection. (Or haul out the big cannon, eval.)

Larry

Stuart Cook

unread,
May 5, 2005, 8:55:08 PM5/5/05
to perl6-l...@perl.org
If I understand correctly, so far we have the following meta-operators:

[ ]
circumfix meta-operator on infix operator which produces a prefix operator

>> <<
circumfix meta-operator on infix operator which produces an infix operator

=
postfix meta-operator on infix operator which produces an infix operator

>>
prefix meta-operator on postfix operator which produces a postfix operator

<<
postfix meta-operator on prefix operator which produces a prefix operator

In other words:
+---------+-----------+-------------+------------+
| Meta-op | is | operates on | to produce |
+---------+-----------+-------------+------------+
| [ ] | circumfix | infix | prefix |
+---------+-----------+-------------+------------+
| >> << | circumfix | infix | infix |
+---------+-----------+-------------+------------+
| = | postfix | infix | infix |
+---------+-----------+-------------+------------+
| >> | prefix | postfix | postfix |
+---------+-----------+-------------+------------+
| << | postfix | prefix | prefix |
+---------+-----------+-------------+------------+

From this table, we can see that [ ] is the only meta-operator that
produces a different 'type' of operator from that which it accepts,
which might be where the confusion lies. As long as each meta-operator
explicitly knows what type of regular operator it accepts (and
produces), there shouldn't be any problems with ambiguity.

Brent 'Dax' Royal-Gordon

unread,
May 5, 2005, 10:20:03 PM5/5/05