Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Outer product considered useful

4 views
Skip to first unread message

Luke Palmer

unread,
Mar 22, 2004, 7:07:31 PM3/22/04
to Language List
I found myself writing a perl script today in which I did (I'll
perl6-ize it for sake of discussion):

for 98,99 -> $i {
for 0..255 -> $j {
# testing IP addresses with $i.$j
}
}

I was thinking about what would happen if I allowed the user to input
those ranges, like:

67.173.[98,99].[0..255]

After appropriate data massagng, I'd have to do something like:

for @(@ranges[1]) -> $i {
for @(@ranges[2]) -> $j {
for @(@ranges[3]) -> $k {
for @(@ranges[4]) -> $l {
# ...
}
}
}
}

Using a permutations module I could make that shorter, but I figure that
since we're already providing C<zip> to make looping easier, why not
provide C<outer> (perhaps spelled °)? The outer function would provide
a way to I<dynamically> nest loops.

for outer(*@ranges) -> [ $i, $j, $k, $l ]
{
# ...
}

Or better yet:

for outer(*@ranges) -> @cp {
my $ip = @cp.join('.');
}

And the original loop could be written:

for 98,99 ° 0..255 -> [$i, $j] {
# ...
}

Supposing ° had sufficiently low precedence. And supposing ° were used
at all, something I'm not particuarly attached to happening.

I believe it could be programmed lazily. Like this:

sub _outer_coro(*$first is context(Scalar),
*@rest is context(Scalar))
is coroutine
{
if @rest {
_outer_coro *@rest;
}
else {
yield $first;
}
}

sub outer(*@data is context(Scalar))
{
<_outer_coro(*@data)>
}

Luke

Luke Palmer

unread,
Mar 22, 2004, 7:21:59 PM3/22/04
to Language List
Luke Palmer writes:
> I believe it could be programmed lazily. Like this:
>
> sub _outer_coro(*$first is context(Scalar),
> *@rest is context(Scalar))
> is coroutine
> {
> if @rest {
> _outer_coro *@rest;
> }
> else {
> yield $first;
> }
> }
>
> sub outer(*@data is context(Scalar))
> {
> <_outer_coro(*@data)>
> }

Which is of course wrong.

sub _outer_coro(@prev, @data) is coroutine
{
if (@data) {
_outer_coro([ @prev, @data[0] ], @data[1...])
}
else {
yield \@prev;
}
}

sub outer(*@data is context(Scalar))
{
<_outer_coro([], @data)>
}

Luke

Luke Palmer

unread,
Mar 22, 2004, 7:29:27 PM3/22/04
to Language List
Luke Palmer writes:
> Which is of course wrong.
>
> sub _outer_coro(@prev, @data) is coroutine
> {
> if (@data) {
> _outer_coro([ @prev, @data[0] ], @data[1...])
> }
> else {
> yield \@prev;
> }
> }
>
> sub outer(*@data is context(Scalar))
> {
> <_outer_coro([], @data)>
> }

I'm just going to stop trying after this one.

