;;;; derrida.lisp (in-package #:derrida) (defmacro with-plist (keys plist &body body) "KEYS is a list, each member of which is either a symbol or a pair of symbols. If a member is just a symbol, say KEY, then it is treated as the name of a symbol-macro (defined using symbol-macrolet) that expands to the expression (getf PLIST KEY). In this case, KEY is not allowed to be a keyword symbol. If a member is a pair of symbols, it is of the form (VAR KEY). Here, key is a valid key into the PLIST and VAR is the name of the symbol macrolet that will be bound to (getf PLIST KEY). EXAMPLE: (let ((pl (list 'name \"colin\" :age 40 :|currentJob| :crumb-bum))) (hq:with-plist (name (age :age) (job :|currentJob|)) pl (setf age (1+ age)) (format t \"~a the ~a had a birthday, and is now ~a years old~%\" name job age) pl)) The above would print out: colin the CRUMB-BUM had a birthday, and is now 41 years old And would return (NAME \"colin\" :AGE 41 :|currentJob| :CRUMB-BUM)" (let* ((plist-var (gensym)) (macrolet-bindings (loop for term in keys when (consp term ) collect (destructuring-bind (var key) term `(,var (getf ,plist-var ',key))) else collect `(,term (getf ,plist-var ',term))))) `(let ((,plist-var ,plist)) (symbol-macrolet ,macrolet-bindings ,@body))))