-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathwalk.lisp
More file actions
41 lines (34 loc) · 1.45 KB
/
walk.lisp
File metadata and controls
41 lines (34 loc) · 1.45 KB
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
;;a simple code walking package based off clojure.walk, with
;;severe limitations.
(defpackage :clclojure.walk
(:use :common-lisp :common-utils)
(:export :walk :prewalk :postwalk :prewalk-replace :postwalk-replace) ;:loop :defmacro
)
(in-package :clclojure.walk)
;; "Traverses form, an arbitrary data structure. inner and outer are
;; functions. Applies inner to each element of form, building up a
;; data structure of the same type, then applies outer to the result.
;; Recognizes all Clojure data structures. Consumes seqs as with doall."
;; {:added "1.1"}
(defun walk (inner outer form)
(cond ((listp form)
(funcall outer (apply #'list (mapcar (lambda (x) (funcall inner x)) form))))
(t (funcall outer form))))
;; "Like postwalk, but does pre-order traversal."
;; {:added "1.1"}
(defun prewalk (f form)
(walk (lambda (x)
(prewalk f x)) #'identity (funcall f form)))
(defun postwalk (f form)
(walk (lambda (x)
(postwalk f x)) f form))
;; "Recursively transforms form by replacing keys in smap with their
;; values. Like clojure/replace but works on any data structure. Does
;; replacement at the root of the tree first."
;; {:added "1.1"}
(defun prewalk-replace (f form)
(prewalk (lambda (x) (let ((res (funcall f x)))
(if res res x))) form))
(defun postwalk-replace (f form)
(postwalk (lambda (x) (let ((res (funcall f x)))
(if res res x))) form))