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

Comment on

( #3333=superdoc: print w/replies, xml ) Need Help??
If you read the FMTYEWTK article (there are links in this thread) by Tom C. then youll get a good idea of what prototypes are for, but heres a quickie explanation

Basically prototypes are a workaround for specifying input templates (they would be better called "function parameter context coercion templates" or something like it.) The idea is that perls tokenizer/lexer needs to handle a variety of ways that a function can be called, and which context its parameters should be in. For example take the scalar function. It puts its argument a scalar context, but it also needs to know that it accepts only a single item (ie have its argument _in_ a scalar context too). Otherwise the below code would print out "6" and not "5-Bar".

sub foo{ print join "-",@_}; my @array=qw(a b c d e); foo(scalar @array,"Bar");
Think about it, if we wrote scalar() by hand we might code it something like:
sub my_scalar { my $count=0; $count++ foreach @_; return $count; }
But of course then we couldnt say foo(my_scalar @array,"bar") as it would return the wrong value. We would have to write it as foo(my_scalar(@array),"bar") which im sure you admit would be a PIA considering the number of times and places you would have to do so. This kind of thing gets even more serious when you consider subs like push() which expect the @array as the first value. Without prototypes we would have to do push(\@somearray,@values) otherwise the array would become listified byt the subroutine call.

Templates also perform a limited kind of type validation, but, and heres the problem, not consistantly. And not in the way they think. For instance

sub listy(\@){ print join("*",@{$_[0]}),"\n"; } listy @array;
Ensures that the first object is indeed an array, but then silently converts it to a reference to the array and passes it on. It will of course perform a certain level of type validation as it will barf on a non array being in that spot, but this behaviour is inconsistent as a '$' prototype will _not_ complain when a non scalar is provided, but rather simply "scalarify" whatever is provided. (Whichever form of scalarification makes the most sense.)

So prototypes are a kludgy work around to some problems in parsing the fairly loose rules of perl, not a way to get your parameters checked at run time.

Do take the time to read Tom C's article. I have only made a minor attempt at explaining the issues here.

Incidentally there are some rare situations where prototypes come in useful. Examples may be found in some of Michael Schwern's modules for instance in Carp::Assert you will find

sub assert ($;$) { unless($_[0]) { require Carp; Carp::confess( _fail_msg($_[1]) ); } return undef; }
So why did he use prototypes here? Well he wanted people to be able to say
assert @array,"Array must have elements within";
instead of
assert scalar @array,"...";
This is what prototypes in perl are for, making the semantics of a subroutine perfom "naturally" in context. Unfortunately when people try to use them as parameter validation mechanisms the resulting subs tend to behave "unnaturally", as they stop behaving as functions would be expected to behave. And this is IMO evil.


Yves / DeMerphq
Software Engineering is Programming when you can't. -- E. W. Dijkstra (RIP)

In reply to Re: Re: Are prototypes evil? by demerphq
in thread Are prototypes evil? by Django

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

    What's my password?
    Create A New User
    and all is quiet...

    How do I use this? | Other CB clients
    Other Users?
    Others contemplating the Monastery: (6)
    As of 2018-06-22 19:48 GMT
    Find Nodes?
      Voting Booth?
      Should cpanminus be part of the standard Perl release?

      Results (124 votes). Check out past polls.