Many functions in Common Lisp are defined for a wide range of argument types. Yet their behavior (in terms of performance, memory consumption and return value types) varies a lot depending on how many arguments of which type are supplied. This library provides /restricted functions/, i.e., functions that have been narrowed to a particular set of argument types. Restricted functions can be created with the function =restrict=
(restrict nil #'+ 'double-float '(complex short-float))
Each restricted function is an instance of =funcallable-standard-class=, and can be queried for a wide range of metadata, such as the number and type of the values it returns, its name, or its arity. The most important feature is the automatic derivation of argument types. This library can infer the type of a wide range of functions from the Common Lisp standard. Type inference can be performed with the function =infer-type=:
(infer-type nil #'* '(integer 2 14) '(integer 0 12)) ; => (integer 0 168)
A future goal is to make it possible to query the cost of a restricted function in terms of CPU cycles, loads, stores and heap allocation on a given platform and Lisp implementation.
A particularly useful feature is that each restricted function has an automatically generated name and an optimizing compiler macro for that name. This is convenient for writing code generators, where one can just write
(let ((rf (restrict nil #'+ 'double-float 'double-float))) (compile nil `(lambda (x y) (,(name rf) x y))))
to get the equivalent of
(compile nil `(lambda (x y) (the double-float (+ (the double-float x) (the double-float y)))))
If you have any suggestions for this library, feel free to contact me!