hchana has asked for the wisdom of the Perl Monks concerning the following question:

As a novice I am a bit confused why script 1 works but script 2 does not.?

print "(4-1) + 2+3 * (2*2) = ", (4-1) + 2+3 * (2*2), "\n\n"; #script 1 + answer 17 print (4-1) + 2+3 * (2*2);#script 2 does not work error message: print (...) interpreted as function at operators.pl line 24 (#1) (W syntax) You've run afoul of the rule that says that any list op +erator followed by parentheses turns into a function, with all the list operators arguments found inside the parentheses. See "Terms and List Operators (Leftward)" in perlop. 3 Useless use of addition (+) in void context at operators.pl line 24 (# +2) (W void) You did something without a side effect in a context that + does nothing with the return value, such as a statement that doesn't re +turn a value from a block, or the left side of a scalar comma operator. +Very often this points not to stupidity on your part, but a failure of +Perl to parse your program the way you thought it would. For example, +you'd get this if you mixed up your C precedence with Python precedence +and said $one, $two = 1, 2; when you meant to say ($one, $two) = (1, 2); Another common error is to use ordinary parentheses to construct a + list reference when you should be using square or curly brackets, for example, if you say $array = (1,2); when you should have said $array = [1,2]; The square brackets explicitly turn a list value into a scalar val +ue, while parentheses do not. So when a parenthesized list is evaluat +ed in a scalar context, the comma is treated like C's comma operator, wh +ich throws away the left argument, which is not what you want. See perlref for more on this. This warning will not be issued for numerical constants equal to 0 + or 1 since they are often used in statements like 1 while sub_with_side_effects(); String constants that would normally evaluate to 0 or 1 are warned about.

Replies are listed 'Best First'.
Re: Order of operations
by Discipulus (Canon) on Nov 15, 2017 at 20:01 UTC
    Hello hchana,

    > print (...) interpreted as function..

    print does not like to be treated as function, ie be followed by parens.

    You can use in these case the + unary operator:  print +(4-1)... or surrounding the whole in an additional parens:  print +((4-1)...)

    See Symbolic Unary Operators on docs and also a precise example at Named Unary Operators

    PS interesting enough is a paragraph of print docs:

    > Be careful not to follow the print keyword with a left parenthesis unless you want the corresponding right parenthesis to terminate the arguments to the print.

    Infact an openening parens do not always provoke the above warning (perl is so smart..):

    perl -we "use strict; my $x; print (1,2,3) and $x++" 123

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

      Thanks that's a great help. I also found the below scripts work; didn't know print was so complicated. haha

      print "", (4-1) + 2+3 * (2*2), "\n\n"; print +((4-1) + 2+3 * (2*2)), "\n\n"; print ((4-1) + 2+3 * (2*2), "\n\n");
Re: Order of operations
by haukex (Archbishop) on Nov 15, 2017 at 20:07 UTC

    The first message refers you to "Terms and List Operators (Leftward)" in perlop, which says:

    print ($foo & 255) + 1, "\n";

    probably doesn't do what you expect at first glance. The parentheses enclose the argument list for print which is evaluated (printing the result of $foo & 255). Then one is added to the return value of print (usually 1). The result is something like this:

    1 + 1, "\n"; # Obviously not what you meant.

    To do what you meant properly, you must write:

    print(($foo & 255) + 1, "\n");

    See Named Unary Operators for more discussion of this.

    ...

    If any list operator (print(), etc.) or any unary operator (chdir(), etc.) is followed by a left parenthesis as the next token, the operator and arguments within parentheses are taken to be of highest precedence, just like a normal function call.

    You can see how Perl is interpreting your code with B::Deparse:

    $ perl -MO=Deparse,-p -e 'print (4-1) + 2+3 * (2*2);' ((print(3) + 2) + 12);
Re: Order of operations
by Marshall (Canon) on Nov 16, 2017 at 02:24 UTC
    The Perl print statement allows an optional file handle right after "print", like print $handle stuff....
    You are confusing print.

    In your code:

    print "(4-1) + 2+3 * (2*2) = ", (4-1) + 2+3 * (2*2), "\n\n"; #script 1 + answer 17 print (4-1) + 2+3 * (2*2);#script 2 does not work
    add a dummy null string at the beginning to script 2:
    print "",(4-1) + 2+3 * (2*2);
    This makes it clear that the first arg is not a file handle.
      The Perl print statement allows an optional file handle right after "print" ... This makes it clear that the first arg is not a file handle.

      Sorry but that's not the reason print gets confused, it's the parens. The optional file handle is independent of those:

      $ perl -wMstrict -le 'print ( STDOUT "42") + 1' print (...) interpreted as function at -e line 1. Useless use of addition (+) in void context at -e line 1. 42 $ perl -wMstrict -le 'print ({*STDOUT} "42") + 1' print (...) interpreted as function at -e line 1. Useless use of addition (+) in void context at -e line 1. 42
        Fine, you are correct. print is confused for a different and more technically correct reason than what I said. However, my suggestion "un-confuses" print.