-
Notifications
You must be signed in to change notification settings - Fork 718
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
Adapt implicit cast example for type system page #6478
base: main
Are you sure you want to change the base?
Conversation
Visit the preview URL for this PR (updated for commit a4175df): https://dart-dev--pr6478-feat-type-system-implicit-casts-j5bzqnf7.web.app |
Thank you for adding that staged link! A dream: we have those created by default when we stage. ^_^ |
@eernstg, adding you as our technical reviewer. Can you double-check the staged doc? If you want to triage this to another technical expert, please do so. Note to Dart engineers: on reviews where any doc changes are added that modify technical content, we generally need to make sure we have at least one technical writer and one additional engineer on those PRs for review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM from a programming language perspective. I recommended a couple of simplifications.
} | ||
``` | ||
|
||
In this example, if `objects` is a `List<String>`, the cast succeeds. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this example, if `objects` is a `List<String>`, the cast succeeds. | |
In this example, if `object` is a `String`, the cast succeeds. |
``` | ||
|
||
In this example, if `objects` is a `List<String>`, the cast succeeds. | ||
If it's not a subtype of `List<String>`, such as `List<int>`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's not a subtype of `List<String>`, such as `List<int>`, | |
If it's not a subtype of `String`, such as `int`, |
List<String> [!strings = objects!]; // Runtime downcast check. | ||
String string = strings[0]; | ||
} | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd recommend using a simpler example: The downcast in the current example takes two steps, but we would already have a perfectly useful example if it is adjusted to take just one step.
The first step in the current example is concerned with the class: Starting from dynamic
, it is tested whether the given object is a list. We could say that we're checking for the type List
, which is just an abbreviated notation for List<dynamic>
. Next, when we know that it is a list, we check for the type argument String
(which is a cast from List<dynamic>
to List<String>
). This second step is based on a subtype relation known as covariance.
I think the topic of the example should just be "implicit downcasts from dynamic
", and there's no need to include anything that requires the reader to think about a two-step subtype relationship that also involves variance.
Here's one possible way to do this:
int assumeString(dynamic object) {
String string = object; // Check at run time that it is a `String`.
return string.length;
}
I'd suggest using 'run time' rather than 'runtime', because the latter commonly refers to the support system which is running along with a program (providing external functions like print
, services like garbage collection, etc.) In contrast, 'run time' is a noun phrase that denotes a specific kind of point in time, namely: One that occurs during an execution of the program. If you want to use the corresponding adjective then it would be 'run-time', as in 'a run-time error occurs if it is not a string'.
|
||
<?code-excerpt "lib/strong_analysis.dart (fail-downcast-check)" replace="/\[.*\]/[!$&!]/g"?> | ||
```dart tag=runtime-fail | ||
assumeStrings(<int>[![1, 2, 3]!]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The notation [!1!]
should be a highlighted version of 1
(I'm not 100% sure about the syntax):
assumeStrings(<int>[![1, 2, 3]!]); | |
final length = assumeString([!1!]); |
I introduced a local variable to store the returned result. That's still a bit artificial because it isn't used anywhere, but I thought it was one step more natural than just having a local variable inside assumeStrings
and not returning anything.
Adds a section about implicit cast runtime errors to the "Type system" page, based off the Invalid casts section of the deprecated sound problems page.
Contributes to #6265
Staged: https://dart-dev--pr6478-feat-type-system-implicit-casts-j5bzqnf7.web.app/language/type-system#implicit-casts