Contracts are actually quite necessary for modularity. In OOP we have data types (interfaces, classes).
As long as other paradigms provide contracts/abstractions, modularity can be achieved there also.
Faked modularity doesn't count. Leaky abstractions neither.