Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

When is a function call not a function call

by dpuu (Chaplain)
on Mar 29, 2006 at 21:46 UTC ( #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?

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 (Vicar) 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.

      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. :-)


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://540065]
Approved by kutsu
[haukex]: I figure someone who wants to contribute will know how to install the missing modules ;-) Not the nicest way to go but I don't think many people are using my modules yet
[ambrus]: Corion: some of these stupid syntax highlighters assume that too. just look at the table in http://perldoc. functions/pack. html for example.
[haukex]: ..."yet" ;-) I haven't had to deal with Dist::Zilla yet but I've heard about how it's a big setup
[ambrus]: I really don't like automagic stuff. I'm happy when computers do exactly what I tell them, even if that means they sometimes do the wrong thing.
[ambrus]: And I don't much like syntax highlighters. If you need a syntax highlighter to understand your code, then your code is written unclear.
[ambrus]: And if you need a syntax highlighter to color parenthesis green and numbers black and letters blue, then you're using the wrong font.
[ambrus]: I have to tolerate syntax highlighters when other people use them, but I don't use them myself. And sorry for the rant.

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (11)
As of 2017-02-27 12:43 GMT
Find Nodes?
    Voting Booth?
    Before electricity was invented, what was the Electric Eel called?

    Results (385 votes). Check out past polls.