Scheme中的printf步骤

时间:2013-11-06 11:57:56

标签: scheme

例如,当我在列表printf上使用过程'((2 t r d))时,输出中的最后一行是

'(#<void>)

'(#<void>)出现的次数取决于嵌套列表的数量。你能帮我解释一下吗???

这是我的printf功能

(define counting 
  (lambda (lst)
    (if (null? lst)
        '()
        (printf "~a, ~s\n" (car lst) (length (cdr lst))))))

我尝试了其他程序,例如fprintf并使用此表格

(fprintf (current-output-port) "~a, ~s\n" (car lst) (length (cdr lst)))

同样的事情发生了!

2 个答案:

答案 0 :(得分:1)

AFAIK Scheme标准中没有此类过程,因此您可能需要为具有该标准的实现添加标记。我知道racketprintf

单独(display x)(以及球拍中的(printf x)通常不显示,因此产生(#<void>)的内容不在问题中。在Scheme中,每个过程都计算为一个值。为了说明这一点,请尝试:

(map display '(1 2 3 4))

这将返回一个包含4个未指定值的列表,因为map会显示结果列表。 display(以及球拍中的printf)打印参数评估的结果,但不需要返回任何内容,因为标准没有说应该。大多数实现通过返回一个未定义的对象来做到这一点,但有些实际上也返回了参数。它们的主要功能是在屏幕上显示某些内容以及它已经完成的副作用。为了忽略返回值,您可以使用for-each来映射副作用。

(for-each display '(1 2 3 4))

当在Scheme中说这是正常的,每个过程都返回一些内容,并且你通过REPL打印返回值来误读输出。

答案 1 :(得分:0)

你说'输出的最后一行是'(#<void>) - 这是因为你的Scheme环境显示1)你想要打印的内容和2)评估表达式的返回值。例如

> (list (display 1))
1(#<void>)

打印“1”,然后打印列表结果。由于您在交互式会话中键入内容,因此始终会显示返回的值。您无法真正隐藏返回的值,但大多数方案将识别“未定义”返回值而不打印它。

> (display 1)
1

在上文中,即使display返回#<void>,解释器也知道不会显示它。