Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Order of execution of functions in list

by vsespb (Hermit)
on Sep 13, 2013 at 12:34 UTC ( #1053912=perlquestion: print w/ replies, xml ) Need Help??
vsespb has asked for the wisdom of the Perl Monks concerning the following question:

It seems like order of execution of some expressions is undefined, including list of arguments to a function call.
1: eval order of args to a sub
2: Why is the execution order of subexpressions undefined?


Now I'm wondering if this is a valid code:
sub mysub { my ($a1, $a2) = (shift, shift) ...
Probably not valid. However I see it's widely used on CPAN: cpan grep
So, question is: is it allowed by perl documentation?

Comment on Order of execution of functions in list
Download Code
Re: Order of execution of functions in list
by LanX (Canon) on Sep 13, 2013 at 12:51 UTC
    Reading the linked discussions reveals that the problem is related to lvalues and composed expressions (like ++$i) with side effects.

    shift is a simple expression (a builtin in this case), has no side-effects and returns an rvalue.

    Cheers Rolf

    ( addicted to the Perl Programming Language)

      has no side-effects
      shift() actually modifies @_, isn't it side-effect?
      if shift()s executed in different order, result will be different.
        Imho a main effect cause its a builtin function.

        Do you expect  sub inc { return $_[0] + 1} to cause ambiguity ?

        Ok ... Maybe better phrased "a well defined effect" my definition of side was to restricted.

        Cheers Rolf

        ( addicted to the Perl Programming Language)

      has no side-effects

      $ perl -E'@a=qw( a b c ); say 0+@a; shift(@a); say 0+@a;' 3 2

      returns an rvalue

      $ perl -E'$_=123; say; sub { sub { ++$_[0] }->(shift); }->($_); say;' 123 124
        The problem with mobiles is that I can't check my code (at least ATM)

        And I don't understand the sideeffect code you posted.

        I'll reply this evening...

        Edit

        At second glance it seems that shift really returns lvalues... Strange

        Mea culpa!!! :(

        Cheers Rolf

        ( addicted to the Perl Programming Language)

        > > returns an rvalue

        FWIW: I think this code is easier to understand and demonstrates your point

        DB<194> sub tst { my $x=\(shift()); ++$$x } DB<195> $a=10 => 10 DB<196> tst $a => 11 DB<197> tst $a => 12 DB<198> $a => 12
        I get the same results using the equivalent splice(@_,0,1)

        That's not documented in the perldocs for shift or splice and I think it's due to the way Perl holds and replaces variables in @_, they just don't loose their aliasing magic when shifted.

        Maybe Perl avoids copying of the values for performance reasons.

        Interesting...

        But since it's not documented, I doubt that this is reliable behavior.

        Cheers Rolf

        ( addicted to the Perl Programming Language)

Re: Order of execution of functions in list
by Marshall (Prior) on Sep 13, 2013 at 13:20 UTC
    Well first, there is a problem with $a and $b in Perl. These are special variables used in for example the sort function. Use $x and $y instead.

    I have bench-marked the shift vs array list assignment.
    my $X = shift; my $Y = shift; vs my ($X,$Y) = @_; The second version is faster with more than one variable.

    my ($a1, $a2) = (shift, shift);
    Better is:
    my ($X,$Y) = @_;
      That was just proof-of-concept example, my original code a bit more complex and I care more about readability than performance in my particular case.
      Well first, there is a problem with $a and $b in Perl
      1. there is no $a and $b in my code.
      2. it's not a problem, at least if you are not defining comparison function in same scope.
Re: Order of execution of functions in list
by ikegami (Pope) on Sep 13, 2013 at 13:23 UTC

    Operand evaluation order isn't defined for all operators[1], but it is for this one.

    Quote perlop,

    In list context, [,] is just the list argument separator, and inserts both its arguments into the list. These arguments are also evaluated from left to right.

    That's perfectly fine.


    1. For example, Perl doesn't define the order in which f, g and h will be called by f() + g() + h().
      Ok, thanks! That was exactly what I looked for!
      So in function calls it's not a list argument separator ?

      function($i++,++$i) ???

      Cheers Rolf

      ( addicted to the Perl Programming Language)

        So in function calls it's not a list argument separator ?

        Sure it is.

        function($i++,++$i) ???

        $i++ is going to be evaluated before ++$i.

Re: Order of execution of functions in list
by ikegami (Pope) on Sep 13, 2013 at 13:59 UTC
    Also,
    my ($a1, $a2) = splice(@_, 0, 2);

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1053912]
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (13)
As of 2014-09-30 16:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (378 votes), past polls