Open toddr opened 4 years ago
This is a huge and slippery minefield. Right now signatures basically only match on the quantity of arguments passed and are not sensitive to the values contained therein. Thus you could
multi sub add($x) { ... }
multi sub add($x, $y) { ... }
currently and it would have some hopefully-expected dispatch semantics. However, if that's as far as it goes then it's hard to imagine in practice what different behaviours the different-arity implementations of this function would have that can't be accounted for by just providing default values for the missing arguments:
sub add($x, $y = 1) { ... }
and in fact even more generally you can always detect the case because of the way the expressions are written:
sub add($x, $y = (my $y_was_missing = 1), 1) { ... }
The slippery minefield (am I mixing my metaphors?) comes if we want to consider dispatch by considering anything about the runtime values contained within those parameters. E.g. a common point that some other languages might jump into first off the bat is to consider a multiple-dispatch method which distinguishes strings from numbers:
multi sub bark($x : str) { ... }
multi sub bark($x : num) { ... }
which I feel would be a huge departure from anything we have existing in Perl. If you added that then the temptation would be now to ask why don't we have such type annotations on non-multiple dispatch?
sub roar ($x : str) { ... }
At which point why can I only put such type-restricting declarations on sub parameters and not regular variables?
my $y : str = func();
Or can I now use these types to dispatch other things in Perl? Maybe a typed switch-like statement?
cond($z) {
where(str) { say "z is a string" }
}
Maybe I get typed catch
(a commonly-requested feature)... Maybe we can do regexp matches and allsorts and this begins to feel like smartmatch all over again and I think I want to stop here.
When I saw this I thought it referred to dispatching on the dynamic type of more than one object.
ie.
# definitions elided
package B {} package C1 { our @ISA = 'B'; } package C2 { out @ISA = 'B';}
package Foo {
sub f ($self, $b : C1) { ... } # One
sub f ($self, my $b : C2) { ... } # Two
}
package Bar {
sub f ($self, my $b : C1) { ... } # Three
sub f ($self, my $b : B) { ... } # Four
}
my $o1 = Foo->new;
my $o2 = C2->new;
my $o3 = Bar->new;
$o1->f($o2); # calls Two
$o3->f($o2); # calls Four
I think what @toddr described is function polymorphism
I dislike multi-method dispatching with a passion, to be honest.
Multi method dispatch requires a kind of type system that we don't have. I suspect this will fail for exactly the same kinds of reasons why smartmatch failed.
Same name different signatures.