Some Lisp implementations (like SBCL) also do that blending, although they can statically catch some integer range violations too. For example if you declare a variable to be an (integer 50 100) and try to assign a literal 30 to it, you'll get a compile-time warning in SBCL:
; Constant 30 conflicts with its asserted type (INTEGER 50 100).
But in many other cases it'll generate a runtime check instead, because the static type checking is basically best-effort.
Re:Dependent Types for F#
by DonaldFisk on Tuesday December 05, 2017 @03:35PM
(#15855570)
They allow you to statically declare integer ranges (as well as other things), even if their bounds are unknown until run-time, and without requiring a run-time type check.
It's interesting to me how Ada takes the approach of blending types and run time contracts. In most languages it would be two different things - a function that takes int, then a contract or assert that handles the value.