Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

map subroutine ignores the sequence in the specific case #5233

Closed
p6rt opened this issue Apr 11, 2016 · 11 comments
Closed

map subroutine ignores the sequence in the specific case #5233

p6rt opened this issue Apr 11, 2016 · 11 comments
Labels

Comments

@p6rt
Copy link

p6rt commented Apr 11, 2016

Migrated from rt.perl.org#127879 (status was 'resolved')

Searchable as RT127879$

@p6rt
Copy link
Author

p6rt commented Apr 11, 2016

From @titsuki

See the following results.

$ echo "h o g e" | perl6 -e 'for $*IN.lines -> $line { $line.split(" ").map(-> $e { $e.perl.say; }) };' # map ignores the input
$ echo "h o g e" | perl6 -e 'for $*IN.lines -> $line { $line.split(" ").perl.say };' # ensure the input sequence
("h", "o", "g", "e")
$ perl6 -e '("h", "o", "g", "e").map(->$e { $e.perl.say });' # ordinary case
"h"
"o"
"g"
"e"

The 1st example seems that map subroutine ignores the input sequence.
I think that the 1st example should return the same result as the 3rd example.

My rakudo version is
$ perl6 -v
This is Rakudo version 2016.03 built on MoarVM version 2016.03
implementing Perl 6.c.

@p6rt
Copy link
Author

p6rt commented Apr 13, 2016

From @lizmat

On 11 Apr 2016, at 15​:19, Itsuki Toyota (via RT) <perl6-bugs-followup@​perl.org> wrote​:

# New Ticket Created by Itsuki Toyota
# Please include the string​: [perl #​127879]
# in the subject line of all future correspondence about this issue.
# <URL​: https://rt-archive.perl.org/perl6/Ticket/Display.html?id=127879 >

See the following results.

$ echo "h o g e" | perl6 -e 'for $*IN.lines -> $line { $line.split(" ").map(-> $e { $e.perl.say; }) };' # map ignores the input
$ echo "h o g e" | perl6 -e 'for $*IN.lines -> $line { $line.split(" ").perl.say };' # ensure the input sequence
("h", "o", "g", "e")
$ perl6 -e '("h", "o", "g", "e").map(->$e { $e.perl.say });' # ordinary case
"h"
"o"
"g"
"e"

The 1st example seems that map subroutine ignores the input sequence.
I think that the 1st example should return the same result as the 3rd example.

I’m not sure.

$*IN.lines is lazy, the for is lazy, the split is lazy, the map is lazy, and apparently the sink is also lazy. There’s nothing pulling values from the far end, so the whole chain is waiting for something to happen.

This should probably create a warning like “Useless use of split in sink context”.

If you make the split eager by storing its result, it works as you’d expect​:

$ echo "h o g e" | perl6 -e 'for $*IN.lines -> $line { my @​a = $line.split(" ").map(-> $e { $e.perl.say; }) };'
"h"
"o"
"g"
“e"

So I would qualify this as *not a bug*, although one could argue that the lack of warning on the split in sink context *is* a bug. And/or the lack of eagerness of the sink is a bug.

Liz

@p6rt
Copy link
Author

p6rt commented Apr 13, 2016

The RT System itself - Status changed from 'new' to 'open'

@p6rt
Copy link
Author

p6rt commented Apr 13, 2016

From @titsuki

Thanks for your neat explanation.
I understand what's going on when using the map in that situation.

On 2016-4月-13 水 04​:58​:24, elizabeth wrote​:

On 11 Apr 2016, at 15​:19, Itsuki Toyota (via RT) <perl6-bugs-
followup@​perl.org> wrote​:

# New Ticket Created by Itsuki Toyota
# Please include the string​: [perl #​127879]
# in the subject line of all future correspondence about this issue.
# <URL​: https://rt-archive.perl.org/perl6/Ticket/Display.html?id=127879 >

See the following results.

