in reply to syntax of map operator

The BLOCK version creates a scope. That adds overhead, so the BLOCK version is a bit slower. I don't remember how much, but it's surely noting substantial.

On the other hand, the BLOCK version allows the use of multiple statements, including variable declarations. It's usually easier to read too.

Update: I since discovered that both versions add a scope. (See higher up post.) That doesn't change the fact that map BLOCK is a bit slower; it just means I don't know why.

Replies are listed 'Best First'.
Re^2: syntax of map operator
by JavaFan (Canon) on Jan 24, 2010 at 15:49 UTC
    I since discovered that both versions add a scope.
    Yes, but they aren't the same scopes. The EXPR variant doesn't create a lexical scope; the BLOCK variant does:
    $ perl -Mstrict -wcE 'my @x = map my $x = $_, 2; say $x' -e syntax OK $ perl -Mstrict -wcE 'my @x = map {my $x = $_} 2; say $x' Global symbol "$x" requires explicit package name at -e line 1. -e had compilation errors.
    I'm not quite sure what kind of scoping effects happen.
    $ perl -Mstrict -wE 'my @x = map my $x = $_, 2; say $x' Use of uninitialized value $x in say at -e line 1. $ perl -Mstrict -wE 'my $x; my @x = map $x = $_, 2; say $x' 2
    So, if we declare $x in the first argument of map, $x exists afterwards, but doesn't have a defined value. If declared before the map, it keeps the last assigned value.

    I guess that's more an artifact of the implementation than that it was designed to work this way.

      I guess that's more an artifact of the implementation than that it was designed to work this way.

      I fully agree. Compile-time lexical scopes and run-time lexical scopes should be the same. All of these are in the same bag:

      • my $x if ...;
      • my $x for ...;
      • map my $x, ...;
      • ... and my $;x

      Just don't.

        I'm very glad EXPR if COND doesn't provide a lexical scope. That allows me to write:
        local $dbh->{AutoCommit} = 0 if !$already_in_a_transaction;
        I once had a cow orker (who thinks he's one of the smartest programmers in the world) rewrite that as
        if (!$already_in_a_transaction) { local $dbh->{AutoCommit} = 0; }
Re^2: syntax of map operator
by bart (Canon) on Jan 24, 2010 at 12:57 UTC
    Intuitively, I feel that the block must add a wider scope than the expression: for the latter, the scope effect is limited to affect just $_, for the block, you can add lexical variables of your own.

    Put it this way: the expression can use a "lite" scope.

    caveat: I have no idea if this is actually the case!

      Intuitively, I feel that the block must add a wider scope than the expression

      I think you mean narrower (i.e more restrictive) scope. Lexicals declared in the block are not visible outside of the map. Lexicals declared in the expression are visible outside of the map

      I agree. That narrower scope is the compile-time scope I mentioned earlier. map BLOCK has one. map EXPR, doesn't (unless EXPR includes a do{} or something).