summaryrefslogtreecommitdiff
path: root/def.lisp
diff options
context:
space:
mode:
authorcolin <colin@cicadas.surf>2024-06-18 08:21:59 -0700
committercolin <colin@cicadas.surf>2024-06-18 08:21:59 -0700
commit06f8c9c96a1d13451276ded4e091175eafd5b4e9 (patch)
treed3d04f85552c7379be8b0c46341dbab37456ac13 /def.lisp
parent22686584f103d163a1e5f370aa06905ec5c3b4a4 (diff)
Add: def:fast for optimized function defs
Diffstat (limited to 'def.lisp')
-rw-r--r--def.lisp39
1 files changed, 39 insertions, 0 deletions
diff --git a/def.lisp b/def.lisp
index 9944505..0142801 100644
--- a/def.lisp
+++ b/def.lisp
@@ -98,4 +98,43 @@ E.g.
,@options))))
+(defmacro fast (name (&rest lambda-list) -> return-type &body body)
+ "A fastfun is one for which every parameter is typed, a return type is
+declared. DEF:FAST generates an optimized DEFUN.
+Each positional parameter must be a list (VAR TYPE) &KEY &REST and
+&OPTIONAL arguments all look like (VAR TYPE . MORE) where MORE is
+whatever defun normally accepts in the lambda list for these
+arguments.
+
+E.g.
+
+(def::fast sum-ints ((x integer) (y integer) &optional (z integer 0)) -> integer
+ \"Sums integers\"
+ (+ x y z))
+"
+ (assert (string-equal -> "->") () "-> must be named -> ** chortle **.")
+ (multiple-value-bind (lambda-list type-declarations)
+ (loop
+ :with types := nil
+ :with ll := nil
+ :for x :in lambda-list
+ :do (cond ((lambda-opt-p x)
+ (push x ll))
+ ((listp x)
+ (destructuring-bind (var type . other) x
+ (let ((found (find type types
+ :test #'equalp
+ :key #'second)))
+ (if found
+ (push var (cddr found))
+ (push (list 'cl:type type var) types)))
+ (push
+ (if other (cons var other) var)
+ ll))))
+ :finally (return (values (nreverse ll) types)))
+ `(defun ,name ,lambda-list
+ (declare ,@type-declarations
+ (values ,return-type)
+ (optimize (speed 3) (safety 0)))
+ ,@body)))