我是Scheme的新手,请原谅我使用错误的词汇。我想要一个函数,我称之为QandA,它将(除其他外)显示其原始或未处理的参数。例如:
(QandA (+ 1 2)) should return the string "(+ 1 2) : 3"
(QandA (quote (+ 1 2))) should return "(quote (+ 1 2)) : (+ 1 2)"
我首先尝试的是:
(define (QandA x)
(display (quote x)) (display " : " ) (display x))
但是
(QandA (+ 1 2)) returns "x : 3"
我理解为什么这是错误的,但不知道在哪里寻找解决方案。
所以问题是,我应该替换(显示(引用x))以获得我需要的行为。任何提示欢迎。
答案 0 :(得分:2)
正如@ymonad所指出的,这是使用macros的好方案 - 因为你需要将对作为参数传递的表达式的评估推迟到QandA
。您之前的一些问题已被标记为racket
,因此这里是使用#lang racket
(也适用于#lang scheme
)的Racket实现,它返回字符串 ,根据要求(如果您希望显示值format
替换为printf
):
(define-syntax-rule (QandA exp)
(format "~a : ~a" 'exp exp))
这是问题中给出的样本输入的输出:
(QandA (+ 1 2))
=> "(+ 1 2) : 3"
(QandA (quote (+ 1 2)))
=> "(quote (+ 1 2)) : (+ 1 2)"
答案 1 :(得分:1)
如您所见,您无法使用函数实现它,因为参数在传递给函数之前已经过计算。
一个解决方案是使用macros,它可以访问未处理的表达式并创建另一个表达式。
以下是适用于guile
的示例(define-syntax QandA
(syntax-rules ()
((QandA arg)
(begin (display (quote arg))(display " : ")(display arg)))))
(QandA ((+ 1 2))) ; (+ 1 2) : 3
(QandA (quote (+ 1 2))) ; (quote (+ 1 2)) : (+ 1 2)
生成宏的支持语法因解释器而异,因此您应该检查您正在使用的解释器文档
但是,define-syntax
和syntax-rules
应该能够在支持R5RS或R6RS的解释器中使用。