Well, almost. Dispatch can happen at compile time, and in fact does for type-stable code. But the dispatch is on run-time types, not static types.
(The fact that you can have static dispatch on dynamic types is a pretty subtle point that hurts my head, but the upshot is that you get semantically dynamic dispatch with static performance as an optimization.)
(The fact that you can have static dispatch on dynamic types is a pretty subtle point that hurts my head, but the upshot is that you get semantically dynamic dispatch with static performance as an optimization.)