Skip to content
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

Revise the guidelines around types. #889

Merged
merged 5 commits into from
May 24, 2018
Merged

Revise the guidelines around types. #889

merged 5 commits into from
May 24, 2018

Conversation

munificent
Copy link
Member

After a lot of discussion with readability and language team folks, I
have a better understanding of what the consensus style is and how to
express it in guidelines.

After a lot of discussion with readability and language team folks, I
have a better understanding of what the consensus style is and how to
express it in guidelines.
@munificent munificent requested a review from chalin May 23, 2018 21:20
@googlebot googlebot added the cla: yes Contributor has signed the Contributor License Agreement label May 23, 2018
Copy link
Contributor

@chalin chalin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the changes. Please see the inlined comments.

var names = people.map((Person person) {
return person.name;
});
var names = people.map((Person person) => person.name);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍



### DO type annotate public declarations whose type isn't inferred.
### PREFER type annotating public top-level variables and fields if the type isn't obvious.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about: top-level variables and fields --> fields and top-level variables

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

{
// #docregion redundant-explicit
var things = new Set();
// #enddocregion redundant-explicit
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe name this region simply explicit (both here and in the design_good.dart file), because there is no redundancy if one must be explicit :) (Yes, I know that it is probably because this example comes under the "redundant" guideline.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

return highest;
}
{% endprettify %}
* What types should I write because I think it's best for them to be visible in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What -> Which

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

These guidelines help you answer the first question:

* [PREFER type annotating public top-level variables and fields if the type isn't obvious.](#prefer-type-annotating-public-top-level-variables-and-fields-if-the-type-isnt-obvious)
* [CONSIDER type annotating private top-level variables and fields if the type isn't obvious.](#consider-type-annotating-private-top-level-variables-and-fields-if-the-type-isnt-obvious)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For both of these guidelines I think that we should write "fields" before "top-level variables". E.g.,

PREFER type annotating public fields and top-level variables if ...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Good call.

@@ -1183,7 +1168,7 @@ List<List<Ingredient>> possibleDesserts(Set<Ingredient> pantry) {
{% endprettify %}

If the local variable doesn't have an initializer, then its type can't be
inferred. In that case, it *is* a good idea to annotate it. Otherwise, you get
inferred. In that case, it *is* a good idea to annotate. Otherwise, you get
`dynamic` and lose the benefits of types.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider:

lose the benefits of types --> lose the benefits of static type checking

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

{% endprettify %}

Here, the type annotation on the variable is used to infer the type argument of
constructor call in the initializer. In cases like this where inference produces
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

like this -> like this,

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Here, the type annotation on the variable is used to infer the type argument of
constructor call in the initializer. In cases like this where inference produces
the right type, it's usually abundantly obvious what the type argument will be
and writing it again is just noise.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Come to think of it, for sake of brievity, I'd consider dropping the sentence "In cases like this ... abundantly obvious ... just noise."

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair. Done. I thought it might help to provide some motivation, but it's probably overkill.

declarations, this guideline just restates that you should prefer typing "on the
left".
Here, since the variable has no type annotation, there isn't enough context to
determine what kind of Set to create, so the type argument should be provided
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set -> Set

or

Set -> set

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

put a type annotation in the initializer to get inference working, then typing
the local variable itself is the way to go.
{:.bad-style}
<?code-excerpt "misc/lib/effective_dart/design_bad.dart (inferred-wrong)" replace="/ +\/\/ ignore: invalid_assignment\n//g"?>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can probably shorten the replace expression:

replace="/ +\/\/ ignore: .*?\n//g"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@munificent
Copy link
Member Author

Thanks!

return highest;
}
{% endprettify %}
* Which types should I write because inference can't provide them for me?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete the blank line between these items, to make them more obviously a group. (Plus, they're shorter than the no-extra-space-between-items list that follows.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Type annotations are important documentation for how a library should be used.
They form boundaries between regions of a program to isolate the source of a
type error.
Consider:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a sentence explaining what to consider.

Also... this doesn't look like a variable or field to me. What does this section really cover?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops. Moved some stuff around and left this hanging. Fixed.

as important is guiding *maintainers* of your code. Adding type annotations to
private member and variable declarations can help future readers of your code
understand it, and help corral bugs.
### CONSIDER type annotating private top-level variables and fields if the type isn't obvious.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adjust to match whatever you do to the title of the previous guideline.

that energy choosing a great *name* for your local variable.
Local variables, especially in modern code where functions tend to be small,
have very little scope. Omitting the type focuses the reader's attention on the
more important *name* of the variable and its initialized value.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do the two examples have different local variable names? I found myself distracted by that, because I expected only the type annotations to be different.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea, which probably is lost on the reader, was that by not worrying about the type annotation, the author had the time to choose a better name. Probably trying to be too clever. Changed to use the same names.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes Contributor has signed the Contributor License Agreement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants