> But I can't do that if I want to do gradual typing. If I type a function, but the type system cannot figure out what's going to call it, that's when I want it to perform a check: at the boundary.
Unless you start using # type: ignore - the only way to interface with untyped code will be to use asserts or other checks (if + throw), i.e. perform checks at the boundary.