Antsan
10/22/2015 10:26:00 AM
Am Donnerstag, 22. Oktober 2015 10:36:08 UTC+2 schrieb Jim Newton:
> Is there an automatic way using destructuring-bind to ignore certain values?
> Here is a pattern that I use too often.
>
> (destructing-bind ((a (b x1) x2 c)) data
> (declare (ignore x1 x2))
> ...)
>
> I'd like to write this something like the following.
>
> (destructing-bind ((a (b :ignore) :ignore c)) data
> ...)
>
> or
>
> (destructing-bind ((a (b t) t c)) data
> ...)
It's probably not the prettiest solution, but this is what I came up with:
(defmacro destructuring-bind? ((&rest lambda-list)
expression &body body)
(labels ((_make-ignored (obj) ; replaces every symbol beginning with an
; underscore with a gensym and collects these
; replaced symbols for ignoring
(etypecase obj
(symbol
(let ((name (symbol-name obj)))
(if (and (> (length name)
0)
(string= (elt name 0)
"_"))
(let ((gsym (gensym name)))
(values gsym (list gsym)))
(values obj '()))))
(cons
(loop with lambda-list = '()
with ignored = '()
for sub in obj
do
(multiple-value-bind (rep ign)
(_make-ignored sub)
(push rep lambda-list)
(setf ignored
(append ignored ign)))
finally (return
(values (nreverse lambda-list)
ignored))))
(null
(values nil nil)))))
(multiple-value-bind (lambda-list ignored)
(_make-ignored lambda-list)
`(destructuring-bind (,@lambda-list)
,expression
(declare (ignore ,@ignored))
,@body))))