Bob Rogers wrote:

I notice that this doesn't allow for anonymous classes, since provision
is made only for named classes.  Is anonymous class support in prospect?

You can't use an anonymous class as a type for multisub dispatch because they don't have a name to dispatch on. A case could be made for anonymous multimethod dispatch, since the list of multi candidates is stored in the class of the first invocant.

(The PDD does mention C<push_pmc> as the PIR API for adding methods to
multisubs, but such a sub must have already been declared :multi, with
named classes, so the C<push_pmc> will have been done automatically
anyway by the loader.)  To define a methods that dispatch on anonymous
classes, one would need to be able to pass an ordinary (non-:multi) sub
and an array of class objects to the method-adding method.  Since it is
syntactically illegal to put ":invocant" on non-multi subs, either this
restriction would have to be lifted, or some other means of declaring
invocant args would be needed, perhaps using a distinguished non-class
value in the class list.

A .sub has to be declared :multi to be used as a multi sub, even if stored as a method. We could provide a dummy type "SELF" that narrowly restricts the type match to the class of the first invocant, but it's only meaningful when :method and :multi are combined.

   BTW, shouldn't there be a requirement that the number of classes in
the :multi attribute match the number of :invocant params?  If not, what
does this mean?

Yes, the :multi attribute must specify as many types as the .sub has invocants (keeping in mind that the method invocant also counts as an invocant).

   As Klaas-Jan pointed out, the magical "_" is not documented.  But I
think we need a better way to specify "any type".  First of all, there
is no way to say "any PMC type" as distinguished from "any register
type" and "any type at all" (I think "_" means the last alternative,
true?).  Secondly, these types need explicit class names that point to
explicit class objects, at which point special-casing for "_" (among
other things) becomes unnecessary.

It's possible to create a variety of pseudo-classes for groupings that aren't strictly relations of inheritance or composition. But, better to wait for a specific practical use and implement it when needed.

For the most part, multiple dispatch at least needs to verify some minimal interface in its invocants, even if that requirement is as simple as "can act like a number", so differentiating on register type may not be very useful. Roles are likely to play a strong part.

   And somewhere, maybe not here, the type network of all Parrot
built-ins needs to be specified.  This amounts to casting it in stone,
but if we don't do it explicitly, it will be effectively cast in stone
by virtue of all the code that will break if we try to change it.

Builtin operations or builtin types? For the types, see PDD 17. We won't cast anything in stone, but a change to the type hierarchy would have a longer deprecation cycle than more trivial changes.

   Finally, a question:  What is the difference between an :invocant
parameter that isn't specialized (i.e. specifies "_" as the :multi
dispatch class), and leaving that parameter out of the :multi list
altogether?  In other words, is there any practical difference between
this:

        .sub test1 :multi(Integer, _, Integer)
                .param pmc i1 :invocant
                .param pmc x2 :invocant
                .param pmc i3 :invocant
                . . .
        .end

and this:

        .sub test1 :multi(Integer, Integer)
                .param pmc i1 :invocant
                .param pmc x2
                .param pmc i3 :invocant
                . . .
        .end

The latter example, with a non-invocant separating two invocants, isn't allowed.

Allison

Reply via email to