Hi all,
Wanted to share with you a macro I wrote about let (and let*) with
list destructuring. Something similar to the destructuring-bind as seen
in stuff.scm
I missed this functionality from clojure.
Example usage:
;; letd: mnemonic: let-destructure
(letd ((a 1)
(b 2)
((c d) (list (+ 1 2) 4)))
(list a b c d ))
;; => (1 2 3 4)
(letd* ((a 1)
(b 2)
((c d) (list (+ 1 2) 4))
(e (+ 1 d)))
(list a b c d e))
;; => ;; (1 2 3 4 5)
Note: clojure also has destructuring for maps etc. Didn't have this need
yet,
but guess the macro could be modified to accommodate destructuring
hashmaps, inlets etc.
;; useful for the letd : let with list destructuring
(define (interleave-pairs c1 c2)
(let loop ((res ())
(c1 c1)
(c2 c2))
(if (or (null? c1)
(null? c2))
res
(loop (append res (list (list (car c1) (car c2))))
(cdr c1)
(cdr c2)))))
(comment
(interleave-pairs '(a b c) '(1 2 3))
;; ((a 1) (b 2) (c 3))
)
;; let with list destructuring
;; Note: the _ is normally bound.. that ok?
;;
;; bacro cause we want the environment of where this is called. From
;; the doc: A bacro is a macro that expands its body and evaluates the
;; result in the calling environment.
(define-bacro (letd bindings . body)
`(let
,(apply
append
()
(map
(lambda (param+exp)
;; the {s} is for param or params
(let ((param{s} (car param+exp)))
(if (pair? param{s})
;; pair => destructuring
(let ((vals (eval (cadr param+exp))))
(interleave-pairs param{s} vals))
;; normal symbol
(list (list (car param+exp) (cadr param+exp))))))
bindings))
,@body))
(comment
(letd ((a 1)
(b 2)
((c d) (list (+ 1 2) 4)))
(list a b c d ))
;; (1 2 3 4)
(letd ((a 1)
(b 2)
((c d) (list (+ 1 2) 4))
(e (+ 1 d)))
(list a b c d e))
;; will fail (e doesn't know about d)
)
;; let* with list destructuring
(define-bacro (letd* bindings . body)
`(let*
,(apply
append
()
(map
(lambda (param+exp)
(print "param+exp" param+exp)
;; the {s} is for param or params
(let ((param{s} (car param+exp)))
(if (pair? param{s})
;; pair => destructuring
(let ((vals (eval (cadr param+exp))))
(interleave-pairs param{s} vals))
;; normal symbol
(list (list (car param+exp) (cadr param+exp))))))
bindings))
,@body))
(comment
(letd* ((a 1)
(b 2)
((c d) (list (+ 1 2) 4))
(e (+ 1 d)))
(list a b c d e))
;; (1 2 3 4 5)
)
_______________________________________________
Cmdist mailing list
[email protected]
https://cm-mail.stanford.edu/mailman/listinfo/cmdist