0

I would to call my subs without using parentheses around the argument lists. For example, I'd like to use

mypush \@list, $item;

instead of

mypush(\@list, $item);

To accomplish that, I've declared my sub with a prototype.

sub mypush (+@) { push shift, @_ }

In fact, that also allows me to the following, but that's just a bonus:

mypush @list, $item;

Other than having to declare subroutines with prototypes before using them anywhere in the code, is there any serious drawback to using prototypes in Perl?

Code looks definitely cleaner to me. But where in general can prototypes go wrong? When would I regret it?

ikegami
  • 367,544
  • 15
  • 269
  • 518
eduardo.tex
  • 115
  • 5
  • See [Perlcritic - Subroutine prototypes](http://stackoverflow.com/questions/8573437/perlcritic-subroutine-prototypes) – Håkon Hægland Aug 05 '15 at 16:24
  • 4
    Have you read everything from [this question](http://stackoverflow.com/questions/297034/why-are-perl-5s-function-prototypes-bad)? – mob Aug 05 '15 at 16:25
  • 4
    and [this](http://www.perlmonks.org/?node_id=861966) – mob Aug 05 '15 at 16:38
  • 1
    @Borodin, I only edit what I was thought was an accidental mistake. Turns out the other 95% of the question was the accidental mistake. Fixed, reopened, deleted the obsolete comments that I could, flagged the others, and answered the question. – ikegami Aug 05 '15 at 19:54

2 Answers2

5

One of the biggest drawbacks is that it makes the code harder to maintain. Very few people seem to understand what a Perl prototype actually does, so there is a lot of guessing and cargo-culting around them.

Note, though, that Perl 5.20 has added a subroutine signature feature. It's still experimental, but it's really kinda awesome and what most people expect prototypes to do. And, when we get type constraints added (oh Santa, please please please bring me those for Christmas I promise I'll be good!), we'll have what I think most people try to do with prototypes (with some syntax I make up):

sub foo (Int $foo, String $var, Int @array) { ... }
brian d foy
  • 129,424
  • 31
  • 207
  • 592
  • Hum, if this is the answer the op wants, the question should be closed as a dup. I have just done this. – ikegami Aug 06 '15 at 16:45
1

Your question is moot since prototypes have no effect on the need for parens. As long as the sub is declared before it's used, parens are optional.

$ perl -E'
   sub foo { say @_; }
   foo "bar";
'
bar

$ perl -E'
   sub foo;
   foo "bar";
   sub foo { say @_; }
'
bar

Note that there are serious downsides to omitting parens.

  1. It's easy to accidentally pass the wrong arguments to a sub:

    $ perl -E'
       sub foo { say @_; }
       foo 9*6;
       foo (4+5)*6;
    '
    54
    9
    
  2. Errors in the code can lead to misleading and confusing error messages.

    $ perl -E'foo bar "baz";'
    Can't locate object method "foo" via package "bar"
       (perhaps you forgot to load "bar"?) at -e line 1.
    

    Here's another example of the wackiness in store for you when you omit parens.

The problems are arguably worse than the problems that result from using prototypes. Using either of these "features" doesn't seem wise; introducing both sets of problems is even less so.

Community
  • 1
  • 1
ikegami
  • 367,544
  • 15
  • 269
  • 518