restricted-functions
2019-05-21
Reasoning about functions with restricted argument types.
Upstream URL
Author
License
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!