Add two of On Lisp's utility functions: group and once-only
This commit is contained in:
parent
aec779ac7b
commit
4e544af6fc
1 changed files with 20 additions and 0 deletions
|
|
@ -10,6 +10,7 @@
|
||||||
(:export :it
|
(:export :it
|
||||||
:aif
|
:aif
|
||||||
:awhen
|
:awhen
|
||||||
|
:group :once-only
|
||||||
:restartable
|
:restartable
|
||||||
:add-hook :remove-hook :run-hook
|
:add-hook :remove-hook :run-hook
|
||||||
:update-current-time :get-delta-time
|
:update-current-time :get-delta-time
|
||||||
|
|
@ -32,6 +33,25 @@
|
||||||
(when it
|
(when it
|
||||||
,@body)))
|
,@body)))
|
||||||
|
|
||||||
|
(defun group (source n)
|
||||||
|
"Regroup the list `source' elements by n."
|
||||||
|
(when (zerop n)
|
||||||
|
(error "zero length"))
|
||||||
|
(labels ((rec (source acc)
|
||||||
|
(let ((rest (nthcdr n source)))
|
||||||
|
(if (consp rest)
|
||||||
|
(rec rest (cons (subseq source 0 n) acc))
|
||||||
|
(nreverse (cons source acc))))))
|
||||||
|
(if source (rec source nil) nil)))
|
||||||
|
|
||||||
|
(defmacro once-only ((&rest names) &body body)
|
||||||
|
"Evaluate the symbols in `names' only once, for use in a macro, as per Peter Siebel's Practical Common-Lisp."
|
||||||
|
(let ((gensyms (loop for n in names collect (gensym))))
|
||||||
|
`(let (,@(loop for g in gensyms collect `(,g (gensym))))
|
||||||
|
`(let (,,@(loop for g in gensyms for n in names collect ``(,,g ,,n)))
|
||||||
|
,(let (,@(loop for n in names for g in gensyms collect `(,n ,g)))
|
||||||
|
,@body)))))
|
||||||
|
|
||||||
(defmacro restartable (unprotected &body body)
|
(defmacro restartable (unprotected &body body)
|
||||||
"Provide a Continue restart unless `unprotected' is t."
|
"Provide a Continue restart unless `unprotected' is t."
|
||||||
`(if ,unprotected
|
`(if ,unprotected
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue