Skip to content
This repository was archived by the owner on Jun 1, 2023. It is now read-only.
This repository was archived by the owner on Jun 1, 2023. It is now read-only.

Wrong order of evaluation in map blocks #280

@rurban

Description

@rurban

The key should be stored before the value is calculated. Left to order evaluation of block members (i.e. a list), i.e. copy away GvSV(defgv).

perl -e'sub x{$_="ouch"};%h=map{$_=>x}(0..3);print join" ",%h' => (ouch=>ouch), but should be
(1=>ouch, 2=>ouch, 0=>ouch, 3=>ouch), because the map list is (ouch, ouch, ouch, ouch, ouch, ouch), which is then collapsed to (ouch=>ouch).
Same problem with sub x{$_="ouch"};@h=map{$_=>x}(0..2);print join ", ",@h => (ouch, ouch, ouch, ouch, ouch, ouch) which should be (0, ouch, 1, ouch, 2, ouch) instead.

$_=>x => x changes $_, but should not influence the former key/list result.

See PatrickCronin/Map-Functional#1

Looks like the problem cannot be solved at runtime.
mapstart sets a fresh $_, then the block produces the stack entries, then mapwhile consumes them.
The problem happens in the block, which overwrites $_ before mapwhile can consume them.
The compiler could be changed to split the block into static list entries with interspersed mapwhile
consumers.

mapstart { stmt, stmt } mapwhile =>
mapstart { stmt; mapwhile; stmt } mapwhile

This would help for the obvious static lists {$_=>$v} and {$_=>x}, but not for the 2nd problem with the call producing a list {x}. Which is fine.


For hash assignments we could restrict the mapwhile producer to accept only pairs, not arbitrary lists. Something like use strict 'hashpairs'. See #281

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions