Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Signature restriction in roles in raku

Tags:

raku

Maybe I'm missing something, but I'd like to know if there is a good reason why this code should compile

role L {
  method do-l (Int, Int --> Int ) { ... }
}

class A does L {
  method do-l (Int $a, Real $b --> Str) {
    .Str ~ ": Did you expect Int?" with $a + $b
  }
}

my $a = A.new;

say $a.do-l: 2, 3.323

This will output

5.323: Did you expect Int?

I was curious if someone know a way for the compiler to at least throw some warning with the implemented signature of the role L.

like image 844
margolari Avatar asked Apr 11 '20 17:04

margolari


1 Answers

throw some warning with the implemented signature of the role L.

You get that if you prefix the method declaration with multi:

role L {
  multi method do-l (Int, Int --> Int ) { ... }
}

With this your program displays:

===SORRY!=== Error while compiling ...
Multi method 'do-l' with signature :(A: Int $, Int $, *%_ --> Int)
must be implemented by A because it is required by a role ...

I'd like to know if there is a good reason why this code should compile [without the multi]

I think the design intent was to support two notions of polymorphic composition:

  • Without the multi, enforcement only relates to existence of a method with the right name; parameters are ignored.

  • With the multi, enforcement covers the name and all parameters as well (or some).

My personal take on whether there's a good reason for:

  • Supporting two flavors of method polymorphism? Sometimes enforcing strict adherence to the signature is helpful. Sometimes it gets in the way.

  • Distinguishing them via multi? Full signature enforcement requires that implementing classes/roles have a method with exactly the same signature. But what if an implementing class/role wants to handle an int instead of Int for a parameter? Raku compromises. Provided an implementing class/role has an exactly compliant method it can also have variations. The perfect way to convey this is to prefix a stubbed method with multi.

  • Having the default be name only polymorphism? We could have chosen multi semantics as the default, and had users write an only prefix if they wanted name only polymorphism. But that would reverse the usual situation (i.e. ignoring stubbed methods). More generally, the intent is that Raku provides a wide range of stricture for its features, from relaxed to uptight, and picks a default for any given feature that is judged right based on feedback from users over the years.

What if the default doesn't seem right? What if the existing range of strictures isn't enough? What if one group thinks we should go left and another thinks we should go right?

Raku has (imo) remarkable governance mechanisms for supporting user driven language evolution. At the top level there are elements like the braid architecture. At the bottom level there are elements like versionable types. In the middle are elements like RoleToClassApplier which mediates the process of applying a role to a class, which is the point at which a required method needs to be found or the class's construction will fail. In short, if the language doesn't work the way you want, including such things as strictures, you can, at least in principle, change it so it does.

like image 105
raiph Avatar answered Oct 05 '22 17:10

raiph