你能从Scheme中的函数中返回任何内容吗?

时间:2009-03-19 22:54:22

标签: lisp scheme

我正在编写一个方案解释器,并且在if语句的情况下如:

(if (< 1 0) 'true)

我尝试过的任何解释器都会返回一个新提示。但是当我对此编码时,我有一个if是否有另一种表达方式。如果不打印任何内容,我可以返回什么?

(if (has-alternative if-expr)
  (eval (alternative if-expr))
  #f) ;; what do I return here?

7 个答案:

答案 0 :(得分:10)

根据R6RS specification

  

如果&lt; test&gt;产生#f而没有&lt; alternate&gt;   指定,然后是结果   表达式未指定。

所以狂野,回归任何你想要的东西!虽然#f或'()是我个人所期望的。

答案 1 :(得分:8)

Scheme确实可以不返回任何值:

   > (values)

在R5RS中,if的单臂形式被指定为返回未指定的值。 这意味着由您来决定返回哪个值。 相当多的方案选择引入一个特定的值 “未指定的值”并返回该值。 其他人返回“无形的价值”#&lt; void&gt;并编写REPL 这样它就不会打印出来。

   > (void)

起初人们可能会认为,这与(值)相同, 但要注意区别:

  > (length (list (void)))
  1

  > (length (list (values)))
  error>  context expected 1 value, received 0 values
  (Here (list ...) expected 1 value, but received nothing)

如果#&lt; void&gt;是列表的一部分,它打印出来:

  > (list (void))
  (#<void>)

答案 2 :(得分:2)

许多方案(PLT,Ikarus,Chicken)都有一个void类型,你可以用(void)生成它。

至少在PLT中,无效就是你得到的(当(&lt; 1 0)#t)时。

(如果没有else子句,PLT v4不允许。)

答案 3 :(得分:2)

如果未指定返回值,您可以返回您喜欢的内容;用户不能依赖于那里,任何地方或跨实现的价值。

答案 4 :(得分:1)

首先,可以要求if是否有一个else子句,如果它更容易让你。其次,Scheme支持从函数返回多个值,因此如果要将返回值实现为列表,则可以使用空列表表示没有给出返回值。

(if (has-alternative if-expr)
  (eval (alternative if-expr)) ; make sure eval returns a list
  '())

这里有一个重要的区别:如果没有其他条款,我不会返回空列表。空列表表示没有返回值。如果表达式中有一个返回值(比如它是3),那么你将得到(3)作为幕后eval的返回值。类似地,从表达式返回多个值将导致eval返回列表具有多个元素。

最后,在所有实际情况中,如果条件失败并且没有别的情况,你可以真正返回任何,因为在程序中尝试捕获函数的值是错误的不归还任何东西。因此,捕获此错误将是程序员的工作,而不是语言。

答案 5 :(得分:1)

奇怪的人会返回'nil'||(空符号)。问题是返回(eval (alternative if-expr))无法返回的符号以避免混淆。

如果(eval (alternative if-expr))可以返回任何内容,而您仍然想知道您是否选择了此替代方案,则必须将结果包含更多信息:

(if (has-alternative if-expr)
  (cons #t (eval (alternative if-expr)))
  (cons #f #f))

因此,结果是cons细胞。如果它的车是#t,那你就躲过了什么。如果是#f,那你没有。

答案 6 :(得分:0)

只是有什么问题:

(if (has-alternative if-expr) (eval (alternative if-expr)))