4 ms·
Extracting keys from maps into a definition, with common-lisp (using my macro defk) (defk login (user pass) (and (string= user "Bob") (string= pass "secret"))
by zeroyzeroa 12y ago
Extracting keys from maps into a definition, with common-lisp (using my macro defk)
(defk login (user pass)
(and (string= user "Bob") (string= pass "secret")))
(login (list-to-hash '(user "Bob" pass "secret"))
(list-to-hash '(user "Bob" pass "secret"))
Given the following definitions:
(defmacro defk(name h-list &rest body)
`(defun ,name (h)
(let ,h-list
,@(loop for k in h-list collect `(setq ,k (gethash (quote ,k) h)))
,@body)))
(defun list-to-hash(list)
(let ((h (make-hash-table)))
(loop for (k v) on list by #'cddr do (setf (gethash k h) v))
h))
- malisper 12y agoIt's probably more idiomatic to implement something similar to the with-slots macro by using symbol-macrolet: (defmacro with-keys (keys table &body body) (let ((gtable (gensym))) `(let ((,gtable ,table)) (symbol-macrolet ,(loop for k in keys collect `(,k (gethash ',k ,gtable))) ,@body)))) This way you can both access and set the keys: CL-USER> (defparameter *table* (make-hash-table)) *TABLE* CL-USER> (setf (gethash 'a *table*) 10 (gethash 'b *table*) 20) 20 CL-USER> (with-keys (a b) *table* (list a b)) (10 20) CL-USER> (with-keys (a b) *table* (setf a 100 b 200)) 200 CL-USER> (list (gethash 'a *table*) (gethash 'b *table*)) (100 200) If you really want to destructure a hash-table when its an argument, it is not much harder to write a new version of defun on top of with-keys or zeroyzeroa's solution (his/hers only takes a single argument).