aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Okay <colin@cicadas.surf>2022-11-01 09:58:17 -0500
committerColin Okay <colin@cicadas.surf>2022-11-01 09:58:17 -0500
commite46dea130e2eb36cb0cc1956a100a0497981dc42 (patch)
treea03afbba68d50a2600c7cce1c070668f046ab598
parentf44415ea46b246bee09b26b21de340b401bacc6d (diff)
Add: pluck-nested and get-nested
-rw-r--r--derrida.lisp16
-rw-r--r--package.lisp4
2 files changed, 19 insertions, 1 deletions
diff --git a/derrida.lisp b/derrida.lisp
index c9bd495..442c890 100644
--- a/derrida.lisp
+++ b/derrida.lisp
@@ -86,3 +86,19 @@ And would return
else
collect `(,term (getf ,plist-var ',term)))))
`(let ((,plist-var ,plist)) (symbol-macrolet ,macrolet-bindings ,@body))))
+
+
+(defun get-nested (plist-tree &rest indicators)
+ "PLIST-TREE is plist some of whose values are also
+ PLISTS. INDICATORS are keyes to the plists."
+ (if (or (null plist-tree) (null indicators))
+ plist-tree
+ (apply #'get-nested (getf plist-tree (car indicators)) (cdr indicators))))
+
+(defmacro pluck-nested (keypaths plist &body body)
+ "Pluck nested binds variables to paths into a plist tree."
+ (let ((tmp-plist (gensym "plist")))
+ `(let ((,tmp-plist ,plist))
+ (let ,(loop for (var . path) in keypaths
+ collect `(,var (get-nested ,tmp-plist ,@path)))
+ ,@body))))
diff --git a/package.lisp b/package.lisp
index 62377cb..8484a30 100644
--- a/package.lisp
+++ b/package.lisp
@@ -3,4 +3,6 @@
(defpackage #:derrida
(:use #:cl)
(:export #:with-plist
- #:with-alist))
+ #:with-alist
+ #:get-nested
+ #:pluck-nested))