我需要一个功能来显示未经处理的'表达

时间:2014-07-15 22:35:16

标签: scheme

我是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))以获得我需要的行为。任何提示欢迎。

2 个答案:

答案 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-syntaxsyntax-rules应该能够在支持R5RSR6RS的解释器中使用。