Suppose Perl 5.20 let you write:
class IceCreamSundae;
method add_toppings(Array @toppings)
{
...
}
Ignore class
and method
. Concentrate on
Array
. What does that mean?
You can easily assume that this method adds zero or more toppings to an ice cream sundae. Again though, what does that mean?
Does the method access the Array
as a queue? As a stack? As a
linked list? As a double-ended queue? With standard iteration? With indexed
iteration? Is it destructive? Does it hold references to the elements of the
array, thus increasing their lifespan with regard to garbage collection?
Sure, you can make cheap and easy type checking work in this case (it's a big patch in Perl 5, but it's not an impossible patch), but what does this code mean?
If we're going to use languages where we don't have to worry about the precise layout of our data structures in memory (because C has the type system of PDP-8 assembly language), we should aim for something more specific and useful and denotative than "Everyone knows what an array is!"
Well-factored programs walk a tight balance between overspecifying their interfaces, thus too-tightly coupling themselves to specific representations, and launching architecture astronauts into space with the unuseful Gordian-knot complexity of too much genericity.
... but it's tempting to use the language's core primitives, because everyone knows what an array means even though no one knows exactly what you're doing with it, which is really the important part of what a good type system can specify.
(Yes, I've written Haskell code. I appreciate Hindley-Milner and consider myself privileged to have corresponded with Dr. Milner about language design in depth. That doesn't change the fact that I can write trivial mathematical code in Haskell which looks obviously correct both to readers and the type checker but which generates infinite loops due to simple arithmetic principles. If you choose the wrong types, you will get the wrong behavior.)