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

Implicit current-index variable, scoped inside for-loops

9 views
Skip to first unread message

cma...@gmail.com

unread,
Aug 29, 2006, 2:33:20 AM8/29/06
to Perl6 Language List
<Yobert> Hey do you know what would be cool in perl 6
<Yobert> A special variable for when you do a for (@array) style loop
<Yobert> it would always have the index of the array

Discussed on #perl6: it's already quite easy in Perl 6 to loop with an
explicit index:

my @array = <moose elk caribou>;
for @array.kv -> $i, $val {
say "$i\t$val";
}

But maybe a variable that implicitly carries along the loop index
would be even snazzier?

for @array -> $val {
say "$.\t$val";
}

(Change "$." to whatever name would actually be appropriate in this
case. "$." contains the current line number for the last filehandle
accessed in Perl 5, and that's probably why I came to think of it
here.)

Questions:

- Is the itch big enough for this? The more I look at the first piece
of code, the more I'm thinking "that's not so bad, really". (Though
opinions differed on the IRC channel.) Is there a situation I'm not
thinking of where the first piece of code would suck, and the second
piece of code would rock? Or is this a case of oversugaring?

- I feel there's a trend of moving away from line-noise variables. I'd
hate to be one to propose adding a new one to the language. Is there a
better syntax than "$."?

- How would this work with non-array data? Specifically, what happens
with next, redo etc on a filehandle, for example?

See

<http://colabti.de/irclogger/irclogger_log/perl6?date=2006-08-29,Tue&sel=145#l205>

for the #perl6 discussion.

--
masak

Ruud H.G. van Tol

unread,
Aug 29, 2006, 6:43:28 AM8/29/06
to perl6-l...@perl.org
Carl Mäsak wrote:

> But maybe a variable that implicitly carries along the loop index
> would be even snazzier?
>
> for @array -> $val {
> say "$.\t$val";
> }

Or give the block a name (label), and have an index (or several indexes, like
some that are reset by redo an some that are not) available, attached to that
name.

--
Affijn, Ruud

cma...@gmail.com

unread,
Aug 29, 2006, 7:45:20 AM8/29/06
to perl6-l...@perl.org
Ruud (>), Carl (>>):

That sounds like an interesting idea. Do you have a short snippet to
hint of what that would look like?

--
masak

Mark A. Biggar

unread,
Aug 29, 2006, 9:46:29 AM8/29/06
to Carl Mäsak, Perl6 Language List
Carl Mäsak wrote:
> <Yobert> Hey do you know what would be cool in perl 6
> <Yobert> A special variable for when you do a for (@array) style loop
> <Yobert> it would always have the index of the array
>
> Discussed on #perl6: it's already quite easy in Perl 6 to loop with an
> explicit index:
>
> my @array = <moose elk caribou>;
> for @array.kv -> $i, $val {
> say "$i\t$val";
> }
>
> But maybe a variable that implicitly carries along the loop index
> would be even snazzier?


Whatever is done should also work for grep and map.

--
ma...@biggar.org
mark.a...@comcast.net

Dr.Ruud

unread,
Aug 29, 2006, 10:09:17 AM8/29/06
to perl6-l...@perl.org
"Carl Mäsak" schreef:
> Ruud:
>> Carl:

Maybe something like:

for @array -> $val
{
say for.ix, "\t$val";
}


for @array -> $val NAME1:
{
say NAME1.ix, "\t$val";
}

--
Affijn, Ruud

"Gewoon is een tijger."


cma...@gmail.com

unread,
Aug 29, 2006, 10:23:11 AM8/29/06
to Perl6 Language List
Mark (>), Carl (>>):

Oh, definitely.

In fact, you may just have found the raison d'etre for this feature. I
suppose doing a map or a grep over @array.kv is possible:

pugs> my @array = <london bridge is falling down>
("london", "bridge", "is", "falling", "down")

pugs> map { "Element $^a is called $^b" }: @array.kv;
("Element 0 is called london",
"Element 1 is called bridge",
"Element 2 is called is",
"Element 3 is called falling",
"Element 4 is called down")

