why optional typing in Dart? why optional typing in Dart? dart dart

why optional typing in Dart?


From Gilad Bracha [1]:

You can write a tool that will scream bloody murder about these things, but what you can’t do is stop people from running their programs.

Or, in other words [2]:

The problem is that expressing type flow fully and explicitly is more difficult for most programmers than writing code that passes values around and deals with runtime type errors when and if they happen. The word chosen for this difference in difficulty is that the latter is more "intuitive" than the former - I don't think it's a particularly bad choice of word. The phenomenon is one of the biggest reasons dynamic languages have become a lot more popular over recent years, a rejection of complexity in specifying static types.

It's like there's another triangle tradeoff: expressive, sound, simple: choose any two for your type system. Almost everyone is unwilling to forgo expressiveness - the object graphs weaved in modern software can be quite tangled indeed - while any language that hopes to have large-scale success cannot start out being anything but fairly simple. So they give up some measure of (statically-typed) soundness, and expect lots of runtime type errors during debugging and testing.

[1] http://blog.sethladd.com/2011/11/transcription-of-quick-tour-of-dart-by.html

[2] http://lambda-the-ultimate.org/node/4377#comment-67589


What was the Dart lang spec writers thinking when they say sound type rules for generics fly in the face of intuition?

Take a look at the related questions to the right of this one. I see:

  • Why is List<Number> not a sub-type of List<Object>?
  • Why generic interfaces are not co/contravariant by default?
  • Why can't I assign a List<Derived> to a List<Base>?
  • Why cant I cast from a list<MyClass> to List<object>?
  • Why Animals[] animals = new Cat[5] compiles, but List<Animal> animals = new List<Cat>() does not?

While covariance isn't sound (for many mutable types), it is the behavior that many programmers intuitively expect when they first start working with generic types.


More concretely, as far as unsoundness goes, generic types are covariant. So a List of Strings can be passed to something that expects a List of Object. This is not typesafe, because the thing that expects a list of Object could conceivably try to add something to the List which wasn't a String. But telling people that when you have B as a subclass of A, but Collection<B> is not a subtype of Collection<A> is quite non-intuitive.