Skip to content

Commit e785535

Browse files
committed
add update, ->, assoc-in
1 parent 2303e11 commit e785535

File tree

1 file changed

+29
-3
lines changed

1 file changed

+29
-3
lines changed

Diff for: src/algorithm/hamt.lisp

+29-3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#:reduce
1616
#:seq)
1717
(:export #:+empty+
18+
#:->
1819
#:immutable-map
1920
#:assoc
2021
#:assoc-in
@@ -36,10 +37,13 @@
3637
#:seq
3738
#:size
3839
#:subset-p
40+
#:update
3941
#:vals))
4042

4143
(in-package #:coalton-impl/algorithm/hamt)
4244

45+
(eval-when (:compile-toplevel :load-toplevel :execute)
46+
4347
(defmacro define-constant (name value &optional doc)
4448
"Define a constant that can be redefined if the new value is equalp to the old."
4549
`(defconstant ,name
@@ -51,6 +55,19 @@
5155
,value)
5256
,@(when doc (list doc))))
5357

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+
5471
;; HAMT constants
5572

5673
(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
153170
(cdr pair))))
154171
(seq map1))))
155172

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))
157177
(write-char #\{ stream)
158178
(let ((first t))
159179
(dolist (pair (seq map))
@@ -169,8 +189,8 @@ Returns (values new-node inserted-p) where inserted-p is true for new insertions
169189
(if *print-readably*
170190
(print-map-pairs map stream)
171191
(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)))))
174194

175195
;;; leaf-node operations
176196

@@ -433,6 +453,12 @@ Returns (values new-node inserted-p) where inserted-p is true for new insertions
433453
(cdr keys)
434454
value)))))
435455

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+
436462
(defun reduce (function map &optional (initial-value +empty+))
437463
"Reduce over key-value pairs in the map"
438464
(cl:reduce (lambda (acc pair)

0 commit comments

Comments
 (0)