in reply to Map Function Weirdness

The manual says map "Evaluates the BLOCK or EXPR for each element of LIST (locally setting $_ to each element) and returns the list value composed of the results of each such evaluation."

A block evaluates to what its last statement evaluates, so the real question is: "What does if evaluate to?"

I can't find that in the manual, and that's because if was never meant to be used as an expression. The value to which if evaluates is a side-effect of implementation more than anything else.

if ( EXPR ) BLOCK

is implemented very similarly to

do { ( EXPR ) and do BLOCK };

as seen below:

$ perl -MO=Concise,-exec -e'if (f()) { g() }' 1 <0> enter 2 <;> nextstate(main 3 -e:1) v:{ 3 <0> pushmark s 4 <#> gv[*f] s/EARLYCV 5 <1> entersub[t3] sKS/TARG,1 6 <|> and(other->7) vK/1 7 <0> pushmark s 8 <#> gv[*g] s/EARLYCV 9 <1> entersub[t6] vKS/TARG,1 a <@> leave[1 ref] vKP/REFC -e syntax OK $ perl -MO=Concise,-exec -e'do { (f()) and do { g() } };' 1 <0> enter 2 <;> nextstate(main 3 -e:1) v:{ 3 <0> pushmark s 4 <#> gv[*f] s/EARLYCV 5 <1> entersub[t3] sKPS/TARG,1 6 <|> and(other->7) vK/1 7 <0> pushmark s 8 <#> gv[*g] s/EARLYCV 9 <1> entersub[t6] vKS/TARG,1 a <@> leave[1 ref] vKP/REFC -e syntax OK

That means that if evaluates to the same thing as its condition if the condition evaluates to something false, and if evaluates to the same thing as its body otherwise.

In your code, it returns the result of the comparion (sv_false, which holds triplevar(0, 0.0, "")) or the result of the assignment ($max, which is currently equal to $_).

Replies are listed 'Best First'.
Re^2: Map Function Weirdness
by davido (Cardinal) on Nov 09, 2011 at 10:32 UTC

    "That means that if evaluates to the same thing as its condition if the condition evaluates to something false, and if evaluates to the same thing as its body otherwise."

    For what it's worth, B::Deparse has this to say about it:

    perl -MO=Deparse,-x9 -e 'if($a<$b){$a;}' $a < $b and do { $a };

    Looking at that makes a lot of sense: and being a logical short circuit means that if $a < $b evaluates to false, the right hand side is never evaluated. Consequently, the return value has to be the value of the relational expression.

    On the other hand, if $a is less than $b, the conditional is true, and the logical and allows the right hand side to be evaluated.

    if( $a < $b ) { $a } $a < $b and do { $a };

    Two ways of looking at it. The latter seems to me to make a lot of sense.


    Dave

      Keep in mind that Deparse is not precise. It's a useful tool, but don't rely on it too deeply. For example, this is wrong.

      >perl -MO=Deparse,-x9 -e"if(my $x=$a<$b){$a;}" my $x = $a < $b and do { $a }; -e syntax OK

      The $x is scoped to the if. Or is it...

      My code is an approximation too. The if is equivalent to neither

      do { ( $a < $b ) and do { $a } };

      nor

      ( $a < $b ) and do { $a };

      The my is lexically scoped at compile-time (as shown in mine), but it's not lexically scoped at run-time (as shown by Concise and Deparse). This means the objects can live a little longer than expected.

      ... { ... if (my $obj = ...) { ... } . . # $obj still exists here "anonymously". . } # $obj cleared here, so destructor only called here. ...