Replies: 1 comment 1 reply
-
Does it even make sense for an interface declaration to declare a default? Maybe that should be left solely to the class. Otherwise -- let's consider some permutations:
|
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Among the various "roles" discussions to do with the class system, one use-case I often see is that people want to use them as some sort of "declared interface", in a way similar to the
interfacekeyword in languages like Java and C#. Now, Perl being a dynamic language that doesn't have static typing information; we have duck typing. All of this is entirely optional from an implementation perspective. Perl doesn't need anyone to declare a set of methods that are available on some variable. Given any example that people might write that uses roles purely as interface requirements, you could just delete all the interface declarations and Perl at least would continue to run it just fine. However, I'm aware that much like Perl features likeuse strict, proper use of declared interfaces like this can help to identify bugs at compile-time, so even while they're not strictly necessary it's still useful to lean into them as a safety mechanism.With that all in mind, my question today concerns the use of subroutine (well, I suppose we should say "method") signatures on methods in these declared interfaces. In particular: I feel it would be very useful to be able to declare signatures on required method declarations as part of interface-style roles. I definitely think you ought to be able to write the following, for example:
class Shape :abstract { method move_to ( $x, $y ); method resize ( $height, $width ); }Already to the human reader of this code we've made it more useful than simply declaring a set of method names - we've now been upfront and explained what we expect in terms of argument counts to these methods. At this point it begins to ask questions about how we might compare signatures on this interface declaration against signatures on methods that claim to implement it. Let's now consider:
class Square { apply Shape; method move_to ( $new_x, $new_y ) { ... } method resize ( @args ) { ... } }Again to the human reader it feels pretty clear that these two methods satisfy those interface declarations, in that any set of arguments that would satisfy the interface are accepted by these signatures. It doesn't matter that the argument names don't match - that's just internal details of the method body. But we can inspect the argument counts and be happy that all's good. But now what would happen in any of the following situations:
In both of those cases, the actual defined method has a signature that is entirely incompatible with the one given in the interface. It can't possibly work. I feel that this should lead to at least a compile-time warning, if not an outright compile-time error.
But we should note, that the signatures don't have to match exactly. In particular, it's always possiible that an actual method body defined in a class could be more permissive than the interface declaration would suggest. E.g. observe that in the actual Square class above we defined
resizeto take an entire array of arguments - that could permit zero, one, or more than two values, in addition to the exactly-two that the interface requires. This should be fine.I'm not sure it's on too many folks' radar yet, but Perl 5.44 will have a new ability in subroutine signatures, of named parameters. While above I said the names of parameter variables aren't important for comparing signatures for compatibility, but we should keep in mind the names of named ones, as they are. So for example, this would be permitted:
These things start to get quite subtle. And I haven't even touched on some of the more exciting questions in this area:
:Checkedattribute for subroutine signatures), does the class implementation get to inherit that for free?In the case of these various "inherit for free" situations, does that come about as a bit surprising? How do we balance Don't Repeat Yourself with the Principle of Least Surprise. It feels surprising if class method implementations suddenly gain default values and argument value validation assertions for free without being declared, but it feels too repetitive if the author of every class method has to write them out again.
I'd like to get at least some vaguely coherent thoughts together on all of these issues before we launch fullscale into trying to implement some sort of "required method interface" ability on the class system, as many of these questions will dig deep into however it gets built.
Beta Was this translation helpful? Give feedback.
All reactions