我需要在方案中编写lisp宏(请使用卫生宏和语法规则等),该方案将具有函数调用和Alist作为参数
我希望调用该函数的函数和宏具有如下语法:
(foo '(10 (a (lambda () (display "10")) b (lambda () (display "20"))))
或不带引号的宏。
我的最后一个代码正在运行,但是不确定这是否是您编写这样的函数/宏的方式。似乎我需要双反引号,但不知道如何编写。 (我现在正在阅读Paul Graham的On Lips,他说很难用双反引号,只需要定义宏的宏即可,但这似乎就是我所需要的。)
(define (foo expr)
`(list ,(car expr)
(,(string->symbol "quasiquote") ,(pair-map (lambda (a b)
(cons (symbol->string a)
(list 'unquote b)))
(cadr expr)))))
(define-macro (bar expr)
(foo expr))
(define xx (bar (10 (a 20 b (lambda () (display "x") (newline))))))
;; (list 10 `((a . ,20) (b . ,(lambda () (display "x") (newline))))
(define bfn (cdr (assoc "b" (cadr xx)))))
(bfn)
;; "x"
这是配对图的定义
(define (pair-map fn seq-list)
"(seq-map fn list)
Function call fn argument for pairs in a list and return combined list with
values returned from function fn. It work like the map but take two items from list"
(let iter ((seq-list seq-list) (result '()))
(if (null? seq-list)
result
(if (and (pair? seq-list) (pair? (cdr seq-list)))
(let* ((first (car seq-list))
(second (cadr seq-list))
(value (fn first second)))
(if (null? value)
(iter (cddr seq-list) result)
(iter (cddr seq-list) (cons value result))))))))
使用(string->symbol "quasiquote")
时,我无法使用双反引号,这可以用双反引号/准引号书写吗?这应该是什么样子?
我在问这是否可以用不同的方式编写,以便我可以在自己的Lisp解释器中解决几个问题(不确定是否可以正常工作,但最终版本似乎在guile中是相同的)。
答案 0 :(得分:0)
我想出了较短的准引用版本,但仍然需要插入符号:
(define (foo expr)
`(list ,(car expr)
(,'quasiquote ,(pair-map (lambda (a b)
`(,(symbol->string a) . (,'unquote ,b)))
(cadr expr)))))