【问题标题】:Racket begin form球拍开始形式
【发布时间】:2015-04-01 04:13:31
【问题描述】:
(define mystery2 
  (lambda (L)
    (if (null? L)
        L
        (begin
          (displayln L)
          (append (mystery2 (cdr L))
                  (list (car L)))))))

我通过(mystery2 '((1 2) (3 4) 5 6))运行它

在这里,我不确定“开始”功能的作用。

另外,当我写“displayln L”时,它只给我们((1 2) (3 4) 5 6))既然是递归,不应该打印出递减的值吗?

请帮我理解为什么这里使用了“begin”,而 displayln 是这样工作的。

代码本身没有问题。

【问题讨论】:

  • 注意它调用mystery 而不是它本身,所以我们不能说它是递归的。它可能是相互递归的,但mystery 需要调用mystery2

标签: scheme racket


【解决方案1】:

使用begin 形式是因为if 只允许在每个分支中使用1 个表达式。

一个更直观的例子可能是调试。假设您正在编写困难的代码,并且您想查看执行了哪个分支。

原码:

(if (true? some-value)
    (dostuff)
    (dostuff2))

但是您不确定哪个分支正在执行,因此您可能希望在执行任一分支时打印一条消息。但是由于 Scheme 只允许在每个分支中使用一个表达式,因此您不能只将它们放在那里。您必须使用begin 将它们粘合在一个表达式中。

(if (true? some-value)
    (begin
      (display "some-value was true")
      (dostuff))
    (begin 
      (display "some-value was false")
      (dostuff2)))

Begin 接受任意数量的表达式并执行每个表达式,但只返回正文中最后一个表达式的结果。

【讨论】:

  • 感谢您的回复!然后我想知道在“displayln”中,它只打印了一个列表。它不应该打印出更多吗?既然是递归,我以为应该多次调用“displayln”,意思是多次显示?
  • 如果mystery 打电话给mystery,当然可以。但是我们看不到mystery函数的代码..
【解决方案2】:

首先,让我回答你的问题:

begin 表单(它不是函数)只计算其子表达式,并返回最后一个的值。

因此,如果您评估 (begin 3 4 5),它只会返回 5。如果你评估(begin (+ 3 4) (+ 9 1)),你会得到10

所以...你可能会问为什么这会有用。答案是某些表达式会导致所谓的“副作用”。 displayln 就是其中之一;它会导致显示一个值。

不过,让我们退后一步。这里的秘诀是:尝试一下! Racket 是一种对实验非常友好的语言;几乎所有值都具有直接“可写”的形式,您可以提取小的表达式并计算它们以查看它们产生的结果。

请随时提出后续问题!

【讨论】:

  • 哦。那么 'begin' 形式用于评估子表达式,但也有助于避免副作用,例如 'displayln'? “副作用”在球拍中的含义是否不同?
  • @HAruMOmo 没有副作用,唯一的结果是返回的值,它仅基于参数。例如。如果你读、写、存储或检索某些东西,它的副作用。在您的示例中,displayln 可能具有向终端打印某些内容的副作用。
  • 感谢您的回复!
【解决方案3】:

begin 将几个表达式包装成一个block。使用cond 而不是if 的原因之一是结果会自动包装在一个块中。

(define mystery2 
  (lambda (L)
    (cond [(null? L)
           L] 
          [else
            (displayln L)
            (append (mystery2 (cdr L))
                    (list (car L)))])))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-03
    • 2016-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    相关资源
    最近更新 更多