|There's more than one way to do things|
Re: Re: Are prototypes evil?by demerphq (Chancellor)
|on Sep 03, 2002 at 18:13 UTC||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".
Think about it, if we wrote scalar() by hand we might code it something like:
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
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
So why did he use prototypes here? Well he wanted people to be able to say
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