But it can hardly be blamed for clarity.

--
masak

Dr.Ruud

unread,
Aug 29, 2006, 11:00:07 AM8/29/06
to perl6-l...@perl.org
Carl Mäsak schreef:

> I suppose doing a map or a grep over @array.kv is possible:
>
> pugs> my @array = <london bridge is falling down>
> ("london", "bridge", "is", "falling", "down")
>
> pugs> map { "Element $^a is called $^b" }: @array.kv;
> ("Element 0 is called london",
> "Element 1 is called bridge",
> "Element 2 is called is",
> "Element 3 is called falling",
> "Element 4 is called down")
>
> But it can hardly be blamed for clarity.

I find it very clear too. <g>
Also try a sparse array.

Jonathan Scott Duff

unread,
Aug 29, 2006, 1:44:44 PM8/29/06
to Carl Mäsak, Perl6 Language List
Having read this thread, I tend to think you're insane for bringing it
up again :-)

That said, I'll entertain the discussion for a bit ...

On Tue, Aug 29, 2006 at 08:33:20AM +0200, Carl Mäsak wrote:
> Questions:
>
> - Is the itch big enough for this? The more I look at the first piece
> of code, the more I'm thinking "that's not so bad, really". (Though
> opinions differed on the IRC channel.) Is there a situation I'm not
> thinking of where the first piece of code would suck, and the second
> piece of code would rock? Or is this a case of oversugaring?

I think this is a case of too much sugar. I also think making the
variable *explicit* rather than implicit is a good thing.

Pointy blocks and .kv are simple and general and can be combined
in different ways for different contexts. A special "index into the
iterator" thingy doesn't sound that general. Just an observation.

> - I feel there's a trend of moving away from line-noise variables. I'd
> hate to be one to propose adding a new one to the language. Is there a
> better syntax than "$."?

Okay, stepping into the madness ...

If each iteratorish construct kept the iterator around in some easily
accessible way, then you could call methods on it. There is a trend
away from line-noisy variables, but given our iterator looks like =<>,
maybe the variable should be $= (hey, formats don't need it any more
;-)

for @array {
say "The value $=.value is at index $=.index";
say "The value $_ is at index $=.index";
}

I'd far and away rather say:

for @array.kv -> $i, $v {
say "The value $v is at index $i";
}

though.

Hmm. Now that I think about it a little more, $= will surely be
conflated with the PODish variables in some way. But, I don't have a
better alternative. (It's at this point that I wish there was a
double-underscore glyph on my keyboard just to have an alternative ;)

> - How would this work with non-array data? Specifically, what happens
> with next, redo etc on a filehandle, for example?

I would expect the index to track the iterator on next/redo. That is, if
you've read line 5, then the index will be 5ish (I'm hand waving 0- vs
1-based counting). On redo it would continue to be 5, and on next it
will be 6.

But what should happen when you're reading from multiple filehandles
or multiple arrays? Should it reset at the start of a new file/array
or continue counting? And how do you get the other behavior?

With the simple primitives we have now we can easily create whichever
behavior we desire. So, I think the extra sugar for some implicit
index will do more harm than good.

Here's one useful semantic I can think of WRT $= ... if it's a true
global (yes, I know we're supposed to be shy of those too, but I'm brain
storming here) then its scope lasts beyond the bounds of the block in
which it's executing so that things like

for @array { ... last if ...; }
say "Stopped processing at $=.index";

work.

But, again, we have other ways of making this work that don't involve
introducing some implicit thing.

-Scott (PerlJam)
--
Jonathan Scott Duff <du...@pobox.com>

Damian Conway

unread,
Aug 29, 2006, 7:17:47 PM8/29/06
to Perl6 Language List
> pugs> map { "Element $^a is called $^b" }: @array.kv;
> ("Element 0 is called london",
> "Element 1 is called bridge",
> "Element 2 is called is",
> "Element 3 is called falling",
> "Element 4 is called down")
>
> But it can hardly be blamed for clarity.

