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

How does List.map: { .say } work?

1 view
Skip to first unread message

Moritz Lenz

unread,
Nov 2, 2009, 9:53:59 AM11/2/09
to perl6-l...@perl.org
Hi,

the current spec doesn't allow immutable containers to call .map with a
block that implicitly uses $_ as an implicit parameter.

Here's why:

S06 says

> The C<$_> variable functions as a placeholder in a block without any
> other placeholders or signature. Any bare block without placeholders
> really has a parameter like this:
>
> -> $_ is rw = OUTER::<$_> { .mumble }

So $_ is marked as rw, which is checked at binding time.

Now lists are immutable, meaning that you can't bind a list item rw, so
even if the block doesn't try to modify $_, calling the { .say } block
fails.

(Note that 'for' has the same problem)

How should that be resolved? Should a temporary variable be created that
can be changed, without any effect? or should it fail() on detecting a
modification? Somehow this approach seems very backward to me...

Cheers,
Moritz

Solomon Foster

unread,
Nov 2, 2009, 10:16:39 AM11/2/09
to perl6-l...@perl.org, Moritz Lenz

Is there a reason $_ is readonly isn't a possible solution?

--
Solomon Foster: col...@gmail.com
HarmonyWare, Inc: http://www.harmonyware.com

Carl Mäsak

unread,
Nov 2, 2009, 10:21:13 AM11/2/09
to Solomon Foster, perl6-l...@perl.org, Moritz Lenz
Solomon (>), Moritz (>>):

>> the current spec doesn't allow immutable containers to call .map with a
>> block that implicitly uses $_ as an implicit parameter.
>>
>> Here's why:
>>
>> S06 says
>>
>>> The C<$_> variable functions as a placeholder in a block without any
>>> other placeholders or signature.  Any bare block without placeholders
>>> really has a parameter like this:
>>>
>>>     -> $_ is rw = OUTER::<$_> { .mumble }
>>
>> So $_ is marked as rw, which is checked at binding time.
>>
>> Now lists are immutable, meaning that you can't bind a list item rw, so
>> even if the block doesn't try to modify $_, calling the { .say } block
>> fails.
>>
>> (Note that 'for' has the same problem)
>>
>> How should that be resolved? Should a temporary variable be created that
>>  can be changed, without any effect? or should it fail() on detecting a
>> modification? Somehow this approach seems very backward to me...
>
> Is there a reason $_ is readonly isn't a possible solution?

For one thing, then you couldn't do this:

my @a = 1, 2, 3;
for @a {
++$_;
}

// Carl

Solomon Foster

unread,
Nov 2, 2009, 2:03:07 PM11/2/09
to Carl Mäsak, perl6-l...@perl.org, Moritz Lenz

I meant, make it readonly if the container being iterated over is
readonly. We're working hard to make the language prefer immutable
things, it seems very odd to short circuit that in a key area like
this...

(Though personally, I would prefer it if map was readonly by default
on all containers.)

Solomon Foster

unread,
Nov 2, 2009, 2:33:58 PM11/2/09
to Carl Mäsak, perl6-l...@perl.org, Moritz Lenz

Or Larry could just find an elegant way to do it. Yay!

Raphael Descamps

unread,
Nov 2, 2009, 4:13:53 PM11/2/09
to Solomon Foster, Carl Mäsak, perl6-l...@perl.org, Moritz Lenz
Am Montag, den 02.11.2009, 14:33 -0500 schrieb Solomon Foster:
> On Mon, Nov 2, 2009 at 2:03 PM, Solomon Foster <col...@gmail.com> wrote:

FYI: Larry already found that correcting the Spec was the most elegant
solution ;)

> Author: lwall
> Date: 2009-11-02 17:31:00 +0100 (Mon, 02 Nov 2009)
> New Revision: 28973
>
> Modified:
> docs/Perl6/Spec/S06-routines.pod
> Log:
> [S06] correct $_ placeholder binding from "rw" to "ref", moritz++


Moritz Lenz

unread,
Nov 2, 2009, 11:19:46 AM11/2/09
to Solomon Foster, perl6-l...@perl.org, Moritz Lenz

I have no idea how often $_ as an implicit parameter is actually used.
Note that if you want s/// to work, you really need a mutable $_.

If it were just for iteration, I'd not object to making it an ro-alias by
default, requiring an explict rw signature (for example with <-> $_ { ... })
otherwise.

Cheers,
Moritz

cma...@gmail.com

unread,
Nov 3, 2009, 11:13:22 AM11/3/09
to Moritz Lenz, Solomon Foster, perl6-l...@perl.org, Moritz Lenz
Moritz (>), Solomon (>>), Moritz (>>>):

>> > the current spec doesn't allow immutable containers to call .map with a
>> > block that implicitly uses $_ as an implicit parameter.
>> >
>> > Here's why:
>> >
>> > S06 says
>> >
>> >> The C<$_> variable functions as a placeholder in a block without any
>> >> other placeholders or signature.  Any bare block without placeholders
>> >> really has a parameter like this:
>> >>
>> >>     -> $_ is rw = OUTER::<$_> { .mumble }
>> >
>> > So $_ is marked as rw, which is checked at binding time.
>> >
>> > Now lists are immutable, meaning that you can't bind a list item rw, so
>> > even if the block doesn't try to modify $_, calling the { .say } block
>> > fails.
>> >
>> > (Note that 'for' has the same problem)
>> >
>> > How should that be resolved? Should a temporary variable be created that
>> >  can be changed, without any effect? or should it fail() on detecting a
>> > modification? Somehow this approach seems very backward to me...
>>
>> Is there a reason $_ is readonly isn't a possible solution?
>
> I have no idea how often $_ as an implicit parameter is actually used.
> Note that if you want s/// to work, you really need a mutable $_.
>
> If it were just for iteration, I'd not object to making it an ro-alias by
> default, requiring an explict rw signature (for example with <-> $_ { ... })
> otherwise.

That would make statement modifier for loops less useful. For those,
there's nowhere to put the lambda arrow.

++$_ for @things;

// Carl

tho...@sandlass.de

unread,
Nov 4, 2009, 4:38:53 PM11/4/09
to perl6-l...@perl.org
HaloO,

On Tuesday, 3. November 2009 17:13:22 Carl Mäsak wrote:
> That would make statement modifier for loops less useful. For those,
> there's nowhere to put the lambda arrow.
>
> ++$_ for @things;

I think this is resolved with the is ref binding which
implies that the thingy that is bound to $_ is a cell
accessor of an array that provides a STORE method.

BTW, the situation of STORE and FETCH methods in classes
is kind of funny. While an object is stored in a container
the respective methods of the container are called. Only
in an is ref binding assignment affects the object directly.
That is, in the scope of the binding the object goes kind of
naked.

Regards, TSa.
--
"The unavoidable price of reliability is simplicity" -- C.A.R. Hoare
"Simplicity does not precede complexity, but follows it." -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan

0 new messages