In a message dated Wed, 27 Sep 2006, Aaron Sherman writes:
Any thoughts?

I'm still thinking about the practical implications of this... but what immediately occurs to me:

The point of multiple, as opposed to single, dispatch (well, one of the points, and the only point that matters when we're talking about multis of a single invocant) is that arguments are not bound to a single type. So at first gloss, having a single prototype in the core for all same-named multis as in your proposal seems to defeat that use, because it does constrain arguments to a single type.

I would hate for Perl 6 to start using C<Any> or C<Whatever> in the sort of ways that many languages abuse "Object" to get around the restrictions of their type systems. I think that, as a rule, any prototype encompassing all variants of a multi should not only specify types big enough to include all possible arguments, but also specify types small enough to exclude impossible arguments.

In other words, to use your proposal, "our proto moose (Moose $x:)" should assert not just that all calls to the multi moose will have an invocant that does Moose, but also that all objects of type Moose will work with a call to the multi moose. That may have been implicit in your proposal, but I wanted to make it explicit.

In practice, the ability to use junctive types, subsets, and roles like any other type makes the concept of "single type" a much less restrictive one in Perl 6 than in most languages. For example, if you wanted C<max> to work on both arrays and hashes, you could have

  our proto max (Array|Hash $container)

Or you could define an C<Indexed> role that both Array and Hash do and have:

  our proto max (Indexed $container)

So maybe this is a reasonable constraint. But it seems odd to me that Perl might then not allow me to write a C<max> that takes, say, Bags or Herds or whatever. And as I said before, I think a prototype of

  our proto max (Whatever $container)

is incorrect too. What I really want is for max to be callable on anything that can do max, and not on anything that can't. Following that observation to its logical conclusion, at some point we get to the core containing prototypes like:

  our proto max(Maxable $container)
  our proto sort(Sortable $container)
  our proto keys(Keyable $container)

which (I think) results in no better support for contracts, but merely requires gratuitious typing (in both senses of the word): where before we could just write our routine "multi max...", now we need to write both "multi max..." and remember to add "does Maxable" so Perl will let us compile it.

My apologies if I'm attacking a strawman here; perhaps there's a saner way to allow the flexibility for users to define novel implementations of global multis while still having the prototypes well-typed.

All that said, the globalness of multis does concern me because of the possibility of name collision, especially in big systems involving multis from many sources. Your proposal would at least make an attempt to define a multi not type-conformant with a core prototype throw a compile-time error, rather than mysterious behavior at runtime when an unexpected multi gets dispatched.


Reply via email to