| There are quite a few dynamically typed languages which let you restrict the numeric types that polymorphic operators can consume and produce. A long heritage of that is in Common Lisp (see the Type Specifiers section in CLtL) and several other Lisp-family languages allow this too (e.g. Racket, which has a pretty substantial contracts sytem). So it's not new. It doesn't make Lisp any less dynamically typed as a language, and it is wholly optional. Newer dynamic languages also let one do some partial or "gradual" typing where a programmer wants to use it. There is a cost to this at function calling time, but then there is also a cost if one manually programs in a check on the type of an argument, for instance. Good compilers, however, can prove that functions that aren't of (or exported to) global scope will never be called with anything other than the specified types, and will omit the type-checking code. Additionally, there is plenty of research into interoperation between code in statically typed languages and dynamically typed ones. Naturally you can always convert back after your arithmetic operator produces the wrong type. But that can be expensive in itself, and it hurts more when the arithmetic operator could have performed a much cheaper operation. A way around this of course is to eventually de-polymorphize the potentially-expensive operator and program in a hopefully cheap type-check by hand, in write-generically-first/optimize-(or even make correct)-after fashion. |