因此,对于大学作业,我们被要求使用宏,并且我发现很难理解如何在计划中实现代码(我们从一个字符串转换到在一个讲座中构建一个解释器)。
(define macro-alist
`((and ,(λ (e)
(let ((forms (cdr e)))
(cond ((null? forms) '#t)
((null? (cdr forms)) (car forms))
(else `(if ,(car forms) (and ,@(cdr forms)) #f))))))
;(or ,error)
;(let ,error)
;(cond ,error)
(if ,(λ (e) (let ((guard (cadr e))
(then-part (caddr e))
(else-part (cadddr e)))
`((%if ,guard (λ () ,then-part) (λ () ,else-part))))))
))
我们被要求填写宏观内容中的错误保留'周末,我发现很难。 我找到了一些资源,并将它们与我自己的简要知识相结合:
`((or ,(lambda (e)
(and (list-strictly-longer-than? e 0)
(equal? (list-ref e 0) 'or)
(letrec ([visit (lambda (i)
(if(null? i)
#t
(and (is-exression? (car i))
(visit (cdr i)))))])
(visit (cdr e)))))))
`((let ,(lambda (e)
(and (proper-list-of-given-length? e 3)
(equal? (car e) 'let)
(list? (cadr e))
(is-expression? (list-ref e 2))
(lectrec ([visit (trace-lambda visit (i a)
(if(null? i)
#t
(and (proper-list-of-given-length? (car i) 2)
(is-identifier? (caar i))
(is-expression? (cadar i))
(not (member (caar i) a))
(visit (cdr i) (cons (caar i) a)))))])
(visit (cadr e) '()))))))
`((cond ,(lambda (e)
(and (list-strictly-longer-than? e 1)
(equal? (car v) 'cond)
(lectrec ([visit (lambda (i)
(if (null? (cdr i))
(is-else-clause? (car i))
(if (pair? (cdr i))
(and (cond? (car i))
(visit (cdr i))))))])
(visit (cdr e)))))))
for or,let and cond。我想知道这些是否正确或我是否关闭。我不太了解宏或计划,所以一些信息/帮助做什么将不胜感激。
答案 0 :(得分:0)
如果你看一下and
的实现:
(define expand-and
(λ (e)
(let ((forms (cdr e)))
(cond ((null? forms) '#t)
((null? (cdr forms)) (car forms))
(else `(if ,(car forms) (and ,@(cdr forms)) #f))))))
(expand-and '(and)) ; ==> #t
(expand-and '(and a)) ; ==> a
(expand-and '(and a b)) ; ==> (if a (and b) #f)
我注意到两件事。它并没有真正仔细检查第一个元素是and
还是它是一个列表。也许解释器不会使用它,除非它已经检查过这个?
其次,您似乎不需要扩展所有内容。如您所见,最终可能会使用较少的参数+ and
。不需要递归,因为评估者会为你做这件事。
我认为你过度思考它。对于or
,它应该非常相似:
(expand-or '(or)) ; ==> #f
(expand-and '(or a b c)) ; ==> (let ((unique-var a)) (if unique-var unique-var (or b c)))
let绑定会阻止a
的双重评估,但如果您没有副作用,则可以将其重写为(if a a (or b))
。与and
一样,or
可能会扩展为使用or
,其参数少于原始参数。您可以使用cond
处理此技巧:
(cond (a b c)
...) ; ==>
(if a
(begin b c)
(cond ...))
let
不需要这个,因为如果你掌握map
,它可能是最简单的一个:
(let ((a x) (c y))
body ...) ; ==>
((lambda (a c) body ...) x y)
The report有examples of how the macros for these are made,但它们可能不是最简单的重写函数,它将代码作为你的interpeter之类的结构。然而,使用报告来理解表格可能与在SO上发布问题一样有效。