-
Notifications
You must be signed in to change notification settings - Fork 205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
extended
(temporary naming) classes
#3024
Comments
This sounds like you want to make a third-party class, Let's say you can just do that, just What would it mean? Well, statically we'd have to determine whether it's a sound subclassing, so We also need to check that What if one library declares a superclass which implements Or what if we declare that Most of our soundness rules depend on knowing all superclasses. OO type systems with subclassing declares a subclass in terms of what it is-a of. Having a way to add a superclass (or more than one) to a class that doesn't know about them, is not something the type system is built for. It means the class doesn't know what itself is. So, this is not very likely to fly unless we can somehow remove the "only one implementation of an interface" rule, which is unlikely. Could we just say that the subclass doesn't really implement the super-interface, it's just assignable to it. We just pretend. We allow you to assign a That's more like Rust trait than a Dart interface, so maybe it should be: trait Date { .... }
declare DateTime implements Date; and traits are special (and cannot implement interfaces, only other traits, which are less strict about being more than one thing than interfaces are). Or we could make all Dart interfaces act like that. Fat pointers, implementation provided on the side. I think it's at least it should be somehow consistent, but probably not entirely consistent with the current design. So another hard sell. (Sure, if we had just done traits from the start, everything would be easier.) But Rust traits are really just unboxed implicit wrapper objects. We could do implicit wrapper objects and forwarding instead. Then the only thing we need is a way to get back, so if we try to do an Then there is no limit to how may "superclasses" we can let an object be wrapped as. (But no easy solutions, that's for sure.) |
Thank you @lrhn for being better at explaining my own request than I was (your comment explains precisely what I meant to suggest). I was unfamiliar with Rust's traits, so if you agree, we could change the name for this issue for better understanding. |
About what you said about the wrapper objects, I'm completely guessing here, but is there any way for #2727 to be used for that? |
Rust traits are resolved statically in the case where the receiver type is known. In that case an invocation of a traits method will just be a function call to a piece of code which is known at compile time, and it is known statically that the given receiver is an appropriate receiver for that implementation. In the case where a reference in Rust has a type which is a trait (so the parameter is declared like Inline class methods are always resolved statically, and this means that they may be used in a situation which is similar to the former, but they will not work in situations like the latter. That is, if you want run-time dispatch to occur then you need to use an object that actually creates the connection between receiver type and method implementation; this may or may not be called a wrapper object, depending on how it is implemented/modeled. |
Just to point out, this could be, depending on how things are done, somewhat related to #83. Meaning that either issue could be worked on to fit the other one. If there was a way of creating a class and using it in the same place as a third-party class (not implementing/extending it), that would solve the use case mentioned in the OP. |
Mentioned this issue on #1612 because of HosseinYousefi's comment:
|
This issue, where Date only needs a subset of DateTime, could be resolved with extension types. extension type Date._(DateTime inner) {
const Date(DateTime inner) : inner = inner.copyWith(second: 0, minute: 0, hour: 0);
...
} or otherwise a normal dart class that does the same, which could then implement Comparable as desired I do like the idea of rust-like traits though, as they would have a ton of benefits. I feel like this is already demonstratable with extensions. otherwise, its just another way to talk about mixins, with the singular difference being that declaring our own "trait" allows us to implement it for any class we're aware of, which is something we can do with extensions, but cannot define an interface for. If we can bring these two concepts together into "traits," it could make the language much more powerful For instance, a In my opinion, the more language features that just-so-happens to solve multiple problems at once, the better. Rust does this super well. |
Sometimes, I find some classes created by some package/core dart (such as
DateTime
which I'll use as an example below), that have everything I need, but some extra methods/parameters that are useless for some specific cases.For example, if I want to have a
Date
class, that only hasyear
,month
andday
parameters and let's saycompareTo
,isAfter
andisBefore
methods.If later I want to create another class that extends it, I'll need to only implement these methods and not
toLocal
andtoUtc
for example, which, in my case wouldn't even make sense, and also, no need to always fill all time fields to 0, since forDate
they wouldn't even exist.But, I would like to have an easier way of using
DateTime
objects where myDate
class goes. I know that I could create an extension method forDateTime
that gives me theDate
or even create aDate
constructor that receives aDateTime
parameter. My only goal here is to ask if this could be made easier.I've seen #884 and #2166 that would maybe handle possible extra parameters/methods (or we could simply make that impossible, but I'm not sure that's easier because we would need to write two classes for solving that).
I thought to create something like:
I'm not sure how we would handle the transition from
DateTime
toDate
if there is a certain processing that needs to be done, (like, for example always transforming ittoUtc
to apply to dates in some specific cases) but I'm sure if you find this proposal interesting we can come up with a way of doing that.The text was updated successfully, but these errors were encountered: