-
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
Record "construction" syntax for typedef #2528
Comments
Is there something that could be improved for the error message? At least for collection literals? Such as:
If the expected context type then could be propagated to In other words, it seems like static analysis correctness should use forward flow analysis, but static analysis error reporting should do reverse flow analysis as much as it can. This would improve static analysis error reporting in general and not just for records. |
I think for collection literals, yes. |
As you say, that's just: typedef MyList = List<int>;
var x = MyList.of([1,2,3]); // Ooooooh, love!
typedef Rectangle = ({int height, int width});
List<Rectangle> gatherPoints() {
Rectangle first = (height: 1, width: 2);
Rectangle second = (heighth: 3, width: 4); // 1
var more = <Rectangle>[
(height: 5, width: 6),
(hieght: 7, width: 8), // 2
];
return [first, second, ...more];
} with no new syntax needed. I don't get the "but no thank you" to that. |
I just mean "no thank you" in that I wouldn't want to write type annotations that violate Effective Dart like https://dart.dev/guides/language/effective-dart/design#dont-write-type-arguments-on-generic-invocations-that-are-inferred and https://dart.dev/guides/language/effective-dart/design#dont-redundantly-type-annotate-initialized-local-variables. I don't live to serve Effective Dart (or rather, I say that I don't live to serve Effective Dart), and it should of course serve me. Maybe writing the type annotations would just be an exception I tack on in my mind, if I want stronger protection against field name mismatches.
I'm definitely not aiming for less characters with this proposal. |
It's actually an interesting example of why types are not necessarily unnecessary, even if they are redundant. Redundancy is used for validation. If the two things don't match up, then something is wrong. If they do, everything is fine. The Effective Dart rules ignores that and tells you to remove all redundancy. Maybe the problem is those rules. 😉 If you write Adding the ability to write Records are special. For lists, you can write For records, you cannot, because the record does not have a type separate from the types of its fields. I can see why putting the |
This is exactly the motivation for dart-lang/sdk#58773, which is a proposal to adjust the lint That concept is given a technical interpretation by categorizing certain expressions as having a obvious type (e.g., We may or may not want to update the corresponding Effective Dart rule: It can certainly be argued that a type annotation is not 'redundant' if it provides actual help to the author of the code (e.g., to avoid those typos), and later on for every reader or maintainer of the code (to understand what the type is, in order to understand other parts of the code). |
Yeah I've never been able to square this circle. I don't like the OK I agree this isn't super duper worth a new syntax, and we can see what arises when people start using records, and then use them long enough that they start wanting IDE refactoring support for their record types and record literals. |
Just to follow up briefly, since I don't think I saw this option mentioned above. You can get essentially exactly what you want already as follows: typedef MyList = List<int>;
var x = MyList.of([1,2,3]); // Ooooooh, love!
({int height, int width}) rectangle({required int height, required int width}) => (height : height, width : width);
List<Rectangle> gatherPoints() {
var first = rectangle(height: 1, width: 2);
var second = rectangle(heighth: 3, width: 4); // 1
var more = [
rectangle(height: 5, width: 6),
rectangle(hieght: 7, width: 8), // 2
];
return [first, second, ...more];
} Ever so slightly more verbose at the definition site, but maybe not too bad? |
Yeah that's not too bad! |
I also don't think we want to do anything special here. Taking a step back, records are introducing a structural type to Dart. Structural types are well known for making errors less obvious. In the example here, a big part of the problem is that you've got a couple of different record types flowing into a least upper bound and you get So, yes, if you start tossing a bunch of records in places where LUB happens, it's possible to get pretty opaque errors. My hope is that this won't be a huge problem in practice, for a combination of reasons:
|
This discussion sparked a thought, which I filed an issue on here. |
Don't you hate it when you are excited to use Records and try them out:
And you're greeted (theoretically) with a static error that a
List<Record>
is returned, but aList<({int height, int width})>
was expected! Where did you go wrong? What do you change? What a mess!You may be quick to see my errors here, but imagine a more complicated example, maybe more lines, more inference, type promotion, return values, lots of
var
this andfinal
that. Perhaps you have just recently changed the name of one field in the record type in the return type, and you're working on cleaning up the record literals.There has to be a better way!
What if we introduced a record "construction" syntax with a typedef, similar to said support for interface types:
Ah ha, now I get static errors at
// 1
and at// 2
, pointing out my spelling mistakes.I know that my Ron Popeil pitch has persuaded you :). You won't regret it!
Yes I only got the benefit of matching a Rectangle's fields with those in the literals because I took the time to spell out
Rectangle
, begrudgingly forced to program with characters in the main stretch of the keyboard, but such a small price. And Yes this could be similarly solved by requiring types everywhere (likeRectangle second = Rectangle(heighth: 3, width: 4);
orvar more = <Rectangle>[
), but, no thank you.The text was updated successfully, but these errors were encountered: