marcoheisig / restricted-functions

Reasoning about functions with restricted argument types.
MIT License
10 stars 0 forks source link

+TITLE: Restricted Functions

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=

+BEGIN_SRC lisp

(restrict nil #'+ 'double-float '(complex short-float))

+END_SRC

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=:

+BEGIN_SRC lisp

(infer-type nil #'* '(integer 2 14) '(integer 0 12)) ; => (integer 0 168)

+END_SRC

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

+BEGIN_SRC lisp

(let ((rf (restrict nil #'+ 'double-float 'double-float))) (compile nil `(lambda (x y) (,(name rf) x y))))

+END_SRC

to get the equivalent of

+BEGIN_SRC lisp

(compile nil `(lambda (x y) (the double-float (+ (the double-float x) (the double-float y)))))

+END_SRC

If you have any suggestions for this library, feel free to contact me!