15
15
# :reduce
16
16
# :seq)
17
17
(:export # :+empty+
18
+ # :->
18
19
# :immutable-map
19
20
# :assoc
20
21
# :assoc-in
36
37
# :seq
37
38
# :size
38
39
# :subset-p
40
+ # :update
39
41
# :vals))
40
42
41
43
(in-package # :coalton-impl/algorithm/hamt)
42
44
45
+ (eval-when (:compile-toplevel :load-toplevel :execute )
46
+
43
47
(defmacro define-constant (name value &optional doc)
44
48
" Define a constant that can be redefined if the new value is equalp to the old."
45
49
` (defconstant , name
51
55
, value)
52
56
,@ (when doc (list doc))))
53
57
58
+ (defmacro -> (x &rest forms)
59
+ " Thread-first macro. Provide x as first argument to first form; provide return value as first argument to second form; etc."
60
+ (if (null forms)
61
+ x
62
+ (let ((form (car forms)))
63
+ (if (listp form)
64
+ ` (-> , (append (list (car form) x) (cdr form))
65
+ ,@ (cdr forms))
66
+ ` (-> (, form , x)
67
+ ,@ (cdr forms))))))
68
+
69
+ ) ; eval-when
70
+
54
71
; ; HAMT constants
55
72
56
73
(defconstant +bit-partition+ 5 ) ; 32 children per node
@@ -153,7 +170,10 @@ Returns (values new-node inserted-p) where inserted-p is true for new insertions
153
170
(cdr pair))))
154
171
(seq map1))))
155
172
156
- (defun print-map-pairs (map stream &key (format-fn #' write ))
173
+ (defun %write (obj s)
174
+ (format s " ~S " obj))
175
+
176
+ (defun print-map-pairs (map stream &key (format-fn #' %write))
157
177
(write-char #\{ stream )
158
178
(let ((first t ))
159
179
(dolist (pair (seq map ))
@@ -169,8 +189,8 @@ Returns (values new-node inserted-p) where inserted-p is true for new insertions
169
189
(if *print-readably*
170
190
(print-map-pairs map stream )
171
191
(print-unreadable-object (map stream :type t )
172
- (print-map-pairs map stream :format-fn
173
- ( lambda (obj s) ( format s " ~S " obj) )))))
192
+ (let (( * print-readably* t ))
193
+ (print-map-pairs map stream )))))
174
194
175
195
; ;; leaf-node operations
176
196
@@ -433,6 +453,12 @@ Returns (values new-node inserted-p) where inserted-p is true for new insertions
433
453
(cdr keys)
434
454
value)))))
435
455
456
+ (defun update (map key fn &rest args)
457
+ " Update a value in MAP by applying FN with extra ARGS to the existing value.
458
+ If the key doesn't exist, nil is provided to fn."
459
+ (assoc map key
460
+ (apply fn (get map key nil ) args)))
461
+
436
462
(defun reduce (function map &optional (initial-value +empty+ ))
437
463
" Reduce over key-value pairs in the map"
438
464
(cl :reduce (lambda (acc pair)
0 commit comments