The problem is that the “live programming” aspect violates a fundamental assumption of a lot of static type systems: the “closed world” assumption that all the relevant types are known at compile-time. If you can dynamically extend/redefine the types on the fly, your type-system guarantees start getting weaker anyways. Instead, you need a system of contracts or something like Racket has.
Also, if you have macros, you can always just embed a Haskell into your language for the parts where you want that sort of guarantee: https://coalton-lang.github.io/