forked from paul7/lrefal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutility.lisp
73 lines (61 loc) · 1.61 KB
/
utility.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
;;;; simple useful utilities
;;;; (c) paul7, 2010
;;;; (c) Paul Graham, 1993
(defpackage :net.paul7.utility
(:nicknames :util)
(:use :common-lisp)
(:export with-gensyms
single
mklist
compose
convert-sequence
post-incf
sequence-reader
test
join-plists))
(in-package :net.paul7.utility)
;;; simple utilities
(defmacro with-gensyms ((&rest names) &body body)
`(let ,(loop for n in names collect `(,n (gensym)))
,@body))
;; check if list consists of sole element
(defun single (list)
(and (consp list)
(not (cdr list))))
(defun mklist (obj)
(if (listp obj) obj (list obj)))
(defun compose (&rest fns)
(if fns
(let ((fn1 (car (last fns)))
(fns (butlast fns)))
#'(lambda (&rest args)
(reduce #'funcall fns
:from-end t
:initial-value (apply fn1 args))))
#'identity))
(defmacro convert-sequence (sequence class)
`(map ,class #'identity ,sequence))
(defmacro post-incf (place)
(with-gensyms (old)
`(let ((,old ,place))
(incf ,place)
,old)))
(defun sequence-reader (sequence)
(let ((position 0)
(length (length sequence)))
#'(lambda ()
(if (< position length)
(elt sequence (post-incf position))))))
(defmacro test (form)
(with-gensyms (result)
`(let ((,result ,form))
(format t "TESTING ~a => ~a~%" ',form ,result)
,result)))
(defun join-plists (first second)
(do ((result (copy-list first))
(rest second (cddr rest)))
((not rest)
result)
(let ((key (car rest))
(value (cadr rest)))
(setf (getf result key) value))))