-
Notifications
You must be signed in to change notification settings - Fork 213
"typedef" with reference name. #4309
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
Comments
This is a languge request. You're proposing to have properties attached to types which are available on type variables. Further, you are proposing that function types that come from type aliases, and which are today completely indistinguishable (function types are structural types, they have no identity or declaration), will have something to distinguish the source (literally) of the type. typedef F1 = void Function();
typedef F2 = void Function();
void foo<T extends void Function()>() {
// T from where ???
}
void main() {
foo<F1>();
foo<F2>();
foo<void Function()>();
} today, then there is no way to distinguish the types bound to Which means that whatever is carried through the type parameter in your proposal is not the type, it's some kind of metadata which flows along with the type. Not impossible, but a little worrisome, because it means you need to correctly track the flow of types, even when the compiler might know that they're the same type. What type is the Why only function types. You can type-alias other types too: typedef Name = String;
typedef Address = String;
void main() {
print(Name.refName == Address.refName); // false?
} (This would presumably work, since the But not all types come from a type-alias. Not even all function types, so what is the At least it's a runtime property, so it's not affected by static type inference. What would you expect this program to print? typedef F1 = void Function();
typedef F2 = void Function();
class C1<T extends F1> {
bool foo<X extends T>() => X.refName == F1.refName;
}
class C2<T extends F2> extends C1<T> {}
class C3<T extends F2> extends C2<T> {
bool foo<X extends T>();
}
void main() {
print(C1().foo());
print(C1<F1>().foo());
print(C1<F2>().foo());
print(C2().foo());
print(C2<F1>().foo());
print(C2<F2>().foo());
print(C3().foo());
print(C3<F1>().foo());
print(C3<F2>().foo());
var c1 = C1();
var c2 = C2();
C1 c21 = c2;
var c3 = C3();
C2 c32 = c3;
C1 c31 = c3;
print(c1.foo());
print(c2.foo());
print(c21.foo());
print(c3.foo());
print(c32.foo());
print(c31.foo());
} I have my guesses. |
Maybe a good question to ask here would be "what's the workaround without using
extension type OnSetup._(VoidCallback callback) {}
extension type OnClearName._(VoidCallback callback) {}
extension type OnBtnClick._(VoidCallback callback) {} Maybe it's also worth noting that registering and calling a list of closures is exactly what ChangeNotifier was designed for. All in all, when reading through the use case you've shared, my gut response is to be excited about several ways we could accomplish it via existing tools rather than wishing we had another language feature. |
@nate-thegrate I don't think extension types works well here for two reasons.
extension type OnSetup._(VoidCallback callback) {}
extension type OnClearName._(VoidCallback callback) {}
extension type OnBtnClick._(VoidCallback callback) {}
void main() {
print(OnSetup == OnClearName); // true
print(OnSetup == OnBtnClick); // true
print(OnClearName == OnBtnClick); // true
} As a result
I would agree, I think this can be solved in a number of ways with existing features, for example using an import 'dart:ui';
import 'package:flutter/widgets.dart';
enum Action { onSetup, onClearName, onBtnClick }
class People {
static final Map<Action, List<VoidCallback>> _callbacks = {};
/// Register a callback for the specific type
static void on(Action action, VoidCallback callback) {
_callbacks.putIfAbsent(action, () => []).add(callback);
}
/// Execute the callback registered of the specific type
static void call(Action action) {
if (_callbacks.containsKey(action)) {
for (var callback in _callbacks[action]!) {
callback();
}
}
}
}
main() {
People.on(Action.onSetup, () {
print('Hi');
});
People.on(Action.onClearName, () {
print('Dart');
});
People.on(Action.onBtnClick, () {
print('How are you?');
});
People.call(Action.onSetup);
} Output
|
Oh wow, I had no idea! (I knew that the object returned by an extension type's "generative constructor" is identical to whatever it was wrapping, so I guess it makes sense for the types themselves to be identical as well.)
Yeah, I remember that issue. I didn't bring it up here, mostly because I was confused about the That enum example looks fantastic, thanks for putting it together! |
Hello everyone, a good son returns home! 😊
I contributed to the bool.parse feature, and now I'm interested in contributing a new feature for typedef.
I’d like to gather community feedback on whether it makes sense for typedef, which serves as an alias for a function, to also carry a refname. This would allow scenarios like the following example to work:
Current Code
Output
Hi Dart How are you?
The expected
Output
Justification
My proposal is to introduce a refname property to typedef, allowing comparisons based on the alias name rather than just the function type. This would make it easier to work with type-based mappings, such as event-driven architectures or dependency injection scenarios.
Impact
N/A
Mitigation
N/A
Change Timeline
N/A
Associated CLs
N/A
The text was updated successfully, but these errors were encountered: