On Thu, Mar 13, 2003 at 10:21:25PM +1100, Damian Conway wrote:
: But if I say:
: : sub foo(@a is Array of Int) {...}
: ...
: foo(@x);
: : then I'm saying: "within &foo, @a is just another name for @x". So they are : (temporarily) the same thing. That can only (be allowed to) happen if the : actual type of @x satisfies all the requirements of the declared type of @a.
Which condition holds if @x is an array of Scalar! Because a Scalar polymorphically supports the Int, Num, Str, and Ref interfaces.
Err, sorry, no it doesn't.
Either Scalar is the superclass of those four, in which case a Scalar isn't
sufficient to satisfy the requirements of an Int; or Scalar is a disjunction of those four, in which case it's still not guaranteed that whatever the Scalar is holding will satisfy the requirements of an Int.
As I said before it comes down to whether a parameter type is a specification that:
a) The argument passed here must be something that could conceivably not cause the program to crash and burn, and we'll verify that at run-time if necessary.
or:
b) The argument passed here must be something that will definitely not cause the program to crash and burn, and we'll verify that at compile-time.
I'm arguing that the former is well-nigh useless, and that the latter is what large systems developers and optimizer writers have been begging for. Besides which, the latter gives you the former. If you don't care about compile-time type checking, declare the *parameter* as Scalar, and let it accept anything.
But if type-specialized parameters are allowed to take *anything*, then they're nigh on worthless, except as a (third) coercion mechanism (in addition to explicit int($x), +$x, ~$x; and implicit contextual coercions).
Damian