Lisp-rookie здесь.Elisp: расширение макроса при времени загрузки с оценкой неопределенной переменной
Моя цель - определить макрос, который сделает ключи точечного алиста доступными как переменные для доступа к соответствующим значениям, следовательно, имя «let-dotted-alist». Так что я хочу:
(setq foo '((a . "aa") (b . "bb")))
(let-dotted-alist foo
(message (concat a b)))
==> "aabb"
Вот лучшее, что я мог придумать до сих пор:
(defmacro let-dotted-alist (alist &rest body)
"binds the car of each element of dotted ALIST to the corresponding cdr and makes them available as variables in BODY."
`(let ,(nreverse
(mapcar
(lambda (p) (list (car p) (cdr p)))
(eval alist)))
,@body))
Проблема здесь является eval
. Мне нужно это для того, чтобы передать alist как переменную (foo
), а не буквальный, что является основным прецедентом при определении функций. Для макроса для разработки кода эта переменная должна быть связана уже. Все еще везде я читал, что использование eval имеет тенденцию указывать на недостаток кода? Есть ли способ обойти это?
Это было бы несколько академической проблемой, если бы Emacs 24 не представил нетерпеливое расширение макроса, которое хочет развернуть макрос во время загрузки, когда переменная (dotlist
в следующем примере), которая должна предоставить alist, по-прежнему недействительна:
(defun concat-my-cdrs (dotlist)
(let-dotted-alist dotlist
(print (concat a b))))
в зависимости от того, как я оцениваю это я либо получить »MAPCAR: значение символа как переменной является ничтожным: dotlist«или»Нетерпеливый отказ макрорасширение: (аннулируются переменной dotlist)«. Это имеет смысл, конечно, потому что переменный список точек действительно недействителен во время загрузки.
Теперь, прежде чем я попытаюсь найти обходное решение вдоль (локально) отключения активного макрообмена, есть ли способ улучшить определение макросов, чтобы вообще избежать eval
?
Заранее благодарен!
Возможно, мне не хватает чего-то тривиального ... но почему бы вам просто не использовать ', alist' вместо' (eval alist) '? (На самом деле, вы находитесь под ',' уже, так что точно отсутствует? –
Извините, не обращайте внимания на мой предыдущий комментарий. Понял! –