diff options
author | colin <colin@cicadas.surf> | 2024-06-18 08:47:42 -0700 |
---|---|---|
committer | colin <colin@cicadas.surf> | 2024-06-18 08:47:42 -0700 |
commit | 2111f61524e5fbdf843950de60740f3a15b5274f (patch) | |
tree | 448a1feea5e3e237ba4e39ff63b30ab5a0e6c3e7 | |
parent | 06f8c9c96a1d13451276ded4e091175eafd5b4e9 (diff) |
Fix: docstring in def:fast; update readme
-rw-r--r-- | README.md | 36 | ||||
-rw-r--r-- | def.lisp | 12 |
2 files changed, 43 insertions, 5 deletions
@@ -64,3 +64,39 @@ The above would expand out into (:DOCUMENTATION "A point in real 3d space")) See `def:class`'s docstring for details. + +## `def:fast` + +Common Lisp compilers like SBCL can produce extremely fast code +... if, that is, you help them out a little. + +Declaring types and `optimize` declare expressions can be a little +verbose and irritating to add to every function that you want to be +fast. + +`def:fast` lightens some of the typing load by embedding types inside +the lambda list, and by declaring the return type of functions. E.g.: + + + (defun list-of-fixnum-p (xs) + (and (listp xs) (every #'sb-int:fixnump xs))) + + (deftype list-of-fixnum () + '(satisfies list-of-fixnum-p)) + + (def:fast sum-fixnum ((x fixnum) (y fixnum) &rest (xs list-of-fixnum)) -> fixnum + "Sums fixnums" + (+ x y (reduce #'+ xs))) + + +The above expands into + + (DEFUN SUM-FIXNUM (X Y &REST XS) + "Sums fixnums" + (DECLARE (TYPE LIST-OF-FIXNUM XS) + (TYPE FIXNUM Y X) + (VALUES FIXNUM) + (OPTIMIZE (SPEED 3) (SAFETY 0))) + (+ x y (REDUCE #'+ XS))) + + @@ -133,8 +133,10 @@ E.g. (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))) + (let ((docstring (when (stringp (first body)) (first body)))) + `(defun ,name ,lambda-list + ,@(when docstring (list docstring)) + (declare ,@type-declarations + (values ,return-type) + (optimize (speed 3) (safety 0))) + ,@(if docstring (rest body) body))))) |