http://www.perlmonks.org?node_id=989813

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Why does reverse in list context operate on () instead of @_ or @ARGV?

my $scalar = reverse; # reverse($_) my @list = reverse; # reverse()

Replies are listed 'Best First'.
Re: Why does reverse in list context operate on () instead of @_ or @ARGV
by Corion (Patriarch) on Aug 26, 2012 at 12:29 UTC

    ... because it's documented that way?

    Of course, for obfuscation reasons, it might be nice to have reverse act on @_, but I fail to see the practical applicability.

      Of course, for obfuscation reasons, it might be nice to have reverse act on @_, but I fail to see the practical applicability.

      I wrote  map { reverse } @words;

      but I wanted  map { scalar reverse } @words;

      If it operated on @_ (or if there was a warning of some kind ) I would have known what was wrong sooner

        It would be lovely if reverse $scalar in list context generated a warning and if reverse; did also (because it becomes reverse $_). But these both need to be based on the syntax used not on the arguments present at run-time. reverse @empty and reverse @one_item must not produce warnings just because @empty is empty or @one_item only contains one item.

        If I had a time machine, then I might go back and make the behavior of reverse be based on the syntax of arguments provided to it instead of being based on the context in which it was used. My motivation for doing that is because I believe that passing a scalar to it or passing an array to it is a much better indication of the desired behavior than the context it is used in.

        My motivation against it is that I suspect that it would be hard to document the distinction and because it would be a unique case of that distinction in the Perl language.

        As to your original question, I think that

        ... map { reverse } @list;

        is a good motivation against both potential defaults. I think that expression is the most reasonable/likely way in which reverse might be used without arguments.

        Making that default to map { reverse @_ } @list would be rather silly. You say it might have made you realize what was wrong sooner. I can easily see cases where that would make diagnosing the problem very hard, where it would lead to a lot of confusion.

        The fact that map { reverse $_ } @list is a complex no-op is a good reason, IMHO, to make 'reverse' with no arguments simply be a fatal error (and an error that mentions if it had been used in list context).

        I can imagine quite a few ways to make reverse DWIM much more effectively. But all of them rather conflict with the tools Perl has built for similar purposes (prototypes and their more powerful brothers that are only available for built-in functions along with scalar vs. list context).

        So, the concept of having «a single English word, "reverse", that is overloaded to mean either "reverse list" or "reverse string" depending on how it is used» seems quite Perlish but is at odds with Perl due to details of implementation.

        It'd be better to have separate functions for "reverse string" and "reverse list". I might even propose "invert" be the verb for lists, but maybe not. I certainly would make the "reverse string" function only accept a single argument.

        - tye        

        Example

        $ perl -le " print for map reverse, qw{ one two three } " $ perl -le " print for map ~~reverse, qw{ one two three } " eno owt eerht
Re: Why does reverse in list context operate on () instead of @_ or @ARGV
by ikegami (Patriarch) on Aug 27, 2012 at 15:30 UTC

    Why does reverse in list context operate on () instead of @_ or @ARGV?

    It's not unimportant that very little that expects a list distinguishes between an empty list and an unspecified list, and those that do* all default to $_.

    * — Only print and say do. reverse in scalar context does too, but that's because it's required to accept a list in case it's called in list context.