Created
November 25, 2013 22:57
-
-
Save briangoetz/7650431 to your computer and use it in GitHub Desktop.
Flow typing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Proponents of "flow typing" have suggested, in code like this: | |
if (foo instanceof Bar) { | |
((Bar) foo).barMethod(); | |
} | |
"why not just" allow the developer to elide the cast to Bar? Implicit in this question is the assumption that this is a very simple feature. | |
Like everything else, the easy cases are easy. The key question to ask is, under such a scheme, if the static type of foo outside the if-block is Moo, what is the static type of foo inside the if block? | |
One obvious, but wrong, candidate is Bar; this means that foo could no longer be used as a Moo: | |
if (foo instanceof Bar) { | |
... | |
foo.mooMethod(); // compile error: mooMethod() not a member of Bar | |
} | |
The less-wrong answer is an intersection type: (Moo & Bar). Now, imagine this overloading of existing methods: | |
void m(Moo m) { ... } | |
void m(Bar b) { ... } | |
and we have existing code like this: | |
if (foo instanceof Bar) { | |
m(foo); | |
... | |
} | |
But if we reinterpret the static type of foo as Moo & Bar, this code no longer compiles, due to an ambiguity in overload resolution. So this language change, as envisioned, is not source-compatible. Oops. | |
Now, one could layer arbitrarily complicated new rules for overload resolution to try and "fix" this problem, but now we're well outside the territory of an "easy" feature. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Ah, OK. Thanks for clearing that up.
I do of course know the difference but I didn't think that would matter here. Luckily you did. :)
Cheers,
Mikael