Simple run-time type checking in muSE
The guarded patterns facility can be used to implement a simple type checking facility that can be turned on and off with a global setting. Some functions useful in this situation are defined in examples/rtts1.scm.
muSE has some built-in functions to check types - int?, float?, cons?, vector?, hashtable?, text? and symbol?. The common characteristic of these predicates is to evaluate to their argument if it satisfies the predicate and to () if it doesn't.
If you take a type to be defined by a predicate - the class of objects being all objects that satisfy the predicate - the above predicates together with the combinators ?or, ?and, ?not and ?list-of defined in examples/rtts1.scm can express a broad set of types.
Note: The type checks are all performed at function invocation time. This can be quite a drag on performance. So the definition of decltype in the rtts1.scm file is such that the checks can be turned off by setting the *enable-rtts* to () at the start of the file.
Here's an example (note the use of braces {} around the decltype expressions) -
(define number? (?or int? float?)) ; From rtts1.scm
(define max
(fn ({decltype n1 number?}
{decltype n2 number?})
(if (> n1 n2) n2 n1)))
(define multi-max
(fn ({decltype n1 number?} . {decltype ns (?list-of number?)})
(reduce max n1 ns)))
With type checking enabled, multi-max will only be usable with numeric arguments and you have to give it at least one argument.
If you disable type checking, then the above definitions become as though you'd typed -
(define max
(fn (n1 n2)
(if (> n1 n2) n2 n1)))
(define multi-max
(fn (n1 . ns)
(reduce max n1 ns)))
No comments:
Post a Comment