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

Look-ahead arguments in for loops

0 views
Skip to first unread message

Dave Whipp

unread,
Sep 29, 2005, 12:41:46 PM9/29/05
to perl6-l...@perl.org
Imagine you're writing an implementation of the unix "uniq" function:

my $prev;
for grep {defined} @in -> $x {
print $x unless defined $prev && $x eq $prev;
$prev = $x;
}

This feels clumsy. $prev seems to get in the way of what I'm trying to
say. Could we imbue optional binding with the semantics of not being
consumed?

for grep {defined} @in -> $item, ?$next {
print $item unless defined $next && $item eq $next;
}

The same behavior, but without the variable outside the loop scope.


It would also be good not to overload the meaning of $?next to also tell
us if we're at the end of the loop. In addition to FIRST{} and LAST{}
blocks, could we have some implicit lexicals:

for @in -> $item, ?$next {
print $item if $?LAST || $item ne $next
}

Austin Hastings

unread,
Sep 29, 2005, 2:08:26 PM9/29/05
to Dave Whipp, perl6-l...@perl.org
Dave Whipp wrote:

I like the idea. There's no reason the view window and the consumption
have to be the same.

=Austin

Luke Palmer

unread,
Sep 29, 2005, 3:42:19 PM9/29/05
to Dave Whipp, perl6-l...@perl.org
On 9/29/05, Dave Whipp <da...@whipp.name> wrote:
> for grep {defined} @in -> $item, ?$next {
> print $item unless defined $next && $item eq $next;
> }

This is an interesting idea. Perhaps "for" (and "map") shift the
minimum arity of the block from the given list and bind the maximum
arity. Of course, the minimum arity has to be >= 1 lest an infinite
loop occur. But then perhaps you have another way to avoid integer
indices:

for @list -> $this, *@rest {
...
}

As long as you don't look backwards. Looking backwards makes problems
for GC in lazy contexts, so this might just be perfect.

Luke

Austin Hastings

unread,
Sep 29, 2005, 5:21:18 PM9/29/05
to Dave Whipp, perl6-l...@perl.org
Luke Palmer wrote:

>>On 9/29/05, Dave Whipp <da...@whipp.name> wrote:
>
>
>>>> for grep {defined} @in -> $item, ?$next {
>>>> print $item unless defined $next && $item eq $next;
>>>> }
>>>>
>>>>
>>
>>
>
>>This is an interesting idea. Perhaps "for" (and "map") shift the
>>minimum arity of the block from the given list and bind the maximum
>>arity. Of course, the minimum arity has to be >= 1 lest an infinite
>>loop occur.
>
>

Or not. We've already seen idioms like

for (;;) ...

If you specify your minimum arity as 0, then you're obviously planning to deal with it. This presumes that iterators can handle behind-the-scenes updating, of course.


>>But then perhaps you have another way to avoid integer
>>indices:
>>
>> for @list -> $this, *@rest {
>> ...
>> }
>>
>>As long as you don't look backwards. Looking backwards makes problems
>>for GC in lazy contexts, so this might just be perfect.
>

Plus it's hard to talk about backwards. If you say

for @l -> ?$prev, $curr, ?$next {...}

what happens when you have two items in the list? I think we're best off using signature rules: optional stuff comes last.


=Austin


Matt Fowles

unread,
Sep 29, 2005, 6:36:43 PM9/29/05
to Austin_...@yahoo.com, Dave Whipp, perl6-l...@perl.org
Austin~

On 9/29/05, Austin Hastings <Austin_...@yahoo.com> wrote:
> Plus it's hard to talk about backwards. If you say
>
> for @l -> ?$prev, $curr, ?$next {...}
>
> what happens when you have two items in the list? I think we're best off using signature rules: optional stuff comes last.

I disagree, I think that is an easy call

for (1, 2) -> ?$prev, $cur, ?$next {
say "$prev -> $cur" if $prev;
say $cur;
say "$cur -> $next" if $next;
say "next";
}

should print

1
1 -> 2
next
1 -> 2
2
next

Matt
--
"Computer Science is merely the post-Turing Decline of Formal Systems Theory."
-Stan Kelly-Bootle, The Devil's DP Dictionary

Luke Palmer

unread,
Sep 29, 2005, 8:40:04 PM9/29/05
to Austin_...@yahoo.com, Dave Whipp, perl6-l...@perl.org
On 9/29/05, Austin Hastings <Austin_...@yahoo.com> wrote:
> Luke Palmer wrote:
> >>This is an interesting idea. Perhaps "for" (and "map") shift the
> >>minimum arity of the block from the given list and bind the maximum
> >>arity. Of course, the minimum arity has to be >= 1 lest an infinite
> >>loop occur.

> Or not. We've already seen idioms like
>>
> for (;;) ...
>
> If you specify your minimum arity as 0, then you're obviously planning to deal with it. This presumes that iterators can handle behind-the-scenes updating, of course.

Well, I see two reasons for not allowing arity zero. First, I think
it's too easy to come up with a function with minimum arity zero:

my @lengths = @list.map:&length # oops, infinite loop

Second, you don't get anything by doing this:

for @list -> *@items {
...
}

As it's equivalent to:

loop {
...
}

Where you use @list instead of @items.

Luke

Austin Hastings

unread,
Sep 29, 2005, 11:17:25 PM9/29/05
to Matt Fowles, perl6-l...@perl.org
Matt Fowles wrote:

>Austin~
>
>On 9/29/05, Austin Hastings <Austin_...@yahoo.com> wrote:
>
>
>>Plus it's hard to talk about backwards. If you say
>>
>>for @l -> ?$prev, $curr, ?$next {...}
>>
>>what happens when you have two items in the list? I think we're best off using signature rules: optional stuff comes last.
>>
>>
>
>I disagree, I think that is an easy call
>
>for (1, 2) -> ?$prev, $cur, ?$next {
> say "$prev -> $cur" if $prev;
> say $cur;
> say "$cur -> $next" if $next;
> say "next";
>}
>
>should print
>
>1
>1 -> 2
>next
>1 -> 2
>2
>next
>
>
>

Did you mean:

next
1 -> 2 # two spaces

there?

I assume so because it's the only execution path that seems to work. But
that would be assuming there was always at least one non-optional
binding. Given that Luke's against all-optional signatures, too, I'll
withdraw that part of the suggestion. And with at least one required
binding, then there's no reason that we can't have the window extend on
both sides of the current value.

Luke?

=Austin

Matt Fowles

unread,
Sep 30, 2005, 12:47:10 PM9/30/05
to Austin_...@yahoo.com, perl6-l...@perl.org
Austin~

No, my logic is that the loop is run through twice, once with (undef,
1, 2) and once with (1, 2, undef).

0 new messages