develooper 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


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About