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

发布于 2024-07-15 07:08:49 字数 289 浏览 4 评论 0原文

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

(if (< 1 0) 'true)

我尝试过的任何解释器都只会返回一个新提示。 但是当我编写这个代码时,我有一个 if 来判断是否有替代表达式。 如果没有打印任何内容,我可以返回什么?

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

I'm writing a scheme interpreter, and in the case of an if statement such as:

(if (< 1 0) 'true)

Any interpreter I've tried just returns a new prompt. But when I coded this, I had an if for whether there was an alternative expression. What can I return in the if such that nothing gets printed?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

稍尽春風 2024-07-22 07:08:49

根据 R6RS 规范

如果<测试> 产生 #f 并且没有;
被指定,那么结果
表达式未指定。

所以,尽情发挥吧,返回任何你想要的东西! 尽管 #f 或 '() 是我个人所期望的。

According to the R6RS specification:

If <test> yields #f and no <alternate>
is specified, then the result of the
expression is unspecified.

So go wild, return anything you want! Although #f or '() are what I, personally, would expect.

人心善变 2024-07-22 07:08:49

Scheme 确实不能返回任何值:

   > (values)

在 R5RS 中,if 的单臂形式被指定返回未指定的值。
这意味着由您决定返回哪个值。
相当多的计划选择引入一个特定的值,称为
“未指定的值”并返回该值。
其他人则返回“不可见的值”#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)

如果 #; 是列表的一部分,它被打印:

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

Scheme can indeed return no values:

   > (values)

In R5RS the one-armed form of if is specified to return an unspecified value.
That means it is up to you, to decide which value to return.
Quite a few Schemes have chosen to introduce a specific value called
"the unspecified value" and returns that value.
Others return "the invisible value" #<void> and the REPL is written
such that it doesn't print it.

   > (void)

At first one might think, this is the same as (values),
but note the difference:

  > (length (list (void)))
  1

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

If #<void> is part of a list, it is printed:

  > (list (void))
  (#<void>)
一笑百媚生 2024-07-22 07:08:49

许多方案(PLT、Ikarus、Chicken)都有 void 类型,您可以使用 (void) 生成它。

至少在 PLT 中,void 是当你这样做时(当 (< 1 0) #t 时)得到的。

(PLT v4 不允许 if 没有 else 子句。)

A number of Schemes (PLT, Ikarus, Chicken) have a void type, which you can produce with (void).

In PLT at least, void is what you get when you do (when (< 1 0) #t).

(PLT v4 doesn't allow if without an else clause.)

濫情▎り 2024-07-22 07:08:49

当返回值未指定时,您可以返回您想要的值; 用户不能依赖该值永远存在或跨实现。

When the return value is unspecified you can return what you like; the user just can't rely on that value being there, ever, or across implementations.

じ违心 2024-07-22 07:08:49

首先,如果对您来说更容易的话,要求 if 有一个 else 子句是可以的。 其次,Scheme 支持从函数返回多个值,因此如果您要将返回值实现为列表,则可以有一个空列表,表示没有给出返回值。

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

这里有一个重要的区别:如果没有 else 子句,我不会返回空列表。 空列表表示没有返回值。 如果表达式有一个返回值(假设是 3),那么您将得到 (3) 作为幕后 eval 的返回值。 同样,从表达式返回多个值将导致 eval 返回列表具有多个元素。

最后,在所有实用性中,如果条件失败并且没有其他条件,您实际上可以返回任何东西,因为尝试捕获不返回的函数的值将是程序中的错误任何事物。 因此,捕获此错误将是程序员的工作,而不是语言的工作。

First, it's OK to require if to have an else clause, if it makes it easier for you. Second, Scheme supports returning multiple values from a function, so if you were to implement the return values as a list, you could have an empty list signify that no return value was given.

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

An important distinction here: I'm not returning an empty list if there was no else clause. The empty list signifies that there was no return value. If there were one return value from an expression (say it was 3) you would have (3) as the return from the eval behind the scenes. Similarly, returning multiple values from an expression would cause the eval return list to have multiple elements.

Finally, in all practicality, you could really return anything if the condition fails and there's no else, because it would be an error in a program to attempt to capture the value of a function that doesn't return anything. As such, it would be the job of the programmer, not the language, to catch this error.

扛起拖把扫天下 2024-07-22 07:08:49

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

如果 (eval (alternative if-expr)) 返回任何内容,并且您仍然想知道是否采用了此替代方案,则必须将结果与更多信息打包在一起:

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

因此,结果是一个缺点细胞。 如果它的车是#t,那么你就评估了一些东西。 如果是#f,那么你就没有。

Weird people would return 'nil or '|| (the empty symbol). The problem is to return a symbol that cannot be return by (eval (alternative if-expr)) to avoid confusion.

If anything can be returned by (eval (alternative if-expr)) and you still want to know whether you came in this alternative or not, you have to pack the result with more information :

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

Thus, the result is a cons cell. If its car is #t, then you evaled something. If it is #f, you didn't.

无人问我粥可暖 2024-07-22 07:08:49

只是: 有什么问题吗

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

What is wrong with just:

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

?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文