Front page | perl.perl5.porters |
Postings from November 2022
Pre-RFC: Map with different topic variable
Thread Next
From:
Graham Knop
Date:
November 25, 2022 11:02
Subject:
Pre-RFC: Map with different topic variable
Message ID:
CAM=m89GoLURqnC8EOOGdLOdfJ+HDyFWn__6f4SDvJmSuN9eouA@mail.gmail.com
## Abstract
Allow map and grep to be given a different variable to be used as the topic
variable, rather than using `$_`. Also allow multiple variables to be given to
do n-at-a-time iteration.
## Motivation
Traditionally, map and grep loop over a list, aliasing `$_` to each list entry.
While this can be convenient in many cases, it gets awkward when nested maps
are needed. You need to manually save the `$_` value in another variable.
```perl
my %hash = (
foo => [ 1, 2, 3, 4 ],
bar => [ 5, 6, 7, 8 ],
);
my @out = map {
my $key = $_;
map { "$key: $_" } $hash{$key}->@*;
} keys %hash;
```
Using `$_` can also be dangerous if you need to call code not under your
direct control, due to it being the implicit target of operations like
readline.
It would be more convenient if you could use a different variable for the
topic, similar to what foreach allows.
```perl
my @out = map my $key {
map my $i { "$key: $i" } $hash{$key}->@*;
} keys %hash;
```
A natural extension of this syntax would be to allow n-at-a-time iteration, as
foreach can do on perl 5.36+.
```perl
my @out = map my ($key, $val) {
map my $i { "$key: $i" } $val->@*;
} %hash;
```
This syntax does conflict with map's EXPR form. However, map BLOCK can do
everything that map EXPR can do already, so under this feature, map EXPR would
be disabled. This has the advantage of eliminating the ambiguity between map
with a block and map with a hash reference expression.
All of this would apply to grep as well.
## Backwards Compatibility
The syntax to provide a topic variable, while currently valid as an
expression, is quite unlikely to be used. An attempt to enable this feature
on existing code is much more likely to produce parsing errors than to
continue to parse but produce different results.
## Examples
```perl
use feature "map_and_grep_only_allow_block_form_but_also_can_be_given_a_topic_variable_or_multiple";
my @guff = (11 .. 14);
my @bluh = map { $_ + 1 } @guff;
# ( 12, 13, 14, 15 )
my @gorf = map +($_ + 1), @guff;
# syntax error
my @blorf = map my $f { $f + 1 } @guff;
# ( 12, 13, 14, 15 )
my @hork = map my ($f, $g) { $f + $g } @guff;
# ( 23, 27 )
my @blork = grep my $f { $f > 12 } @guff;
# ( 13, 14 )
my %harf = (
clow => 11,
blug => 14,
);
my %plog = grep my ($f, $g) { $g % 2 == 0 } %harf;
# ( blug => 14 )
```
Thread Next
-
Pre-RFC: Map with different topic variable
by Graham Knop