From: Static Typing Where Possible, Dynamic Typing When Needed

当程序员说我需要动态/静态类型时的实际需求

类型推断

// X
Button b = new Button();
String s = "Doh!";
// O
var b = new Button();
var s = "Doh!";

var b = new Button { Size = new Size { Height = 20, Width = 40 } };
Button b = { Size = { Height = 20, Width = 40 } };

约束

int f(int i) [[expects: i > 0]] [[ensures audit x: x < 1]];

(强制) 子类化

class Dog {}
class Poodle extends Dog { Bark() {} }
Dog d = new Poodle();
d.Bark();

object b = new Button();
object c = b.BuckColor;

...;
SqlDataReader r =
new SqlCommand("SELECT Name, Age From ...", c).ExecuteReader();
while (r.Read()) {
    // Name,Age 自动带上接收它们的变量/函数需要的类型
    ...; r.Name; ...; r.Age; ...;
}
...;

泛型

interface IComparer<T> { int Compare(T a, T b) }
void Sort<T>([implicit]IComparer<T> comparer) {...}

(unsafe) 协变

object[] xs = new Button[]{ new Button() };
xs[0] = "Hello World";

自动建立对象关联和原型继承

// java 需要提前"知道" Person 有 Dog
class Person { ...; Dog myDog; }
// 但我们希望这样
class Person { ... }
class Dog { ... }
class MyDogs { Person& p; Dog& d; }
Person p;
Collection<Dog> ds = p.MyDogs;

惰性求值

用 lazy list, unix pipe, async msg system 搞,这不是类型系统要做的事情。

高阶函数、(反) 序列化、eval

区分动态/静态语言的关键不是谁有 eval 函数,任何语言都可以动态地导入代码(通过例如 DLL、so、dynamic class loading(java))。真正的问题是是否需要运行时生成代码,以及如何实现。eval 通常有三种用途:高阶函数(f(x)=`${x}+1`; eval(f(42)) -> 43)、字面量解析(eval("123") -> 123)、元编程(C++ 模板、Lisp 的 '() 表达式)。