Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

When is a function call not a function call

by dpuu (Chaplain)
on Mar 29, 2006 at 21:46 UTC ( [id://540065]=perlquestion: print w/replies, xml ) Need Help??

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

Everyone known why print (1+1)*2; doesn't work as newbies might expect. But there's a simple rule to understand it: if it looks like a funtion call then it is a function call.

But I came across another example today:

sub uniq { local $_; my %seen; return grep { !$seen{$_}++ } @_; } print uniq 0,0,1,2; # good: prints 0,1,2 print sort uniq 0,0,1,2; # bad: prints 0,0,1,2
It appears that the sort function is seeing "uniq" as the code block that defines sort critera. OK, I thought, lets make it "look like a function call":
print sort uniq(0,0,1,2);
But nope, this still prints "0,0,1,2". To make it work I need to resort to:
print sort grep {1} uniq 0,0,1,2;
or some similar intusive builtin.

This example probably just scratches the surface of some parser logic that I haven't correctly groked. Why doesn't the "if it looks like a function" rule work in this case? If a builtin like "grep" (or "map") isn't treated as a sort-criteria code block, then how do I define my own subroutines that similarly are not sort-critera?

--Dave
Opinions my own; statements of fact may be in error.

Replies are listed 'Best First'.
Re: When is a function call not a function call
by Roy Johnson (Monsignor) on Mar 29, 2006 at 21:55 UTC
Re: When is a function call not a function call
by duff (Parson) on Mar 30, 2006 at 04:15 UTC
    To make it work I need to resort to:
    print sort grep {1} uniq 0,0,1,2;
    

    I know it's mentioned in the node that Roy Johnson linked to, but I think it bears repeating that you don't need to resort to such arcane chicanery. Simply adding parentheses does the trick:

    print sort(uniq(0,0,1,2));
      That doesn't seem to work:
      % perl -we 'sub fn {print "$a$b\n"} print(sort(fn(0,0,1,2)))' Unquoted string "fn" may clash with future reserved word at -e line 1. 00 10 21 0012
      I can eliminate the warnings by choosing a function name that isn't all-lowercase but, as the output demonstrates, the function is still called as a comparator, not a modifier of the input list.

      Update: I was using perl 5.6.1. The parentheses trick works with 5.8.

      --Dave
      Opinions my own; statements of fact may be in error.

        It's good to know that 5.6.x is broken in this regard in case one of us is unlucky enough to be required to use a 5 year old perl distribution. :-)

        thanks

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://540065]
Approved by kutsu
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (6)
As of 2024-04-25 11:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found