sub _outer_coro(@prev, @data) is coroutine
{
if (@data) {

_outer_coro([ @prev, $_ ], @data[1...]) for @(@data[0]);

Austin Hastings

unread,
Mar 22, 2004, 7:48:17 PM3/22/04
to Luke Palmer, Language List
> -----Original Message-----
> From: Luke Palmer [mailto:lu...@luqui.org]
>

...

> Using a permutations module I could make that shorter, but I figure that
> since we're already providing C<zip> to make looping easier, why not
> provide C<outer> (perhaps spelled °)? The outer function would provide
> a way to I<dynamically> nest loops.
>
> for outer(*@ranges) -> [ $i, $j, $k, $l ]
> {
> # ...
> }
>
> Or better yet:
>
> for outer(*@ranges) -> @cp {
> my $ip = @cp.join('.');
> }
>

Before this gets simonized, let me add that this seems genuinely useful: It provides a way of constructing a loop in a dimension that is not really accessible, except via recursion.

Luke: Would that have to be

for outer(*@ranges) ->« @cp {...}

?

> Supposing ° had sufficiently low precedence. And supposing ° were used
> at all, something I'm not particuarly attached to happening.

I'm opposed to it: bad huffman coding.

> I believe it could be programmed lazily. Like this:

> sub _outer_coro(*$first is context(Scalar),
> *@rest is context(Scalar))
> is coroutine
> {
> if @rest {
> _outer_coro *@rest;
> }
> else {
> yield $first;
> }
> }
>
> sub outer(*@data is context(Scalar))
> {
> <_outer_coro(*@data)>
> }

I find this code utterly baffling. How does this yield 255.255.0.[0..2] ?

Or is this supposed to be yielding iterators, in which case it seems to reverse them?

=Austin

Simon Cozens

unread,
Mar 22, 2004, 7:51:04 PM3/22/04
to perl6-l...@perl.org
Austin_...@Yahoo.com (Austin Hastings) writes:
> Before this gets simonized, let me add that this seems genuinely useful: It provides a way of constructing a loop in a dimension that is not really accessible, except via recursion.

Oh, it *is* useful, and it's extremely nice to know that something like this
will be able to be done as a user-defined extension, outside the core, or even
in the standard library, I don't mind, once the Perl 6 core itself gets
designed and implemented.

--
Be not anxious about what you have, but about what you are.
-- Pope St. Gregory I

Austin Hastings

unread,
Mar 22, 2004, 8:31:30 PM3/22/04
to perl6-l...@perl.org
> -----Original Message-----
> From: si...@alibi.simon-cozens.org
>
> Austin_...@Yahoo.com (Austin Hastings) writes:
> > Before this gets simonized, let me add that this seems
> genuinely useful: It provides a way of constructing a loop in a
> dimension that is not really accessible, except via recursion.
>
> Oh, it *is* useful, and it's extremely nice to know that
> something like this will be able to be done as a user-defined
> extension, outside the core, or even in the standard library,
> I don't mind, once the Perl 6 core itself gets designed and
> implemented.

Granted it can be a UDF. My interest is more in the question "What else have
we omitted?"

As I recall, the discussion a while back about iterators quickly mutated
into a discussion on how to do coroutines. We never actually explored the
"what cool things are possible with iterators as a basic data object/type"
question.

Luke just illuminated one of those dark corners for us:

"By applying iteration to iterators, you can express
complex code structures via arrays.

"Also, you can reclaim the FORTRAN variable namespace
($i..$n) for other uses."

Cool:- thinking on it, the fact that every damn coding book on the planet
has a section about nesting loops should have been a flag that P6l should be
looking at that.

What else have we missed?

=Austin

PS: The thought just occurred to me that C<outer> enables something like:

for outer(*grep ...) -> @indices {...}

which means that the code structure gets even more dynamic.

I wonder if it's possible to code C<outer> to handle variable length, like
walking a graph. (Garbage collector, anyone?) That would be C<traverse>, or
<enumerate>. Good for walking XML, too.

Luke Palmer

unread,
Mar 22, 2004, 11:09:26 PM3/22/04
to Austin Hastings, Language List
Austin Hastings writes:
> Before this gets simonized, let me add that this seems genuinely
> useful: It provides a way of constructing a loop in a dimension that
> is not really accessible, except via recursion.
>
> Luke: Would that have to be
>
> for outer(*@ranges) ->« @cp {...}
>
> ?

->« @cp makes about as much sense as sub«(@cp). C<outer> returns a
list of array references, right? So it binds each one to @cp (the right
of -> is a subroutine parameter list, remember?).

> > Supposing ° had sufficiently low precedence. And supposing ° were used
> > at all, something I'm not particuarly attached to happening.
>
> I'm opposed to it: bad huffman coding.

That's why it's a non-ascii operator. But I agree, there's really no
need for an operator here.

> > I believe it could be programmed lazily. Like this:
>
> > sub _outer_coro(*$first is context(Scalar),
> > *@rest is context(Scalar))
> > is coroutine
> > {
> > if @rest {
> > _outer_coro *@rest;
> > }
> > else {
> > yield $first;
> > }
> > }
> >
> > sub outer(*@data is context(Scalar))
> > {
> > <_outer_coro(*@data)>
> > }
>
> I find this code utterly baffling. How does this yield 255.255.0.[0..2] ?

It doesn't. You probably noticed by my numerous replys fixing the
numerous bugs in that code.

Luke

Austin Hastings

unread,
Mar 22, 2004, 11:26:03 PM3/22/04
to Luke Palmer, Language List

> -----Original Message-----
> From: Luke Palmer [mailto:lu...@luqui.org]
>

> Austin Hastings writes:
> > Before this gets simonized, let me add that this seems genuinely
> > useful: It provides a way of constructing a loop in a dimension that
> > is not really accessible, except via recursion.
> >
> > Luke: Would that have to be
> >
> > for outer(*@ranges) ->« @cp {...}
> >
> > ?
>
> ->« @cp makes about as much sense as sub«(@cp). C<outer> returns a
> list of array references, right? So it binds each one to @cp (the right
> of -> is a subroutine parameter list, remember?).

Are you saying that sub«(@cp) is not, in fact, an alias for C<map &sub, @cp> ?

Anyway, I ask because I wonder what happens if @cp happens to contain some discrete number of elements that is not equal to the number returned by C<outer>?

IOW:

@cp = (1, 2, 3);
for outer([0..255] xx 4) -> @cp {...}

Does the current number of entries have any impact?

for outer(@a, @b, @c) -> ($a, undef, $c) {...}

Does that work?

> > I'm opposed to it: bad huffman coding.
>
> That's why it's a non-ascii operator. But I agree, there's really no
> need for an operator here.

And more to the point, the fact that we've "opened the (code) page" doesn't mean that we have an infinite supply of iso-latin-1 glyphs. We'd be prudent to conserve them.

=Austin

Luke Palmer

unread,
Mar 22, 2004, 11:32:52 PM3/22/04
to Austin Hastings, Language List
Austin Hastings writes:
> > ->« @cp makes about as much sense as sub«(@cp). C<outer> returns a
> > list of array references, right? So it binds each one to @cp (the right
> > of -> is a subroutine parameter list, remember?).
>
> Are you saying that sub«(@cp) is not, in fact, an alias for C<map &sub, @cp> ?
>
> Anyway, I ask because I wonder what happens if @cp happens to contain some discrete number of elements that is not equal to the number returned by C<outer>?
>
> IOW:
>
> @cp = (1, 2, 3);
> for outer([0..255] xx 4) -> @cp {...}
>
> Does the current number of entries have any impact?
>
> for outer(@a, @b, @c) -> ($a, undef, $c) {...}
>
> Does that work?

Allow me to rewrite the loop to clarify. This has the exact same
semantic effect (as long as there is no C<return> within the loop
body), and pretty close to the same parse:

for outer(@a, @b, @c), sub (@cp) {...}

And now you can see that the previous contents of @cp don't mean
anything, because you're working with a different variable entirely. It
just happens to share the same name, but it's associated with a
different lexical scope.

The reason that:

for outer(@a, @b, @c) -> [$a, $b, $c] {...}

Works comes from Apocalypse 6, which states that a parameter list can be
placed in square brackets to indicate that an array is expected, and
that it will be decomposed as a separate, nested parameter list.

At first, I thought that was an unnecessary, bloating feature, but now I
see how marvelously useful it is :-)

Oh, by the way, this:

for outer([0..255] xx 4) -> @cp {...}

Needs to be written:

for outer(*[0..255] xx 4) -> @cp {...}

(Or even:

for outer(*([0..255] xx 4)) -> @cp {...}

depending on the precedence of unary *)

Luke

Smylers

unread,
Mar 23, 2004, 12:33:18 PM3/23/04
to perl6-l...@perl.org
Luke Palmer writes:

> for @(@ranges[1]) -> $i {

Oooh, where did that dereferencing syntax come from, using parens rather
than braces?

Smylers

Brent 'Dax' Royal-Gordon

unread,
Mar 23, 2004, 12:53:35 PM3/23/04
to Smylers, perl6-l...@perl.org

It isn't a dereferencing syntax--it's a context-forcing syntax (one I'm
intimately familiar with), which forces @ranges[1] into list context.
Which shouldn't affect anything. So I think it's probably a mistake.

--
Brent "Dax" Royal-Gordon <br...@brentdax.com>
Perl and Parrot hacker

Oceania has always been at war with Eastasia.

Goplat

unread,
Mar 23, 2004, 1:11:30 PM3/23/04
to perl6-l...@perl.org

@(...) is the "list context" operator in S3. I hope array references won't
explode in list context, that would be very annoying when making
multi-dimentional arrays:

@foo = ([1, 2], [3, 4]) # oops, would be (1, 2, 3, 4)
@foo = ($([1, 2]), $([3, 4])) # ugh :(

__________________________________
Do you Yahoo!?
Yahoo! Finance Tax Center - File online. File on time.
http://taxes.yahoo.com/filing.html

Aaron Sherman

unread,
Mar 25, 2004, 9:17:01 AM3/25/04
to Perl6 Language List
On Tue, 2004-03-23 at 13:11, Goplat wrote:

> @(...) is the "list context" operator in S3. I hope array references won't
> explode in list context, that would be very annoying when making
> multi-dimentional arrays:
>
> @foo = ([1, 2], [3, 4]) # oops, would be (1, 2, 3, 4)
> @foo = ($([1, 2]), $([3, 4])) # ugh :(

I would expect [] to force itself into scalar context anyway. Is there
ever a reason to want otherwise? Clearly the entire point of [] is to
create a scalar array ref from a list of arguments.

More to the point is there ever a reason to want any array ref in list
context to NOT explode other than []? I can't think of any.

push @a, $b

Is it too non-obvious that if $b is an array ref, then this is going to
extend @a by $b.length elements?

Pardon my ignorance, but I thought this was the plan. Feel free to
correct me if I am wrong.

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

signature.asc

Luke Palmer

unread,
Mar 25, 2004, 10:42:53 AM3/25/04
to Aaron Sherman, Perl6 Language List
Aaron Sherman writes:
> I would expect [] to force itself into scalar context anyway. Is there
> ever a reason to want otherwise? Clearly the entire point of [] is to
> create a scalar array ref from a list of arguments.
>
> More to the point is there ever a reason to want any array ref in list
> context to NOT explode other than []? I can't think of any.
>
> push @a, $b
>
> Is it too non-obvious that if $b is an array ref, then this is going to
> extend @a by $b.length elements?

Quite a bit too subtle, yes. While array references are now doing many
of the same things in similar contexts as arrays, flattening in list
context is not one of them. Array references are still different beasts
from arrays. Your push example is one of the reasons why.

Some time back, Larry said that you had to do:

push @a, @$b;

Just like in Perl 5. But this was before * was a unary operator instead
of a context forcing operator. That is, as of A6:

sub foo(@a, @b, @c, @d, @e);
foo(@a, @b, *@c, @d); # Flatten @c and @d into the parameter list

But now, it's:

foo(@a, @b, *@c, @d); # Flatten @c into the parameter list

So that might mean that push looks like:

push @a, *$b;

Luke

Larry Wall

unread,
Mar 25, 2004, 1:14:26 PM3/25/04
to Perl6 Language List
On Thu, Mar 25, 2004 at 08:42:53AM -0700, Luke Palmer wrote:
: Aaron Sherman writes:
: > More to the point is there ever a reason to want any array ref in list

: > context to NOT explode other than []? I can't think of any.
: >
: > push @a, $b
: >
: > Is it too non-obvious that if $b is an array ref, then this is going to
: > extend @a by $b.length elements?
:
: Quite a bit too subtle, yes. While array references are now doing many
: of the same things in similar contexts as arrays, flattening in list
: context is not one of them. Array references are still different beasts
: from arrays. Your push example is one of the reasons why.

Yes, things that look like scalars have to stay scalars in list context.

: Some time back, Larry said that you had to do:


:
: push @a, @$b;
:
: Just like in Perl 5. But this was before * was a unary operator instead
: of a context forcing operator. That is, as of A6:
:
: sub foo(@a, @b, @c, @d, @e);
: foo(@a, @b, *@c, @d); # Flatten @c and @d into the parameter list
:
: But now, it's:
:
: foo(@a, @b, *@c, @d); # Flatten @c into the parameter list
:
: So that might mean that push looks like:
:
: push @a, *$b;

Yes, * was originally a no-op in list context, but I think now we can
use it to deref a list that would otherwise not interpolate itself.
It maps better onto how a C programmer thinks, and if in scalar
context it also happens to defer the signature checking to use the
interpolated values, that's just an extra bonus.

However, we'll have to be a little careful about calling it a
"flattening" operator, because it isn't exactly... Normal list context
only flattens notionally in Perl 6, and the actual flattening is done
lazily by default. If you really, truly want it flattened Right Now,
you have to use unary ** instead (by analogy to the ** prefix in the
declaration, or is it the other way around now?). But usually you
want the * semantics such that, if a lazy list is interpolated into
the list, it's just another generator in that list. To wit:

$foo = 0...; # take ref to an infinite range
@bar = $foo; # puts in the iterator as a reference
say @bar.elems; # prints 1
@bar = *$foo; # puts in 0...
say @bar.elems; # prints Inf
@bar = **$foo; # throws exception: "Please install a lot more memory"

It seems to be a useful mnemonic that, loosely speaking, ** is always
an "exponential" operator, one way or another... :-)

Larry

Brent 'Dax' Royal-Gordon

unread,
Mar 25, 2004, 2:35:46 PM3/25/04
to Larry Wall, Perl6 Language List
Larry Wall wrote:
> say @bar.elems; # prints 1

C<say>? Not C<print>?

Larry Wall

unread,
Mar 25, 2004, 3:33:21 PM3/25/04
to Perl6 Language List
On Thu, Mar 25, 2004 at 11:35:46AM -0800, Brent 'Dax' Royal-Gordon wrote:
: Larry Wall wrote:
: > say @bar.elems; # prints 1
:
: C<say>? Not C<print>?

It's just a "println" spelled Huffmanly.

Larry

James Mastros

unread,
Mar 26, 2004, 2:59:36 AM3/26/04
to perl6-l...@perl.org
Larry Wall wrote:
> Yes, * was originally a no-op in list context, but I think now we can
> use it to deref a list that would otherwise not interpolate itself.
> It maps better onto how a C programmer thinks, and if in scalar
> context it also happens to defer the signature checking to use the
> interpolated values, that's just an extra bonus.
No! Please, God, no! I like perl, in no small part, because references
are less confusing then pointers. Pointers, in no small part, are
confusing because "*" means both "this is a pointer" (as in "int*"), and
"give me the thingy at" (as in "chr=*str").

It seems like this is creating the same confusion.

> $foo = 0...; # take ref to an infinite range
> @bar = $foo; # puts in the iterator as a reference
> say @bar.elems; # prints 1
> @bar = *$foo; # puts in 0...
> say @bar.elems; # prints Inf
> @bar = **$foo; # throws exception: "Please install a lot more memory"

I hope that Perl will be intelegent enough to notice that the range is
infinite, and say "attempt to flatten infinite list" rather then
"ENOMEM" here.

Also, how does the use of *$foo differ from @$foo here? Is the later
going away? (I'd think that horrible, for the same reason as above: C
is confusing because it's not always clear what you get when you *.)

By the way, I like say, but wonder if we're going to become a horrible
mix of APL and PHP. At least we don't have a Unicode alias for say
(yet, why do I suspect we're about to get a unary » operator for it?
Perhaps I'm just pessimistic this morning.)

-=- James Mastros

Larry Wall

unread,
Mar 26, 2004, 11:16:07 AM3/26/04
to perl6-l...@perl.org
On Fri, Mar 26, 2004 at 08:59:36AM +0100, James Mastros wrote:
: Larry Wall wrote:
: >Yes, * was originally a no-op in list context, but I think now we can
: >use it to deref a list that would otherwise not interpolate itself.
: >It maps better onto how a C programmer thinks, and if in scalar
: >context it also happens to defer the signature checking to use the
: >interpolated values, that's just an extra bonus.
: No! Please, God, no! I like perl, in no small part, because references
: are less confusing then pointers. Pointers, in no small part, are
: confusing because "*" means both "this is a pointer" (as in "int*"), and
: "give me the thingy at" (as in "chr=*str").
:
: It seems like this is creating the same confusion.

No, the confusion in C is because you never know whether * indicates a
single item or the start of a list. In Perl it will only indicate
that something should be considered listier than it otherwise would.

: > $foo = 0...; # take ref to an infinite range


: > @bar = $foo; # puts in the iterator as a reference
: > say @bar.elems; # prints 1
: > @bar = *$foo; # puts in 0...
: > say @bar.elems; # prints Inf
: > @bar = **$foo; # throws exception: "Please install a lot more
: > memory"
: I hope that Perl will be intelegent enough to notice that the range is
: infinite, and say "attempt to flatten infinite list" rather then
: "ENOMEM" here.

Er, that was a joke...

: Also, how does the use of *$foo differ from @$foo here? Is the later

: going away? (I'd think that horrible, for the same reason as above: C
: is confusing because it's not always clear what you get when you *.)

No, @$foo is not going away. You can write it that way when you think
it's clearer. The primary use of * is still to defeat the signature,
and @$foo doesn't do that.

: By the way, I like say, but wonder if we're going to become a horrible

: mix of APL and PHP. At least we don't have a Unicode alias for say
: (yet, why do I suspect we're about to get a unary » operator for it?

I will let other people define their own Unicode alias for "say". And
I hope it takes them more than three keystrokes to type. :-)

And "say" isn't in there because of APL or PHP. It's actually inspired
by something worse in Ruby.

: Perhaps I'm just pessimistic this morning.)

Don't slit your wrists just yet...

Larry

Mark J. Reed

unread,
Mar 26, 2004, 11:40:30 AM3/26/04
to perl6-l...@perl.org

On 2004-03-26 at 08:16:07, Larry Wall wrote:
> And "say" isn't in there because of APL or PHP. It's actually inspired
> by something worse in Ruby.

Presumably by "something worse" you mean "puts"? Not a great name, to
be sure, but it does have a venerable tradition behind it. :)

I do like having an auto-newline-appending version of print (without
having to make *all* my prints behave that way via -l), and my Perl
scripts of late often begin with a
sub puts(@) { for (@_) { print "$_\n" } }.

Of course, then I start forgetting my semicolons . . .

-Mark

Luke Palmer

unread,
Mar 26, 2004, 11:41:23 AM3/26/04
to perl6-l...@perl.org
Larry Wall writes:
> : Also, how does the use of *$foo differ from @$foo here? Is the later
> : going away? (I'd think that horrible, for the same reason as above: C
> : is confusing because it's not always clear what you get when you *.)
>
> No, @$foo is not going away. You can write it that way when you think
> it's clearer. The primary use of * is still to defeat the signature,
> and @$foo doesn't do that.

Okay, good. So this is correct:

my $baz = @foo;
@bar = map { ... } @$baz;

(to be equivalent of mapping over @foo)?

Is @{$foo} going away? More specifically, how do I write that map if
$baz is some more complex expression, and I don't want to use * (say I
want to adhere if map decides to change its signature to take a real
array)?

Luke

Juerd

unread,
Mar 26, 2004, 12:01:08 PM3/26/04
to Larry Wall, perl6-l...@perl.org
Larry Wall skribis 2004-03-25 12:33 (-0800):

What happened to the principle that things that work similarly should look
similarly?

I dislike having another method/function/whatever to do exactly the same
thing, yet a little different. That is PHP's niche.

Can't we instead just have a pseudo-filehandle or perhaps a tied one and
just use C<print> to print?

ln.print @bar.elems;
print ln : @bar.elems;

Though I'm not sure why a feature like this would be needed at all, so I
think this is something users should define something like this
themselves if they want it:

my &say = &print.assuming :ors "\n";

(Wildly guessing syntax here. I cincerely hope parens won't be needed.)

I think I prefer things the way they happen to already be.

print @bar.elems, "\n";

Also, I think C<say> is a bad choice. Many people use a function called
C<say> for chat bots and text-to-speech. It will of course be possible
to override the builtin, but for a good reason most people choose to not
do that.

Has this C<say> already been decided?

Juerd

Luke Palmer

unread,
Mar 26, 2004, 12:35:02 PM3/26/04
to Juerd, Larry Wall, perl6-l...@perl.org
Juerd writes:
> Larry Wall skribis 2004-03-25 12:33 (-0800):
> > On Thu, Mar 25, 2004 at 11:35:46AM -0800, Brent 'Dax' Royal-Gordon wrote:
> > : Larry Wall wrote:
> > : > say @bar.elems; # prints 1
> > : C<say>? Not C<print>?
> > It's just a "println" spelled Huffmanly.
>
> Can't we instead just have a pseudo-filehandle or perhaps a tied one and
> just use C<print> to print?
>
> ln.print @bar.elems;
> print ln : @bar.elems;
>
> Though I'm not sure why a feature like this would be needed at all, so I
> think this is something users should define something like this
> themselves if they want it:
>
> my &say = &print.assuming :ors "\n";
>
> (Wildly guessing syntax here. I cincerely hope parens won't be needed.)

Well I'm sincerely certain that they are.

my &say := &print.assuming(:ors("\n"));



> I think I prefer things the way they happen to already be.
>
> print @bar.elems, "\n";

Ugh. You do!? I think that's the biggest PITA in Perl. I never
thought of "say", but I've been known to write:

sub p { print @_, "\n" }

In some of my more verbose scripts.

It's a sign that something's wrong when on every one-liner I write, and
in even some longer scripts, I specify -l on the command line. C<say>
is indeed shorter than C<print>, and I like that, because I use it more
often.

Will there also be:

sub complain(*@_) {
print $ERR: @_, "\n";
}

:-)

> Also, I think C<say> is a bad choice. Many people use a function called
> C<say> for chat bots and text-to-speech.

Uh huh, but the ones I have experience with use it as a method, so it
doesn't interfere.

$bot.say("Welcome, $user")

Plus, a lot of people use C<index> to create an index, C<length> to find
the length of an array, C<delete> to delete files, C<study> to do their
homework, and C<die> to commit suicide (or was that C<goto>?). That's
why variables have sigils, and lexicals have scopes...

You even said yourself:

my &say := ...

That works even if C<say> is built-in.

> It will of course be possible to override the builtin, but for a good
> reason most people choose to not do that.
>
> Has this C<say> already been decided?

Doesn't matter, because most of these decisions are up for discussion.
I think everything that was "decided" when Apocalypse 3 was written has
changed at least three times (contrast with Synposis 3 :-).

Luke

Larry Wall

unread,
Mar 26, 2004, 2:53:21 PM3/26/04
to perl6-l...@perl.org
On Fri, Mar 26, 2004 at 09:41:23AM -0700, Luke Palmer wrote:
: Okay, good. So this is correct:

:
: my $baz = @foo;
: @bar = map { ... } @$baz;
:
: (to be equivalent of mapping over @foo)?

Yes, that's correct.

: Is @{$foo} going away? More specifically, how do I write that map if


: $baz is some more complex expression, and I don't want to use * (say I
: want to adhere if map decides to change its signature to take a real
: array)?

@{EXPR} still works.

Larry

Luke Palmer

unread,
Mar 26, 2004, 3:20:45 PM3/26/04
to perl6-l...@perl.org

Okay, now that that's all cleared up, time to propose something.

When writing Perl 5, I always find myself writing @{ more often than @$.
Maybe it's just a bad habit that I don't tend to use a lot of
intermediate variables.

I propose that the precedence of the of the dereferencing sigils be
loosened so I don't have to write those pesky squigglies all the time.
What used to be:

for my $i (@{$foo->{bar}[$ind]}) { }

Can now be:

for @$foo{bar}[$ind] -> $i {...}

It doesn't feel quite right, but that's probably because I've written it
the other way so much.

The only reason to keep it around is if you wanted to use the archaic:

@$foo[2];

Or if you wanted to call methods on the array:

@$foo.sort;

But since you can call methods on a reference and get them delegated
anyway, that's not a problem. And as for the first one, well, who needs
that when they can just leave off the @ altogether?

Luke

Aaron Sherman

unread,
Mar 26, 2004, 4:20:15 PM3/26/04
to Perl6 Language List
On Fri, 2004-03-26 at 15:20, Luke Palmer wrote:

> When writing Perl 5, I always find myself writing @{ more often than @$.
> Maybe it's just a bad habit that I don't tend to use a lot of
> intermediate variables.

Well, one of the big problems with Perl 5's dereferencing is that it's
painful to create intermediate variables that make it any easier. For
example, you can say "my $ref = $x{$y}{$z};@$ref" or you can say "local
*ary=$x{$y}{$z};@ary" but the latter isn't that obvious to most, and can
run afoul of strict. In Perl 6:

my @ary := %x{$y}{$z};

should make it much more likely that we'll all use those intermediates.
I also seem to recall something about a ".@" operator that would work
like so:

for %x{$y}{$z}.@ -> $i {...}

No? If everything else is chained on the right for dereferencing, I
certainly see the utility in this. Am I imagining that it was stated
earlier?

What's more that could be:

for *%x{$y}{$z} -> $i {...}

and I can't imagine it makes any sense to bind that * anywhere but:

for *(%x{$y}{$z}) -> $i {...}

I like the division between @ and *, since the two meanings had somewhat
too much overlap in most code.

Joe Gottman

unread,
Mar 26, 2004, 8:44:43 PM3/26/04
to perl6-l...@perl.org

----- Original Message -----
From: "Luke Palmer" <lu...@luqui.org>


> Juerd writes:
> > Has this C<say> already been decided?
>
> Doesn't matter, because most of these decisions are up for discussion.
> I think everything that was "decided" when Apocalypse 3 was written has
> changed at least three times (contrast with Synposis 3 :-).
>

If Larry is still adding functions to the core, maybe he can add the
"outer" function that Luke suggested last week. This function would be very
useful in inner loops, so if it is possible to implement it more efficiently
in the core than as a sub in a module I think we should do so.

Joe Gottman


Simon Cozens

unread,
Mar 27, 2004, 1:59:38 AM3/27/04
to perl6-l...@perl.org
jgot...@carolina.rr.com (Joe Gottman) writes:
> This function would be very useful in inner loops, so if it is possible to
> implement it more efficiently in the core than as a sub in a module I think
> we should do so.

And, if it's possible to implement it more efficiently in the core than as a
sub in a module that Parrot didn't live up to one of its design principles.

--
<yrlnry> I think the real problem here is that he is a university CS
professor and therefore knows very little about programming in the real
world, in any languge.

Dan Sugalski

unread,
Mar 27, 2004, 10:31:13 AM3/27/04
to perl6-l...@perl.org
At 6:59 AM +0000 3/27/04, Simon Cozens wrote:
>jgot...@carolina.rr.com (Joe Gottman) writes:
>> This function would be very useful in inner loops, so if it is possible to
>> implement it more efficiently in the core than as a sub in a module I think
>> we should do so.
>
>And, if it's possible to implement it more efficiently in the core than as a
>sub in a module that Parrot didn't live up to one of its design principles.

Erm... I suppose. As long as you've written the module code in C...
--
Dan

--------------------------------------"it's like this"-------------------
Dan Sugalski even samurai
d...@sidhe.org have teddy bears and even
teddy bears get drunk

Larry Wall

unread,
Mar 27, 2004, 11:19:18 AM3/27/04
to Dan Sugalski, perl6-l...@perl.org
On Sat, Mar 27, 2004 at 10:31:13AM -0500, Dan Sugalski wrote:
: At 6:59 AM +0000 3/27/04, Simon Cozens wrote:
: >jgot...@carolina.rr.com (Joe Gottman) writes:
: >> This function would be very useful in inner loops, so if it is possible
: >> to
: >> implement it more efficiently in the core than as a sub in a module I
: >> think
: >> we should do so.
: >
: >And, if it's possible to implement it more efficiently in the core than as
: >a
: >sub in a module that Parrot didn't live up to one of its design principles.
:
: Erm... I suppose. As long as you've written the module code in C...

Well, hey, I'm not required to decide anything about functions till
Apocalypse 29 or so... :-)

Larry

0 new messages