OLD | NEW |
(Empty) | |
| 1 # Strong Mode and Idiomatic JavaScript |
| 2 |
| 3 The Dart Dev Compiler (DDC) uses [Strong Mode](STRONG_MODE.md) to safely generat
e |
| 4 idiomatic JavaScript. This enables better interoperability between Dart and Jav
aScript code. |
| 5 |
| 6 The standard Dart type system is unsound by design. This means that static type
annotations may not match the actual runtime values even when a program is runn
ing in checked mode. This allows considerable flexibility, but it also means th
at Dart implementations cannot easily use these annotations for optimization or
code generation. |
| 7 |
| 8 Because of this, existing Dart implementations require dynamic dispatch. Furthe
rmore, because Dart’s dispatch semantics are different from JavaScript’s, it eff
ectively precludes mapping Dart calls to idiomatic JavaScript. For example, the
following Dart code: |
| 9 |
| 10 ```dart |
| 11 var x = a.bar; |
| 12 b.foo("hello", x); |
| 13 ``` |
| 14 |
| 15 cannot easily be mapped to the identical JavaScript code. If `a` does not conta
in a `bar` field, Dart requires a `NoSuchMethodError` while JavaScript simply re
turns undefined. If `b` contains a `foo` method, but with the wrong number of a
rguments, Dart again requires a `NoSuchMethodError` while JavaScript either igno
res extra arguments or fills in omitted ones with undefined. |
| 16 |
| 17 To capture these differences, the Dart2JS compiler instead generates code that a
pproximately looks like: |
| 18 |
| 19 ```dart |
| 20 var x = getInterceptor(a).get$bar(a); |
| 21 getInterceptor(b).foo$2(b, "hello", x); |
| 22 ``` |
| 23 The “interceptor” is Dart’s dispatch table for the objects `a` and `b`, and the
mangled names (`get$bar` and `foo$2`) account for Dart’s different dispatch sema
ntics. |
| 24 |
| 25 The above highlights why Dart-JavaScript interoperability hasn’t been seamless:
Dart objects and methods do not look like normal JavaScript ones. |
| 26 |
| 27 DDC relies on strong mode to map Dart calling conventions to normal JavaScript o
nes. If `a` and `b` have static type annotations (with a type other than `dynam
ic`), strong mode statically verifies that they have a field `bar` and a 2-argum
ent method `foo` respectively. In this case, DDC safely generates the identical
JavaScript: |
| 28 |
| 29 ```javascript |
| 30 var x = a.bar; |
| 31 b.foo("hello", x); |
| 32 ``` |
| 33 |
| 34 Note that DDC still supports the `dynamic` type, but relies on runtime helper fu
nctions in this case. E.g., if `a` and `b` are type `dynamic`, DDC instead gene
rates: |
| 35 |
| 36 ```javascript |
| 37 var x = dload(a, "bar"); |
| 38 dsend(b, "foo", "hello", x); |
| 39 ``` |
| 40 |
| 41 where `dload` and `dsend` are runtime helpers that implement Dart dispatch seman
tics. Programmers are encouraged to use static annotations to avoid this. Stron
g mode is able to use static checking to enforce much of what checked mode does
at runtime. In the code above, strong mode statically verifies that `b`’s type
(if not `dynamic`) has a `foo` method that accepts a `String` as its first argum
ent and `a.bar`’s type as its second. If the code is sufficiently typed, runtim
e checks are unnecessary. |
OLD | NEW |