Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.91k stars 542 forks source link

Map reverse surprise #18840

Open philiprbrenan opened 3 years ago

philiprbrenan commented 3 years ago

Please provide a compile time message explaining that map{reverse $_} does not behave as one might immediately expect as shown below:

#!/usr/bin/perl
use warnings FATAL => qw(all);
use strict;
use Data::Dump qw(dump);
use feature qw(say);

say dump map{            $_} 10..19; # (10 .. 19) # Expected
say dump map{    reverse $_} 10..19; # (10 .. 19) # Surprising
say dump map{scalar reverse} 10..19; # ("01", 11, 21, 31, 41, 51, 61, 71, 81, 91) # Annoying
richardleach commented 3 years ago

What behaviour might people otherwise be expecting? (The results of the examples do seem to follow the documentation for mapand reverse.)

Grinnz commented 3 years ago

This is a general problem with two sources:

More warnings are helpful but I'm not sure exactly what we could warn about in this specific case.

gugod commented 3 years ago

The way I see it... the surprising factors are (1) when reverse itself is in list context, and (2) when reverse is passed only one argument. Such as these cases:

# a single string literal
($foo) = reverse("foo");

# a single scalar variable
%ridx = map { reverse($_) => 1 } ("foo", "bar");

When both (1) and (2) are satisfied, the list-reverse is essentially an no-op -- it does effectly nothing to the list, nor to the only element inside.

A warning message can probably be yield, saying: "reversing a list of one item would have no effect. Do you mean: scalar reverse($x) ?"

But there should probably be no warnings when an array of just one item is given to the list-reverse

@x = ("foo");
my @y = reverse(@x);