|
|
Created:
5 years ago by vsm Modified:
4 years, 10 months ago CC:
dev-compiler+reviews_dartlang.org, Kathy Walrath Base URL:
https://github.com/dart-lang/dev_compiler.git@master Target Ref:
refs/heads/master Visibility:
Public. |
DescriptionRefactored this and uploaded here:
https://github.com/dart-lang/dev_compiler/blob/strong/STRONG_MODE.md
PTAL
R=jmesserly@google.com, rnystrom@google.com
Committed: https://github.com/dart-lang/dev_compiler/commit/bc15ab3a70d4e2007b222c4eeb799ad0b8f31ed9
Patch Set 1 #Patch Set 2 : minor fixes #
Total comments: 7
Patch Set 3 : Rename to STATIC_SAFETY and restore old doc #Patch Set 4 : Address Bob's comments #
Total comments: 22
Patch Set 5 : Address Leaf's comments #Patch Set 6 : Runtime safety #Patch Set 7 : More runtime text #Patch Set 8 : More runtime headings #
Total comments: 6
Patch Set 9 : Address Leaf's comments #Patch Set 10 : More updates #Patch Set 11 : Update #Patch Set 12 : Flesh this out #Patch Set 13 : Fixed links #
Total comments: 70
Patch Set 14 : Address comments #Patch Set 15 : git cl land #
Messages
Total messages: 20 (6 generated)
Description was changed from ========== Update strong mode doc ========== to ========== Update strong mode doc This is not ready yet. Some opens: - separate out discussion of static behavior and runtime behavior - perhaps we need some distinct terminology? - update out-of-date text (e.g., around field overrides) - preserve discussion around JS codegen - but maybe in a separate doc? ==========
vsm@google.com changed reviewers: + leafp@google.com, rnystrom@google.com
What are the dots in the headings about? https://codereview.chromium.org/1541833002/diff/20001/STRONG_MODE.md File STRONG_MODE.md (right): https://codereview.chromium.org/1541833002/diff/20001/STRONG_MODE.md#newcode47 STRONG_MODE.md:47: An explicit goal of strong mode to provide stronger typing while preserving the terseness of Dart. While strong mode requires and/or encourages more static type annotations, our aim is make this as lightweight as possible. I would omit the last sentence. I don't think strong mode requires a significant amount of annotations beyond what people are already writing. If anything, I might add a sentence like, "While we want to give users better static analysis, we don't want them to have to do much, if any, additional work on their part to get it." https://codereview.chromium.org/1541833002/diff/20001/STRONG_MODE.md#newcode68 STRONG_MODE.md:68: ###. Top-level and Static Fields ? https://codereview.chromium.org/1541833002/diff/20001/STRONG_MODE.md#newcode235 STRONG_MODE.md:235: The primary sources of unsoundness in Dart are generics and functions. Both introduce circularity in the Dart subtyping relationship. Not implicit downcasting? https://codereview.chromium.org/1541833002/diff/20001/STRONG_MODE.md#newcode239 STRONG_MODE.md:239: Generics in Dart are co-variant, with the added rule that the `dynamic` type may serve as both ⊤ (top) and ⊥ (bottom) of the type hierarchy in certain situations. For example, let *<:<sub>D</sub>* represent the standard Dart subtyping rule. Then, for all types `S` and `T`: No hyphen in "covariant".
Moved this to a separate file. Bob's comments are address in patch 4. Perhaps we should move these new md files to the docs directory and leave a small top-level STRONG_MODE.md (that link is already out) with pointers. https://codereview.chromium.org/1541833002/diff/20001/STRONG_MODE.md File STRONG_MODE.md (right): https://codereview.chromium.org/1541833002/diff/20001/STRONG_MODE.md#newcode47 STRONG_MODE.md:47: An explicit goal of strong mode to provide stronger typing while preserving the terseness of Dart. While strong mode requires and/or encourages more static type annotations, our aim is make this as lightweight as possible. On 2015/12/22 21:30:58, Bob Nystrom wrote: > I would omit the last sentence. I don't think strong mode requires a significant > amount of annotations beyond what people are already writing. > > If anything, I might add a sentence like, "While we want to give users better > static analysis, we don't want them to have to do much, if any, additional work > on their part to get it." Reworked this. https://codereview.chromium.org/1541833002/diff/20001/STRONG_MODE.md#newcode68 STRONG_MODE.md:68: ###. Top-level and Static Fields On 2015/12/22 21:30:58, Bob Nystrom wrote: > ? Ugh. Emacs markdown mode sucks. Switching to a different editor. https://codereview.chromium.org/1541833002/diff/20001/STRONG_MODE.md#newcode235 STRONG_MODE.md:235: The primary sources of unsoundness in Dart are generics and functions. Both introduce circularity in the Dart subtyping relationship. On 2015/12/22 21:30:58, Bob Nystrom wrote: > Not implicit downcasting? No, that doesn't affect the underlying type system, because that implicit cast becomes an explicit cast in (DDC or checked mode) generated code. In a sense, implicit casts determine whether: Object x = ...; String y = x; is either an error or syntactic sugar for: Object x = ...; String y = x as String;
https://codereview.chromium.org/1541833002/diff/60001/STATIC_SAFETY.md File STATIC_SAFETY.md (right): https://codereview.chromium.org/1541833002/diff/60001/STATIC_SAFETY.md#newcode62 STATIC_SAFETY.md:62: - Allocation expressions Generic method argument inference as well. It may not be worth worrying about, but really local variables, allocation expressions, and generic method arguments are all inferred in the same pass, which is observable in cases like: List<int> o; // x will be inferred to have type int, because generic method argument inference kicks in. var x = o.fold(0, (x, y) => x + y); https://codereview.chromium.org/1541833002/diff/60001/STATIC_SAFETY.md#newcod... STATIC_SAFETY.md:131: The second form inference is limited to instance fields (not methods) and is similar to that on static fields. For instance fields where the static type is omitted and an initializer is present, the field’s type is inferred as the initializer’s type. In this continuation of our example: missing 'of' between 'form' and 'inference'. https://codereview.chromium.org/1541833002/diff/60001/STATIC_SAFETY.md#newcod... STATIC_SAFETY.md:163: The final form of strong mode inference is on allocation expressions. This inference is rather different from the above: it tightens the runtime type of the corresponding expression using the static type of its context. Contextual inference is used on expressions that allocated a new object: closure literals, map and list literals, and explicit constructor invocations (i.e., via `new` or `const`). I think "expressions that allocated" reads better as "expressions that allocate" since you start out the sentence in present tense. https://codereview.chromium.org/1541833002/diff/60001/STATIC_SAFETY.md#newcod... STATIC_SAFETY.md:163: The final form of strong mode inference is on allocation expressions. This inference is rather different from the above: it tightens the runtime type of the corresponding expression using the static type of its context. Contextual inference is used on expressions that allocated a new object: closure literals, map and list literals, and explicit constructor invocations (i.e., via `new` or `const`). Final form, except generic method arguments. https://codereview.chromium.org/1541833002/diff/60001/STATIC_SAFETY.md#newcod... STATIC_SAFETY.md:185: Strong mode sidesteps this difficulty via contextual inference. It infers the closure type as `(dynamic) -> int`. This is the most general type allowed by the context: the parameter type of apply. Actually, it will now infer it as `(int) -> int`. https://codereview.chromium.org/1541833002/diff/60001/STATIC_SAFETY.md#newcod... STATIC_SAFETY.md:195: the runtime type is inferred as `List<String>` in order to match the context of the left hand side. In other words, the code above executes as if it was: maybe say "the code above is type checked and executes as if" and maybe point out that List<String> l = ["hello", 3] will be rejected (you point this out below in the nested example, but it's a more complicated example that's demonstrating other things as well, so maybe worth emphasizing this in a simple example). https://codereview.chromium.org/1541833002/diff/60001/STATIC_SAFETY.md#newcod... STATIC_SAFETY.md:243: where `List` is equivalent to `List<dynamic>`. This introduces circularity - e.g.,: extra comma "e.g.,:" https://codereview.chromium.org/1541833002/diff/60001/STATIC_SAFETY.md#newcod... STATIC_SAFETY.md:377: - A non-generic class type (e.g., `Object`, `String`, `int`, ...). extra comma after e.g.? https://codereview.chromium.org/1541833002/diff/60001/STATIC_SAFETY.md#newcod... STATIC_SAFETY.md:378: - A generic class type where all type parameters are implicitly or explicitly `dynamic` (e.g., `List<dynamic>`, `Map`, …). ditto? https://codereview.chromium.org/1541833002/diff/60001/STATIC_SAFETY.md#newcod... STATIC_SAFETY.md:379: - A function type where the return type and all parameter types are `dynamic` (e.g., (`dynamic`, `dynamic`) -> `dynamic`, ([`dynamic`]) -> `dynamic`). ditto? https://codereview.chromium.org/1541833002/diff/60001/STATIC_SAFETY.md#newcod... STATIC_SAFETY.md:411: strong mode requires `expr` to be a subtype of `Future`. In standard Dart, this is not required although tools may provide a hint. This is no longer true - we allow await on Future<T> or on T, and we allow async functions to return T or Future<T>.
https://codereview.chromium.org/1541833002/diff/60001/STATIC_SAFETY.md File STATIC_SAFETY.md (right): https://codereview.chromium.org/1541833002/diff/60001/STATIC_SAFETY.md#newcode62 STATIC_SAFETY.md:62: - Allocation expressions The order here is based on the old code in dev_compiler. On 2016/01/14 01:07:17, Leaf wrote: > Generic method argument inference as well. It may not be worth worrying about, > but really local variables, allocation expressions, and generic method arguments > are all inferred in the same pass, which is observable in cases like: > > List<int> o; > // x will be inferred to have type int, because generic method argument > inference kicks in. > var x = o.fold(0, (x, y) => x + y); > If the above are top-level fields, do we still infer x's type? https://codereview.chromium.org/1541833002/diff/60001/STATIC_SAFETY.md#newcod... STATIC_SAFETY.md:163: The final form of strong mode inference is on allocation expressions. This inference is rather different from the above: it tightens the runtime type of the corresponding expression using the static type of its context. Contextual inference is used on expressions that allocated a new object: closure literals, map and list literals, and explicit constructor invocations (i.e., via `new` or `const`). On 2016/01/14 01:07:17, Leaf wrote: > I think "expressions that allocated" reads better as "expressions that allocate" > since you start out the sentence in present tense. Done. https://codereview.chromium.org/1541833002/diff/60001/STATIC_SAFETY.md#newcod... STATIC_SAFETY.md:163: The final form of strong mode inference is on allocation expressions. This inference is rather different from the above: it tightens the runtime type of the corresponding expression using the static type of its context. Contextual inference is used on expressions that allocated a new object: closure literals, map and list literals, and explicit constructor invocations (i.e., via `new` or `const`). On 2016/01/14 01:07:17, Leaf wrote: > Final form, except generic method arguments. Added section, fixed text. https://codereview.chromium.org/1541833002/diff/60001/STATIC_SAFETY.md#newcod... STATIC_SAFETY.md:185: Strong mode sidesteps this difficulty via contextual inference. It infers the closure type as `(dynamic) -> int`. This is the most general type allowed by the context: the parameter type of apply. On 2016/01/14 01:07:17, Leaf wrote: > Actually, it will now infer it as `(int) -> int`. Done. https://codereview.chromium.org/1541833002/diff/60001/STATIC_SAFETY.md#newcod... STATIC_SAFETY.md:195: the runtime type is inferred as `List<String>` in order to match the context of the left hand side. In other words, the code above executes as if it was: On 2016/01/14 01:07:17, Leaf wrote: > maybe say > > "the code above is type checked and executes as if" > > and maybe point out that List<String> l = ["hello", 3] will be rejected (you > point this out below in the nested example, but it's a more complicated example > that's demonstrating other things as well, so maybe worth emphasizing this in a > simple example). Done. https://codereview.chromium.org/1541833002/diff/60001/STATIC_SAFETY.md#newcod... STATIC_SAFETY.md:243: where `List` is equivalent to `List<dynamic>`. This introduces circularity - e.g.,: On 2016/01/14 01:07:17, Leaf wrote: > extra comma "e.g.,:" Done. https://codereview.chromium.org/1541833002/diff/60001/STATIC_SAFETY.md#newcod... STATIC_SAFETY.md:377: - A non-generic class type (e.g., `Object`, `String`, `int`, ...). On 2016/01/14 01:07:17, Leaf wrote: > extra comma after e.g.? Going British on us? :-) https://en.wiktionary.org/wiki/e.g.#Usage_notes https://codereview.chromium.org/1541833002/diff/60001/STATIC_SAFETY.md#newcod... STATIC_SAFETY.md:411: strong mode requires `expr` to be a subtype of `Future`. In standard Dart, this is not required although tools may provide a hint. On 2016/01/14 01:07:17, Leaf wrote: > This is no longer true - we allow await on Future<T> or on T, and we allow async > functions to return T or Future<T>. Is that the standard Dart rule as well? Should we just delete the section or are we still doing something different?
https://codereview.chromium.org/1541833002/diff/60001/STATIC_SAFETY.md File STATIC_SAFETY.md (right): https://codereview.chromium.org/1541833002/diff/60001/STATIC_SAFETY.md#newcode62 STATIC_SAFETY.md:62: - Allocation expressions On 2016/01/14 16:35:14, vsm wrote: > The order here is based on the old code in dev_compiler. > > On 2016/01/14 01:07:17, Leaf wrote: > > Generic method argument inference as well. It may not be worth worrying > about, > > but really local variables, allocation expressions, and generic method > arguments > > are all inferred in the same pass, which is observable in cases like: > > > > List<int> o; > > // x will be inferred to have type int, because generic method argument > > inference kicks in. > > var x = o.fold(0, (x, y) => x + y); > > > > If the above are top-level fields, do we still infer x's type? Yes, though the generic type inference is not actually catching that case right now. But that's independent of being at top level or not. https://codereview.chromium.org/1541833002/diff/60001/STATIC_SAFETY.md#newcod... STATIC_SAFETY.md:377: - A non-generic class type (e.g., `Object`, `String`, `int`, ...). On 2016/01/14 16:35:14, vsm wrote: > On 2016/01/14 01:07:17, Leaf wrote: > > extra comma after e.g.? > > Going British on us? :-) > > https://en.wiktionary.org/wiki/e.g.#Usage_notes Heh... too much Wodehouse I guess. https://codereview.chromium.org/1541833002/diff/60001/STATIC_SAFETY.md#newcod... STATIC_SAFETY.md:411: strong mode requires `expr` to be a subtype of `Future`. In standard Dart, this is not required although tools may provide a hint. On 2016/01/14 16:35:14, vsm wrote: > On 2016/01/14 01:07:17, Leaf wrote: > > This is no longer true - we allow await on Future<T> or on T, and we allow > async > > functions to return T or Future<T>. > > Is that the standard Dart rule as well? Should we just delete the section or > are we still doing something different? Other than the fact that we do downwards inference based on the return type, I think we treat these the same as regular Dart, so yes I think we could delete this. https://codereview.chromium.org/1541833002/diff/140001/RUNTIME_SAFETY.md File RUNTIME_SAFETY.md (right): https://codereview.chromium.org/1541833002/diff/140001/RUNTIME_SAFETY.md#newc... RUNTIME_SAFETY.md:5: In the Dart Dev Compiler (DDC), static strong mode checks are augmented stricter runtime behavior. Together, they enforce the soundness of Dart type annotations. 'augmented with'? https://codereview.chromium.org/1541833002/diff/140001/STATIC_SAFETY.md File STATIC_SAFETY.md (right): https://codereview.chromium.org/1541833002/diff/140001/STATIC_SAFETY.md#newco... STATIC_SAFETY.md:30: Strong mode is designed to work in conjunction with the Dart Dev Compiler (DDC), which uses static type verification to generate better code. It also may alone be used alone for stricter error checking. 'may alone be used alone' -> extra alone I think we should be slightly more explicit here that "stricter" != sound in the absence of the runtime checks. Somewhere we should mention that we keep covariant generics. https://codereview.chromium.org/1541833002/diff/140001/STATIC_SAFETY.md#newco... STATIC_SAFETY.md:57: To avoid this, strong mode uses type inference. In the case above, the strong mode infers and enforces the type of `x` as `Map<String, String>`. An important aspect to inference is ordering: when an inferred type may be used to infer other type. To maximize the impact, we perform the following inference in the following order: 'the strong mode' -> 'strong mode' ? 'other type' -> 'another type' or 'other types'?
https://codereview.chromium.org/1541833002/diff/140001/RUNTIME_SAFETY.md File RUNTIME_SAFETY.md (right): https://codereview.chromium.org/1541833002/diff/140001/RUNTIME_SAFETY.md#newc... RUNTIME_SAFETY.md:5: In the Dart Dev Compiler (DDC), static strong mode checks are augmented stricter runtime behavior. Together, they enforce the soundness of Dart type annotations. On 2016/01/15 00:01:10, Leaf wrote: > 'augmented with'? Done. https://codereview.chromium.org/1541833002/diff/140001/STATIC_SAFETY.md File STATIC_SAFETY.md (right): https://codereview.chromium.org/1541833002/diff/140001/STATIC_SAFETY.md#newco... STATIC_SAFETY.md:30: Strong mode is designed to work in conjunction with the Dart Dev Compiler (DDC), which uses static type verification to generate better code. It also may alone be used alone for stricter error checking. On 2016/01/15 00:01:10, Leaf wrote: > 'may alone be used alone' -> extra alone > > I think we should be slightly more explicit here that "stricter" != sound in the > absence of the runtime checks. > > Somewhere we should mention that we keep covariant generics. Done. https://codereview.chromium.org/1541833002/diff/140001/STATIC_SAFETY.md#newco... STATIC_SAFETY.md:57: To avoid this, strong mode uses type inference. In the case above, the strong mode infers and enforces the type of `x` as `Map<String, String>`. An important aspect to inference is ordering: when an inferred type may be used to infer other type. To maximize the impact, we perform the following inference in the following order: On 2016/01/15 00:01:10, Leaf wrote: > 'the strong mode' -> 'strong mode' ? > > 'other type' -> 'another type' or 'other types'? Done.
vsm@google.com changed reviewers: + paulberry@google.com
Description was changed from ========== Update strong mode doc This is not ready yet. Some opens: - separate out discussion of static behavior and runtime behavior - perhaps we need some distinct terminology? - update out-of-date text (e.g., around field overrides) - preserve discussion around JS codegen - but maybe in a separate doc? ========== to ========== Refactored this and uploaded here: https://github.com/dart-lang/dev_compiler/blob/strong/STRONG_MODE.md PTAL ==========
vsm@google.com changed reviewers: + jmesserly@google.com
PTAL
Only 31 comments! https://codereview.chromium.org/1541833002/diff/240001/STRONG_MODE.md File STRONG_MODE.md (right): https://codereview.chromium.org/1541833002/diff/240001/STRONG_MODE.md#newcode3 STRONG_MODE.md:3: Strong mode imposes a more restrictive type system on Dart to address its unsoundness. "imposes ... on" -> "applies ... to" "restrictive" -> "powerful" https://codereview.chromium.org/1541833002/diff/240001/STRONG_MODE.md#newcode4 STRONG_MODE.md:4: Strong mode may be used for: "may be used for" -> "helps with" https://codereview.chromium.org/1541833002/diff/240001/STRONG_MODE.md#newcode12 STRONG_MODE.md:12: Strong mode aims to ensure that static type annotations are actually correct at runtime. For this to work, strong mode requires a stricter type system than standard Dart. To understand this, consider the following example: "requires" -> "provides". Also, probably remove "To understand this,". https://codereview.chromium.org/1541833002/diff/240001/STRONG_MODE.md#newcode16 STRONG_MODE.md:16: I would just do: // util.dart I think it makes it a little clearer what the actual filename is, which is what's relevant to the import below. https://codereview.chromium.org/1541833002/diff/240001/STRONG_MODE.md#newcode46 STRONG_MODE.md:46: The lack of static or runtime errors is not an oversight; it is by design. It provides developers a mechanism to circumvent or ignore types when convenient, but it comes at cost. While the above example is contrived, it demonstrates that developers cannot easily reason about a program modularly: the static type annotations in the `util` library are of limited use, even in checked mode. "errors is" -> errors in the Dart specification's type rules". https://codereview.chromium.org/1541833002/diff/240001/STRONG_MODE.md#newcode48 STRONG_MODE.md:48: For the same reason, a compiler cannot easily exploit type annotations if they are unsound. A Dart compiler cannot simply assume that a `List<int>` contains `int` values or even that its `length` is an integer. Instead, it must either rely on expensive (and often brittle) whole program analysis or on additional runtime checking. Maybe add: "That additional checking leads to larger, slower code and harder-to-read output when Dart is transpiled to a high level language like JavaScript. https://codereview.chromium.org/1541833002/diff/240001/STRONG_MODE.md#newcode52 STRONG_MODE.md:52: Strong mode aims to enforce the correctness of static type annotations. It disallows examples such as the above. In this example, standard Dart rules (checked or otherwise) allow `MyList` to masquerade as a `List<int>`. Strong mode statically rejects the declaration of `MyList`. How about present tense? "Strong mode solves that by enforcing the correctness..." https://codereview.chromium.org/1541833002/diff/240001/STRONG_MODE.md#newcode54 STRONG_MODE.md:54: DDC augments strong mode static checking with a minimal set of runtime checks to enforce soundness. This allows both the developer and the compiler to better reason about the info method. For statically checked code, both may assume that the argument is a proper `List<int>`, with integer-valued length and elements. Maybe add: "soundness, similar to how Java and C# handle array casts." https://codereview.chromium.org/1541833002/diff/240001/STRONG_MODE.md#newcode56 STRONG_MODE.md:56: DDC execution is strictly stronger than checked mode. A Dart program execution where (a) the program passes DDC’s static checking and (b) the execution does not trigger DDC’s runtime assertions, will also run in checked mode on any Dart platform. "strictly stronger" is vague. Maybe just "stricter"? https://codereview.chromium.org/1541833002/diff/240001/doc/RUNTIME_SAFETY.md File doc/RUNTIME_SAFETY.md (right): https://codereview.chromium.org/1541833002/diff/240001/doc/RUNTIME_SAFETY.md#... doc/RUNTIME_SAFETY.md:29: Strong mode will enforce that the function `foo` is only invoked in a manner consistent with its signature. DDC - which assumes strong mode static checking - inserts no further runtime checks. In contrast, standard Dart checked mode would check the type of the parameters - `map` and `x` - along with the type of the return value at runtime on every invocation of `foo`. Even Dart production mode, depending on the implementation and its ability to optimize, may require similar checking to dynamically dispatch the map lookup and the method call in the body of `foo`. " - " -> "—". https://codereview.chromium.org/1541833002/diff/240001/doc/RUNTIME_SAFETY.md#... doc/RUNTIME_SAFETY.md:49: Dart's inference may narrow the static type of certain variables. If the variable is mutable, DDC will enforce the narrower type at runtime when necessary. "will enforce" -> "enforces". https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md File doc/STATIC_SAFETY.md (right): https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:5: The Dart programming language has an optional, unsound type system. Although it is similar in appearance to languages such as Java, C#, or C++, its type system and static checking are fundamentally different. It permits erroneous behavior in ways that may be surprising to programmers coming from those and other traditionally typed languages. "traditionally" -> "conventional" https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:24: - Type inference. Dart’s standard type rules treat omitted types as `dynamic` and effectively suppresses any static errors or warnings on variables of this type. Strong mode infers static types based upon context. In the example above, strong mode infers that `list` has type `List`. Note, in strong mode, programmers may still explicitly use the `dynamic` type. Maybe: "Dart’s standard type rules treats untyped variables as `dynamic`, which suppresses any static warnings on them." This isn't strictly comprehensive because there are places you can omit a type that aren't variables, but I think it's easier for a casual reader to understand. Also, how about making **Type inference**, **Strict subtyping** and **Generic methods** bold? https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:26: - Strict subtyping. Dart’s primary sources of unsoundness are due to its subtyping rules on function types and generic classes. Strong mode restricts these: e.g., `List` may not used as `List<int>` in the example above. Note, strong does still preserve Dart's covariance of generic classes. > Dart’s primary sources of unsoundness are due to its subty ping rules on function types and generic classes. What about implicit downcasting? That seems like the biggest hole to me. I would maybe remove the line about covariance. No one who understands that line will like it, and the people that benefit from it won't understand it. https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:28: - Generic methods. Standard Dart does not yet provide generic methods. This makes certain polymorphic methods difficult to use soundly. For example, the `List.map` invocation above is statically typed to return an `Iterable<dynamic>` in standard Dart. Strong mode allows methods to be annotated as generic. `List.map` is statically typed to return an `Iterable<T>` where `T` is bound to `int` at this use site. A number of common higher-order methods are annotated and checked as generic in strong mode, and programmers may annotate their own methods as well. "at this use site" -> "in the previous example". "common higher-order methods" -> "methods in the core libraries". https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:51: An explicit goal of strong mode to provide stronger typing while preserving the terseness of Dart. Dart syntax and [common style](https://www.dartlang.org/effective-dart/style/) encourages a modest level of type annotations. Strong mode should not compel programmers to add more. Instead, it relies on type inference. How about replacing this with: "With strong mode, we want to provide stronger typing while preserving the terseness of Dart. [Idiomatic Dart code](https://www.dartlang.org/effective-dart/) discourages type annotations outside of API boundaries, and user shouldn't have to add more types to get better checking. Instead, strong mode uses type inference." https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:66: - Allocation expressions Maybe "Constructor calls and collection literals"? https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:69: Inference may tighten the static type as compared to the Dart specification. The `dynamic` type, either alone or in the context of a function or generic parameter type, is inferred to a more specific type. This inference may result in stricter type errors than standard Dart. I wouldn't code format "dynamic" since a reader may think that means an *explicit* dynamic annotation is also inferred. Or maybe say "an implicitly dynamic...". https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:75: Strong mode will infer the static type of any top-level or static field with: "will infer" -> "infers" Present tense is your friend. Or, at least, it will be. Also "with" -> "with both". Actually, just say: "Strong mode infers any untyped top-level field or static field from the type of its initializer." https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:87: Strong mode would infer the static type of `PI` as `double` directly from its initializer. It would infer the static type of `TAU` as `double`, transitively using `PI`’s inferred type. Standard Dart rules would treat the static type of both `PI` and `TAU` as `dynamic`. Note that the following later assignment would be allowed in standard Dart, but disallowed (as a static type error) in strong mode: "would infer" -> "infers". https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:89: PI = "\u{03C0}"; // Unicode string for PI symbol This might be a weird example since users expect PI and TAU to be constants. How about: var PI = 3.114159; var radius = 20; var circumference = PI * radius; https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:91: Strong mode inference avoids circular dependences. If a variable’s initializer expression refers to another variable whose type would be dependent (directly or transitively) on the first, the static type of that other variable is treated as `dynamic` for the purpose of inference. In this modified example, "transitively" -> "indirectly". https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:99: the variables `PI` and `TAU` are circularly dependent on each other. Strong mode would leave the static type of both as `dynamic`. Also kind of a strange example. Maybe just leave this section out? Does it come into play enough to matter? https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:103: Strong mode performs two types of inference on instances fields and methods. "instances" -> "instance". https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:122: Strong mode - without inference - would disallow this: if `m` in `B` could be assigned an arbitrarily typed value, it would violate the type contract in the declaration of `A`. " - " -> "—". "an arbitrarily typed value" -> "any kind of object, including one that isn't a Map". https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:162: z = “$z”; Unsmarten the quotes. https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:164: would trigger a static error in strong mode, but is allowed in standard Dart. In strong mode, the programmer must use an explicit type annotation to suppress inference. Explicitly declaring `z` with the type `Object` or `dynamic` would suffice in this case. Maybe "would" -> "This would". https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:167: I think it would be good to define "allocation expressions" first instead of later in the paragraph. https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:170: In DDC, these inferred types are also [reified at runtime](RUNTIME_SAFETY.md) on the newly allocated objects to provide stronger runtime type safety. I think most users think of "type safety" as a compile time thing, so "runtime type safety" sounds kind of like an oxymoron. How about "stronger runtime validation"? https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:199: List<String> l = [ "hello", "world" ]; "l" -> "list" or maybe "words". https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:232: Finally, strong mode performs similar contextual inference on explicit constructor invocations via new or const. For example: Code format "new" and "const"? https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:312: Strong mode introduces generic methods to allow stricter typing on polymorphic methods. Such code in standard Dart today often loses static type information. For example, the `Iterable.map` method is declared as below: "stricter" -> "more expressive" https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:329: The [generic methods proposal](https://github.com/leafpetersen/dep-generic-methods/blob/master/proposal.md) proposes to add proper generic methods to the Dart language as a first class language construct and to make methods such as the `Iterable.map` generic. "proposal proposes to add" -> "proposal adds".
Looks like Bob has a lot of detailed comments. I just read through for overall content, which LGTM. @Vijay -- do you think eventually we'll want docs on dartlang.org? https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md File doc/STATIC_SAFETY.md (right): https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:282: The other primary source of unsoundness in Dart is function subtyping. An unusual feature of the Dart type system is that function types are bivariant in both the parameter types and the return type (see Section 19.5 of the [Dart specification](http://www.google.com/url?q=http%3A%2F%2Fwww.ecma-international.org%2Fpublications%2Ffiles%2FECMA-ST%2FECMA-408.pdf&sa=D&sntz=1&usg=AFQjCNGoFPzBNx2fgejKQgSgiS2dUBstBw)). As with generics, this leads to circularity: suggestion, direct link: http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-408.pdf or maybe even better: https://www.dartlang.org/docs/spec/ https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:361: Strong mode effectively treats all standard Dart static warnings as static errors. Most of these warnings are required for soundness (e.g., if a concrete class is missing methods required by a declared interface). A full list of Dart static warnings may found in the [Dart specification](http://www.google.com/url?q=http%3A%2F%2Fwww.ecma-international.org%2Fpublications%2Ffiles%2FECMA-ST%2FECMA-408.pdf&sa=D&sntz=1&usg=AFQjCNGoFPzBNx2fgejKQgSgiS2dUBstBw), or enumerated here: BTW: a feature of Markdown, is you can do reference links like: [Dart specification][dartspec] Then at the bottom: [dartspec]: https://www.dartlang.org/docs/spec/ "Dart Language Spec" That way you don't have to repeat it. More info @ https://daringfireball.net/projects/markdown/syntax#link
Thanks! PTAL https://codereview.chromium.org/1541833002/diff/240001/STRONG_MODE.md File STRONG_MODE.md (right): https://codereview.chromium.org/1541833002/diff/240001/STRONG_MODE.md#newcode3 STRONG_MODE.md:3: Strong mode imposes a more restrictive type system on Dart to address its unsoundness. On 2016/02/02 23:02:16, Bob Nystrom wrote: > "imposes ... on" -> "applies ... to" > "restrictive" -> "powerful" Done - and expanded a bit. https://codereview.chromium.org/1541833002/diff/240001/STRONG_MODE.md#newcode4 STRONG_MODE.md:4: Strong mode may be used for: On 2016/02/02 23:02:16, Bob Nystrom wrote: > "may be used for" -> "helps with" Done. https://codereview.chromium.org/1541833002/diff/240001/STRONG_MODE.md#newcode12 STRONG_MODE.md:12: Strong mode aims to ensure that static type annotations are actually correct at runtime. For this to work, strong mode requires a stricter type system than standard Dart. To understand this, consider the following example: On 2016/02/02 23:02:16, Bob Nystrom wrote: > "requires" -> "provides". > > Also, probably remove "To understand this,". Done. https://codereview.chromium.org/1541833002/diff/240001/STRONG_MODE.md#newcode16 STRONG_MODE.md:16: On 2016/02/02 23:02:16, Bob Nystrom wrote: > I would just do: > > // util.dart > > I think it makes it a little clearer what the actual filename is, which is > what's relevant to the import below. Done. https://codereview.chromium.org/1541833002/diff/240001/STRONG_MODE.md#newcode46 STRONG_MODE.md:46: The lack of static or runtime errors is not an oversight; it is by design. It provides developers a mechanism to circumvent or ignore types when convenient, but it comes at cost. While the above example is contrived, it demonstrates that developers cannot easily reason about a program modularly: the static type annotations in the `util` library are of limited use, even in checked mode. On 2016/02/02 23:02:16, Bob Nystrom wrote: > "errors is" -> errors in the Dart specification's type rules". Done. https://codereview.chromium.org/1541833002/diff/240001/STRONG_MODE.md#newcode48 STRONG_MODE.md:48: For the same reason, a compiler cannot easily exploit type annotations if they are unsound. A Dart compiler cannot simply assume that a `List<int>` contains `int` values or even that its `length` is an integer. Instead, it must either rely on expensive (and often brittle) whole program analysis or on additional runtime checking. On 2016/02/02 23:02:16, Bob Nystrom wrote: > Maybe add: > > "That additional checking leads to larger, slower code and harder-to-read output > when Dart is transpiled to a high level language like JavaScript. Done. https://codereview.chromium.org/1541833002/diff/240001/STRONG_MODE.md#newcode52 STRONG_MODE.md:52: Strong mode aims to enforce the correctness of static type annotations. It disallows examples such as the above. In this example, standard Dart rules (checked or otherwise) allow `MyList` to masquerade as a `List<int>`. Strong mode statically rejects the declaration of `MyList`. On 2016/02/02 23:02:16, Bob Nystrom wrote: > How about present tense? > > "Strong mode solves that by enforcing the correctness..." Done. https://codereview.chromium.org/1541833002/diff/240001/STRONG_MODE.md#newcode54 STRONG_MODE.md:54: DDC augments strong mode static checking with a minimal set of runtime checks to enforce soundness. This allows both the developer and the compiler to better reason about the info method. For statically checked code, both may assume that the argument is a proper `List<int>`, with integer-valued length and elements. On 2016/02/02 23:02:16, Bob Nystrom wrote: > Maybe add: > > "soundness, similar to how Java and C# handle array casts." done, with "array" -> "potentially unsafe" https://codereview.chromium.org/1541833002/diff/240001/STRONG_MODE.md#newcode56 STRONG_MODE.md:56: DDC execution is strictly stronger than checked mode. A Dart program execution where (a) the program passes DDC’s static checking and (b) the execution does not trigger DDC’s runtime assertions, will also run in checked mode on any Dart platform. On 2016/02/02 23:02:16, Bob Nystrom wrote: > "strictly stronger" is vague. Maybe just "stricter"? Done. https://codereview.chromium.org/1541833002/diff/240001/doc/RUNTIME_SAFETY.md File doc/RUNTIME_SAFETY.md (right): https://codereview.chromium.org/1541833002/diff/240001/doc/RUNTIME_SAFETY.md#... doc/RUNTIME_SAFETY.md:29: Strong mode will enforce that the function `foo` is only invoked in a manner consistent with its signature. DDC - which assumes strong mode static checking - inserts no further runtime checks. In contrast, standard Dart checked mode would check the type of the parameters - `map` and `x` - along with the type of the return value at runtime on every invocation of `foo`. Even Dart production mode, depending on the implementation and its ability to optimize, may require similar checking to dynamically dispatch the map lookup and the method call in the body of `foo`. On 2016/02/02 23:02:16, Bob Nystrom wrote: > " - " -> "—". Done. https://codereview.chromium.org/1541833002/diff/240001/doc/RUNTIME_SAFETY.md#... doc/RUNTIME_SAFETY.md:49: Dart's inference may narrow the static type of certain variables. If the variable is mutable, DDC will enforce the narrower type at runtime when necessary. On 2016/02/02 23:02:16, Bob Nystrom wrote: > "will enforce" -> "enforces". Done. https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md File doc/STATIC_SAFETY.md (right): https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:5: The Dart programming language has an optional, unsound type system. Although it is similar in appearance to languages such as Java, C#, or C++, its type system and static checking are fundamentally different. It permits erroneous behavior in ways that may be surprising to programmers coming from those and other traditionally typed languages. On 2016/02/02 23:02:17, Bob Nystrom wrote: > "traditionally" -> "conventional" Done. https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:24: - Type inference. Dart’s standard type rules treat omitted types as `dynamic` and effectively suppresses any static errors or warnings on variables of this type. Strong mode infers static types based upon context. In the example above, strong mode infers that `list` has type `List`. Note, in strong mode, programmers may still explicitly use the `dynamic` type. On 2016/02/02 23:02:17, Bob Nystrom wrote: > Maybe: > > "Dart’s standard type rules treats untyped variables as `dynamic`, which > suppresses any static warnings on them." > > This isn't strictly comprehensive because there are places you can omit a type > that aren't variables, but I think it's easier for a casual reader to > understand. > > Also, how about making **Type inference**, **Strict subtyping** and **Generic > methods** bold? Done. https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:26: - Strict subtyping. Dart’s primary sources of unsoundness are due to its subtyping rules on function types and generic classes. Strong mode restricts these: e.g., `List` may not used as `List<int>` in the example above. Note, strong does still preserve Dart's covariance of generic classes. On 2016/02/02 23:02:17, Bob Nystrom wrote: > > Dart’s primary sources of unsoundness are due to its subty > ping rules on function types and generic classes. > > What about implicit downcasting? That seems like the biggest hole to me. We plug it with runtime checks, so it's effectively a pluggable hole. :-) > I would maybe remove the line about covariance. No one who understands that line > will like it, and the people that benefit from it won't understand it. Done https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:28: - Generic methods. Standard Dart does not yet provide generic methods. This makes certain polymorphic methods difficult to use soundly. For example, the `List.map` invocation above is statically typed to return an `Iterable<dynamic>` in standard Dart. Strong mode allows methods to be annotated as generic. `List.map` is statically typed to return an `Iterable<T>` where `T` is bound to `int` at this use site. A number of common higher-order methods are annotated and checked as generic in strong mode, and programmers may annotate their own methods as well. On 2016/02/02 23:02:17, Bob Nystrom wrote: > "at this use site" -> "in the previous example". > > "common higher-order methods" -> "methods in the core libraries". Done. https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:51: An explicit goal of strong mode to provide stronger typing while preserving the terseness of Dart. Dart syntax and [common style](https://www.dartlang.org/effective-dart/style/) encourages a modest level of type annotations. Strong mode should not compel programmers to add more. Instead, it relies on type inference. On 2016/02/02 23:02:17, Bob Nystrom wrote: > How about replacing this with: > > "With strong mode, we want to provide stronger typing while preserving the > terseness of Dart. [Idiomatic Dart > code](https://www.dartlang.org/effective-dart/) discourages type annotations > outside of API boundaries, and user shouldn't have to add more types to get > better checking. Instead, strong mode uses type inference." Done. https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:66: - Allocation expressions On 2016/02/02 23:02:17, Bob Nystrom wrote: > Maybe "Constructor calls and collection literals"? Done, but dropped "collection" - closure literals as well. https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:69: Inference may tighten the static type as compared to the Dart specification. The `dynamic` type, either alone or in the context of a function or generic parameter type, is inferred to a more specific type. This inference may result in stricter type errors than standard Dart. On 2016/02/02 23:02:17, Bob Nystrom wrote: > I wouldn't code format "dynamic" since a reader may think that means an > *explicit* dynamic annotation is also inferred. Or maybe say "an implicitly > dynamic...". Done. https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:75: Strong mode will infer the static type of any top-level or static field with: On 2016/02/02 23:02:17, Bob Nystrom wrote: > "will infer" -> "infers" > > Present tense is your friend. Or, at least, it will be. > > Also "with" -> "with both". Actually, just say: > > "Strong mode infers any untyped top-level field or static field from the type of > its initializer." Done. https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:87: Strong mode would infer the static type of `PI` as `double` directly from its initializer. It would infer the static type of `TAU` as `double`, transitively using `PI`’s inferred type. Standard Dart rules would treat the static type of both `PI` and `TAU` as `dynamic`. Note that the following later assignment would be allowed in standard Dart, but disallowed (as a static type error) in strong mode: On 2016/02/02 23:02:17, Bob Nystrom wrote: > "would infer" -> "infers". Done. https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:89: PI = "\u{03C0}"; // Unicode string for PI symbol On 2016/02/02 23:02:17, Bob Nystrom wrote: > This might be a weird example since users expect PI and TAU to be constants. How > about: > > var PI = 3.114159; > var radius = 20; > var circumference = PI * radius; Done https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:91: Strong mode inference avoids circular dependences. If a variable’s initializer expression refers to another variable whose type would be dependent (directly or transitively) on the first, the static type of that other variable is treated as `dynamic` for the purpose of inference. In this modified example, On 2016/02/02 23:02:17, Bob Nystrom wrote: > "transitively" -> "indirectly". Done. https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:99: the variables `PI` and `TAU` are circularly dependent on each other. Strong mode would leave the static type of both as `dynamic`. On 2016/02/02 23:02:17, Bob Nystrom wrote: > Also kind of a strange example. Maybe just leave this section out? Does it come > into play enough to matter? Took the examples out. https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:103: Strong mode performs two types of inference on instances fields and methods. On 2016/02/02 23:02:17, Bob Nystrom wrote: > "instances" -> "instance". Done. https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:122: Strong mode - without inference - would disallow this: if `m` in `B` could be assigned an arbitrarily typed value, it would violate the type contract in the declaration of `A`. On 2016/02/02 23:02:17, Bob Nystrom wrote: > " - " -> "—". > > "an arbitrarily typed value" -> "any kind of object, including one that isn't a > Map". Done. https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:162: z = “$z”; On 2016/02/02 23:02:17, Bob Nystrom wrote: > Unsmarten the quotes. Done. https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:164: would trigger a static error in strong mode, but is allowed in standard Dart. In strong mode, the programmer must use an explicit type annotation to suppress inference. Explicitly declaring `z` with the type `Object` or `dynamic` would suffice in this case. On 2016/02/02 23:02:17, Bob Nystrom wrote: > Maybe "would" -> "This would". This is continuing the sentence before the code snippet. https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:167: On 2016/02/02 23:02:17, Bob Nystrom wrote: > I think it would be good to define "allocation expressions" first instead of > later in the paragraph. Changed to match the list above. https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:170: In DDC, these inferred types are also [reified at runtime](RUNTIME_SAFETY.md) on the newly allocated objects to provide stronger runtime type safety. On 2016/02/02 23:02:17, Bob Nystrom wrote: > I think most users think of "type safety" as a compile time thing, so "runtime > type safety" sounds kind of like an oxymoron. How about "stronger runtime > validation"? How about "stronger soundness guarantee"? https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:199: List<String> l = [ "hello", "world" ]; On 2016/02/02 23:02:17, Bob Nystrom wrote: > "l" -> "list" or maybe "words". Done. https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:232: Finally, strong mode performs similar contextual inference on explicit constructor invocations via new or const. For example: On 2016/02/02 23:02:17, Bob Nystrom wrote: > Code format "new" and "const"? Done. https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:282: The other primary source of unsoundness in Dart is function subtyping. An unusual feature of the Dart type system is that function types are bivariant in both the parameter types and the return type (see Section 19.5 of the [Dart specification](http://www.google.com/url?q=http%3A%2F%2Fwww.ecma-international.org%2Fpublications%2Ffiles%2FECMA-ST%2FECMA-408.pdf&sa=D&sntz=1&usg=AFQjCNGoFPzBNx2fgejKQgSgiS2dUBstBw)). As with generics, this leads to circularity: On 2016/02/02 23:07:45, John Messerly wrote: > suggestion, direct link: > http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-408.pdf > > or maybe even better: https://www.dartlang.org/docs/spec/ Done. https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:312: Strong mode introduces generic methods to allow stricter typing on polymorphic methods. Such code in standard Dart today often loses static type information. For example, the `Iterable.map` method is declared as below: On 2016/02/02 23:02:17, Bob Nystrom wrote: > "stricter" -> "more expressive" Done. https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:329: The [generic methods proposal](https://github.com/leafpetersen/dep-generic-methods/blob/master/proposal.md) proposes to add proper generic methods to the Dart language as a first class language construct and to make methods such as the `Iterable.map` generic. On 2016/02/02 23:02:17, Bob Nystrom wrote: > "proposal proposes to add" -> "proposal adds". Done. https://codereview.chromium.org/1541833002/diff/240001/doc/STATIC_SAFETY.md#n... doc/STATIC_SAFETY.md:361: Strong mode effectively treats all standard Dart static warnings as static errors. Most of these warnings are required for soundness (e.g., if a concrete class is missing methods required by a declared interface). A full list of Dart static warnings may found in the [Dart specification](http://www.google.com/url?q=http%3A%2F%2Fwww.ecma-international.org%2Fpublications%2Ffiles%2FECMA-ST%2FECMA-408.pdf&sa=D&sntz=1&usg=AFQjCNGoFPzBNx2fgejKQgSgiS2dUBstBw), or enumerated here: On 2016/02/02 23:07:45, John Messerly wrote: > BTW: a feature of Markdown, is you can do reference links like: > [Dart specification][dartspec] > > Then at the bottom: > [dartspec]: https://www.dartlang.org/docs/spec/ "Dart Language Spec" > > That way you don't have to repeat it. > > More info @ https://daringfireball.net/projects/markdown/syntax#link Done.
LGTM!
Description was changed from ========== Refactored this and uploaded here: https://github.com/dart-lang/dev_compiler/blob/strong/STRONG_MODE.md PTAL ========== to ========== Refactored this and uploaded here: https://github.com/dart-lang/dev_compiler/blob/strong/STRONG_MODE.md PTAL R=jmesserly@google.com, rnystrom@google.com Committed: https://github.com/dart-lang/dev_compiler/commit/bc15ab3a70d4e2007b222c4eeb79... ==========
Message was sent while issue was closed.
Committed patchset #15 (id:280001) manually as bc15ab3a70d4e2007b222c4eeb799ad0b8f31ed9 (presubmit successful). |