In Re: Array regex matching, I said:
a list assignment (what you have in parentheses) in scalar context results in the number of elements on the right side of the assignment
This has drawn a couple of private responses. Yes, it does actually use the right side of the assignment, not the left. Consider the idiom:
while (my ($key,$value) = each %foo) { }
There are always 2 values on the left of the assignment there. list-context each() will produce 2 values also, until the end of the hash is reached; whereupon it will return an empty list. So the condition the while is checking will be 2 each time there is another key to process and 0 once there is not, terminating the loop.

Another idiom: example taken from perlfaq4 "How do I count the number of occurences of a substring within a string?":

$count = () = $string =~ /-\d+/g;
Here, the left hand side of the list assignment has 0 elements, and the right has however many -\d+ sequences are in $string. $count is assigned that number of sequences.

Replies are listed 'Best First'.
Re: list assignment in scalar context
by stvn (Monsignor) on Jan 13, 2004 at 17:45 UTC

    Personally I love this kind of stuff. Its a nice combination of the elegance of the functional (LISP, ML) paradigm and your more standard brute-force imperative/side-effect paradigm. You assign/pattern-match the array returned from each (functional), then the while statement uses the side effect value produced when it reduces the values in its conditional clause to a scalar value (imperative/side-effect). This is as close as Perl comes to a pattern matching syntax for functions (pattern matching != reg-ex in this context). Which, IMHO is one of the coolest peices of syntactic suger out there.

    Consider this ML code for finding the length of a list:

    fun length [] = 0 | length (head::tail) = 1 + length tail;
    The first version of the length function is for empty lists (hence the []). The second version (after the | character) matches the head (the first element) of the list and the tail (the rest of the list). (The "::" is actually ML's list operator, and far to esoteric to explain here). The equivalent Perl would be:
    sub length { return 0 unless @_; # manual pattern matching of the array here my ($head, @tail) = @_; return 1 + length(@tail); }

    Or this (oh so cool) Erlang code for testing list membership:

    member (X, []) -> false; member (X, [X|_]) -> true; member (X, [_|T]) -> member(X, T).
    Erlang uses the "_" (underscore) to mean "A variable whose value i dont care about", and all variables can only be assigned to once and must begin with capital letters (its a language for real-time systems, so it is strict like this for good reason). This function can be read like this:

    • The first clause; given a value (X) and an empty list ([]), we know that we either have exhausted the list or never had one. So we can return false knowing that X is not in the list.
    • The second clause is; given a value (X) and a list. If X is at the head of the list (the [X|_] part) then return true because the value of X is found in the list. The comparison is implicit here since Erlang's variable are single assignment.
    • And the last clause (the recursive clause); If the value of X is not on the head of the list (the [_|T]) then take the tail of the list (T) and feed it through member again (there-by reducing the list by one).

    Erlang evaluates this function by moving down the argument-lists/guard-clauses, and runing the body of the function that best matches the actual given arguments. If you think this looks kinda like Prolog, it does, the original Erlang interpreter was written in Prolog.

    It is not hard to do an equivalent of this in perl, it would roughly be this:

    sub member { my ($X, $head, @tail) = @_; return 0 unless defined($head) && scalar @tail; return 1 if $X == $head; return member($X, @tail) if $X != $head; }
    Sure, all this Perl code is recursive, and therefor not terribly efficient. But the Erlang and ML code is compiled in such a way that they are efficient. ML can reach C-like speeds at times, and Erlang can get up there too.

    IMHO Perl is one of the coolest langauges out there; its very multi-paradigm, super-flexible in syntax and you can you can open it up and play with its guts (symbol tables, the B modules, etc etc) without "voiding the warranty" :). A very nice combination.

    -stvn

    NOTE: The ML and Erlang code are not mine, stole them from 2 very cool books. Concurrent Programming in Erlang and ML for the Working Programmer.

Re: list assignment in scalar context
by ysth (Canon) on Jan 13, 2004 at 17:50 UTC
    voiding the warranty
    Perhaps it's just a context problem, but at first glance I read that as "voiding the wantarray" :)
      You can get either if you ignore the possible return. :-)

      Interesting you should mention that. I've been considering the idea of using wantarray to mean warranty in a perl poem for some time now. I guess it's too obvious. Oh well.

      antirice    
      The first rule of Perl club is - use Perl
      The
      ith rule of Perl club is - follow rule i - 1 for i > 1