-
Notifications
You must be signed in to change notification settings - Fork 2
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
Early Return Macro #9
Comments
Sounds like a good idea! (Also not super familiar with the macro system) Based on my experience with custom build_runners, I think this should be possible with macros. My only concern is how this effects formatting. I don't know if a method annotated with a macro can still be formatted and what that would mean for the user experience. I'd also suggest that |
AFAIK the formatting is expected to work normally. I didn't understand the $ though, are you proposing that the macro can automatically transform the |
Yeah, and the initial implementation should be easy/efficient to implement - "Any $ at the end of an Ident or ) or ], transform into [$]". This should work for 99% of cases without conflict, and I'd expect all cases a user would ever write. So in the end result you would be able to do something like @$()
Result<User, int> buildUser(int userId) {
final email = getUser(userId)$.email;
final isVerified = isUserVerified(email)$;
...
} |
Note to future implementer: Worth investing if inlining the try-catch may lead to optimizations. e.g generated code Result<User, int> buildUser(int userId) {
final $ = _ResultEarlyReturnKey<F>._();
try {
// Body
} on _ResultEarlyReturnNotification<F> catch (notification) {
return notification.value;
}
} |
For a later addition, it may even be possible to skip try-catch all together. e.g. var $res = expr;
switch ($res) {
case Err():
return $res.into();
case Ok():
}
final x = $res.ok; |
This may a good opportunity to revisit #3 By adding a @$()
Result<User, int> buildUser(int userId) {
final email = getUser(userId).$.email;
final isVerified = isUserVerified(email).$;
...
} generates Result<User, int> buildUser(int userId) {
try {
// ignore: internal
final email = getUser(userId).$.email;
// ignore: internal
final isVerified = isUserVerified(email).$;
...
} on _ResultEarlyReturnNotification<F> catch (notification) {
return notification.value;
}
} Edit: This may cause some issues when mixing |
The most important thing imo it's to not let the early return be used outside the safe context of an early return expression. Other then that, I like the idea of being able to ditch the try-catch entirely |
Alright, this is a proposition that I don't know if it's possible with the current state of macros in Dart. This is based on my experience using the rust_core package, specially talking about early return.
Proposition
Create a dart macro for a function that has the return type of either
Result
orOption
, that can simplify the use of the early return operator:As you can see, we used the early return operator without explicitly wrapping it in an Early Return expression. Currently, this function works like this:
This would make it so you don't need to add the early return expression to get an early return key, while also providing the same safety guarantees that an explicit early return expression would give.
How to do this
I'm going to be honest, I have 0 idea if it is possible. I am not yet familiar enough with macros to say how it could be done, but I think this is how it could.
Let's call this part of the function body:
What the macro would have to do is to get the body and wrap it inside the early return expression:
The body would be able to access the early return operator without excplicity typing the early return context.
Again, 0 idea if it can be done, but it would be very helpful.
The text was updated successfully, but these errors were encountered: