我对Scheme很新,我一直在努力解决我认为应该是一个简单的问题。
我正在尝试转换类似
的内容 ((qty 30) (name "ham"))
至(sandwich "@qty" 30) (sandwich "@name" "ham")
此外,这必须是动态的,以允许额外的条款:
((qty 30) (name "ham") (cheese 'no))
这是我到目前为止所做的:
(define-syntax (make-sandwiches x)
(syntax-case x ()
[(_ ((col val)...) ) #``(sandwich #,(format "@,~a" (caar #'((col val)...))) #,(cadar #'((col val)...)))]
[(_) "make-sandwiches is bad"]))
(制作三明治((数量30)(姓名"火腿")))=> (param" @#(语法数量)" 30)
所以这有点接近,但它只翻译第一个子句,所以我的想法是使用map
或类似的东西,但我不确定这是否正确:
(define-syntax (make-sandwiches x)
(syntax-case x ()
[(_ ((col val)...)) (map (lambda (cv) #``(sandwich #,(format "@,~a" (caar cv)) #,(cadar cv))) #'((col val)...))]
[(_) "make-sandwiches is bad"]))
答案 0 :(得分:4)
你真的必须使用宏吗?并返回多个值?一个返回列表的简单程序就可以解决问题:
(define (make-sandwiches lst)
(map (lambda (data)
(list 'sandwich
(string-append "@" (symbol->string (car data)))
(cadr data)))
lst))
或者更短(你似乎在使用Racket):
(define (make-sandwiches lst)
(map (lambda (data) `(sandwich ,(format "@~a" (first data)) ,(second data)))
lst))
例如,使用问题中的示例输入:
(make-sandwiches '((qty 30) (name "ham") (cheese 'no)))
=> '((sandwich "@qty" 30) (sandwich "@name" "ham") (sandwich "@cheese" 'no))