That's a little unfair. Choose good names and it's perfectly clear:

map { "Element $^array_index is called $^array_value" } <== @array.kv;

Likewise, for your original formulation:

for @array {
say "$^index\t$^value";
}


Given that we already have both placeholders (above) and pointy blocks:

for @array -> $index, $value {
say "$index\t$value";
}

to achieve this task, and given that both mechanisms allow you to choose the
name of the counter variable (rather than being stuck with some unreadable
punctuation variable), I don't think we need a third mechanism for this.

Damian

Dr.Ruud

unread,
Aug 29, 2006, 9:55:41 PM8/29/06
to perl6-l...@perl.org
Damian Conway schreef:
> [attribution repaired] Carl:

>> But it can hardly be blamed for clarity.
>
> That's a little unfair.

"can hardly be blamed" -> "can easily be praised" <g>

Damian Conway

unread,
Aug 29, 2006, 10:07:03 PM8/29/06
to p6l
> >> But it can hardly be blamed for clarity.
> >
> > That's a little unfair.
>
> "can hardly be blamed" -> "can easily be praised" <g>

Apologies to Carl if I misinterpreted. I read it as:

"can hardly be blamed for (having) clarity"

;-)

Damian

Dr.Ruud

unread,
Aug 29, 2006, 11:46:33 PM8/29/06
to perl6-l...@perl.org
"Damian Conway" schreef:
> Ruud:
>> Damian:
>>> Carl:

Nah, I was just joking; his "but" gave it away already.

I didn't agree that the map-approach Carl showed is not clear, but
prefer the pointy blocks version that you showed.

my @array = <london bridge is falling down> ;


for @array -> $index, $value
{

say "Element $_ is called $value"
}

But I don't understand how the "$index, $value" pair gets its values; is
@array somehow turned into a hash with the index as the key?
With @array -> $index, $value {}, is $_ an alias of $index?

--
Affijn, Ruud (should update his pugs, but on dialup now)

"Gewoon is een tijger."


Damian Conway

unread,
Aug 30, 2006, 12:05:36 AM8/30/06
to p6l
> for @array -> $index, $value
> {
> say "Element $_ is called $value"
> }
>
> But I don't understand how the "$index, $value" pair gets its values; is
> @array somehow turned into a hash with the index as the key?
> With @array -> $index, $value {}, is $_ an alias of $index?

No. There's no such magic. I simply screwed up. I should have written:

for @array.kv -> $index, $value {...}

:-(

Damian

cma...@gmail.com

unread,
Aug 30, 2006, 2:36:02 AM8/30/06
to Damian Conway, p6l
Damian (>), Ruud (>>), Damian (>>>), Carl (>>>>):

No, yours is the correct interpretation, Damian. Though my sentence is
very open to misinterpretation, as it, too, can hardly be blamed for
clarity.

Furthermore, I agree that the solution worked out by this thread is
good enough not to warrant a separate index mechanism. To me, naming
the variables "$index" and "$value" makes the meaning perfectly clear.

for @array.kv -> $index, $value {...}

And if anyone still hates .kv's guts, and wants a magic index syntax,
that's probably perfect material for a Perl 6 module with some macro
goodness in it.

I gather that the below syntax should eventually work, too; right now
it doesn't in Pugs. But I guess I ought to brush up my Haskell and
contribute instead of complaining. :-)

map -> $index, $value { "$index, $value" } <== @array.kv

Scott (>):


> Having read this thread, I tend to think you're insane for bringing it
> up again :-)

Why thank you sir. Well, one does one's best.

--
masak

Dr.Ruud

unread,
Aug 30, 2006, 12:55:46 AM8/30/06
to perl6-l...@perl.org
Damian Conway schreef:

> [for @array -> $index, $value {...}]


>
> No. There's no such magic. I simply screwed up. I should have written:
> for @array.kv -> $index, $value {...}
> :-(

Ah, much clearer now. <g>

0 new messages