$ echo "h o g e" | perl6 -e 'for $*IN.lines -> $line { $line.split("
").map(-> $e { $e.perl.say; }) };' # map ignores the input
$ echo "h o g e" | perl6 -e 'for $*IN.lines -> $line { $line.split("
").perl.say };' # ensure the input sequence
("h", "o", "g", "e")
$ perl6 -e '("h", "o", "g", "e").map(->$e { $e.perl.say });' #
ordinary case
"h"
"o"
"g"
"e"

The 1st example seems that map subroutine ignores the input sequence.
I think that the 1st example should return the same result as the 3rd
example.

I’m not sure.

$*IN.lines is lazy, the for is lazy, the split is lazy, the map is
lazy, and apparently the sink is also lazy. There’s nothing pulling
values from the far end, so the whole chain is waiting for something
to happen.

This should probably create a warning like “Useless use of split in
sink context”.

If you make the split eager by storing its result, it works as you’d
expect​:

$ echo "h o g e" | perl6 -e 'for $*IN.lines -> $line { my @​a =
$line.split(" ").map(-> $e { $e.perl.say; }) };'
"h"
"o"
"g"
“e"

So I would qualify this as *not a bug*, although one could argue that
the lack of warning on the split in sink context *is* a bug. And/or
the lack of eagerness of the sink is a bug.

Liz

@p6rt
Copy link
Author

p6rt commented Jul 20, 2016

From @zoffixznet

I'm going to close this, since the original report was ruled as not a bug.

The lazines of such constructs has now also been documented in Traps.

--
Cheers,
ZZ | https://twitter.com/zoffix

@p6rt
Copy link
Author

p6rt commented Jul 20, 2016

@zoffixznet - Status changed from 'open' to 'rejected'

@p6rt
Copy link
Author

p6rt commented Jul 21, 2016

From @zoffixznet

Re-opening per TimToady's comments​: http://irclog.perlgeek.de/perl6/2016-07-21#i_12881470

The map de-lazifies when sunk, but in this case the for's sinking doesn't seem to propagate to the map.

This, for example, prints all the values​:

m​: for ^3 { ^10 .map​: *.say; Nil }; say 42;

--
Cheers,
ZZ | https://twitter.com/zoffix

@p6rt
Copy link
Author

p6rt commented Jul 21, 2016

@zoffixznet - Status changed from 'rejected' to 'open'

@p6rt
Copy link
Author

p6rt commented Aug 9, 2016

From @TimToady

The unwanted() routine needed to add an explicit sink to certain methods found in a block-final Want node. (Method calls for dispatch​:<.=> and Pair.new are exempt, however. In the case of .=, it is 'nosink' because it's essentially going to cause a side effect anyway, and doing it twice tends to drain Seq prematurely if that's what .= returns. With Pair.new, wrapping in .sink suppressed sink warnings on useless use of pairs.) Other than those exceptions, it seems more reasonable to default method calls to sinking on the chance that the method will return a sequence that needs to be iterated for its side effects.

Fix in 328402599c16077e182bb38baf68e435b8bc1082

Test in b6012e0cd755d9c89ddff00dc45ce81a82bcbdcc

1 similar comment
@p6rt
Copy link
Author

p6rt commented Aug 9, 2016

From @TimToady

The unwanted() routine needed to add an explicit sink to certain methods found in a block-final Want node. (Method calls for dispatch​:<.=> and Pair.new are exempt, however. In the case of .=, it is 'nosink' because it's essentially going to cause a side effect anyway, and doing it twice tends to drain Seq prematurely if that's what .= returns. With Pair.new, wrapping in .sink suppressed sink warnings on useless use of pairs.) Other than those exceptions, it seems more reasonable to default method calls to sinking on the chance that the method will return a sequence that needs to be iterated for its side effects.

Fix in 328402599c16077e182bb38baf68e435b8bc1082

Test in b6012e0cd755d9c89ddff00dc45ce81a82bcbdcc

@p6rt
Copy link
Author

p6rt commented Aug 9, 2016

@TimToady - Status changed from 'open' to 'resolved'

@p6rt p6rt closed this as completed Aug 9, 2016
@p6rt p6rt added the Bug label Jan 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant