Skip Menu |
Report information
Id: 130859
Status: new
Priority: 0/
Queue: perl6

Owner: Nobody
Requestors: smls75 [at]

Severity: (no value)
Tag: (no value)
Platform: (no value)
Patch Status: (no value)
VM: (no value)

Subject: [WEIRD] WhateverCode subscript inside WhateverCode inside block doesn't properly close over lexical
From: "Sam S." <smls75 [...]>
To: rakudobug [...]
Date: Sat, 25 Feb 2017 15:54:49 +0100
Download (untitled) / with headers
text/plain 1.5k
A WhateverCode containing an array subscript that is itself a WhateverCode, usually works fine... e.g. `*.[*-1]` always returns the last positional element of its argument. A WhateverCode closing over a lexical variable usually works fine, e.g. `* - $x` always subtracts the *current* value of $x from its argument. But when *both* of those features are combined, *and* the variable that is closed over is scoped to an outer block or routine that is called repeatedly, then it misbehaves: sub f { my $x = ++$; (*.[* - $x])(<a b c>) } say (f,f,f); # (c c c) The same, using `map`: say (1..3).map: { (*.[* - $_])(<a b c>) }; # (c c c) The expected output would be `(c b a)`. For some reason, it seems to use the first value of `$x` or `$_` for all three iterations. ---------- Demonstration that the particular circumstances described above have to align for the bug to appear: 1) If the WhateverCode subscript is replaced with a static expression, the bug disappears: say (1..3).map: { (*.[3 - $_])(<a b c>) }; # (c b a) 2) If the outer WhateverCode is removed by "inlining" it, the bug disappears: say (1..3).map: { <a b c>[* - $_] }; # (c b a) 3) If the `map` is unrolled so that there is no outer block that gets re-entered between invocations of the WhateverCode's, the bug disappears: my &f = *.[* - $_]; $_ = 1; say f <a b c>; # c $_ = 2; say f <a b c>; # b $_ = 3; say f <a b c>; # a ---------- This is Rakudo version 2017.02-95-g0be724727 built on MoarVM version 2017.02-7-g3d859008 implementing Perl 6.c.
Download (untitled) / with headers
text/plain 308b
Replacing the outer WhateverCode with a Block lambda, makes the bug disappear: say (1..3).map: -> $n { {.[* - $n]}(<a b c>) }; # (c b a) Replacing the WhateverCode subscript with a Block lambda subscript, makes the bug disappear: say (1..3).map: -> $n { (*.[{$_ - $n}])(<a b c>) }; # (c b a)
Download (untitled) / with headers
text/plain 139b
committable reveals that the bug has existed since before 2014.01:

This service is sponsored and maintained by Best Practical Solutions and runs on infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at