in reply to Functional Composition

'|' is left associative, and the left argument is evaluated first

Left-associative means that

a | b | c
is equivalent to
( a | b ) | c
and not
a | ( b | c )

It says nothing about the order in which a, b and c are evaluated in relation to each other. In fact, the operand evaluation order is undefined for most Perl operators including the "|" operator.

Perl is free to evaluate

a | b | c
as follows:
push @stack, c; push @stack, b; push @stack, a; push @stack, pop(@stack) | pop(@stack); push @stack, pop(@stack) | pop(@stack); pop @stack;

The left pipe is evaluated before the right pipe, so the operator is left-associative, but note how c is evaluated before b, which is evaluated before a.

Your code is relying on undefined functionality. It's not guaranteed to work. You'd have to switch to || if you wanted predictable results. || is guaranteed to evaluate its LHS argument before its RHS argument due to its short-circuiting nature.

That's the official line, anyway. In reality, |'s LHS arg is always evaluated before its RHS, and I don't see that ever changing.

Replies are listed 'Best First'.
Re^2: Functional Composition
by billh (Pilgrim) on Dec 17, 2009 at 21:19 UTC

    I stand corrected, I chose '|' pretty arbitrarily to mimic unix pipes, and assumed that the left operand would always be evaluated first. I do know what "left associative" means though, there was an "and" in that sentance :-)

    Bill H
    perl -e 'print sub { "Hello @{[shift->()]}!\n" }->(sub{"World"})'

      there was an "and" in that sentance

      There was a possibility that you meant "and therefore". If not, then you can ignore the top half while others benefit from it.

        No problem, It does provoke a random question though: If you overload a short-circuited operator, does it still short-circuit? I mean if the result of an intermediate operation returned a false value, would the whole expression end up false?

        Bill H
        perl -e 'print sub { "Hello @{[shift->()]}!\n" }->(sub{"World"})'