球拍开始形式
Racket begin form
(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))
在这里,我不确定 "begin" 函数的作用。
此外,当我写 "displayln L" 时,它只会给我们 ((1 2) (3 4) 5 6))
。 既然是递归,它不应该打印出递减的值吗?
请帮我理解为什么这里使用 "begin" 并且 displayln 是这样工作的。
代码本身没有问题
首先,让我回答你的问题:
begin
形式(它不是函数)只计算它的子表达式,returns 是最后一个的值。
因此,如果您评估 (begin 3 4 5)
,它将只是 return 5
。如果你评估 (begin (+ 3 4) (+ 9 1))
,你将得到 10
。
所以...您可能会振振有词地问为什么这会有用。答案是某些表达式会导致所谓的 "side effects"。 displayln
是其中之一;它会导致显示一个值。
不过,让我们退后一步。这里的秘诀是:尝试一下! Racket 是一种对实验非常友好的语言;几乎所有值都有直接的 "writable" 形式,您可以提取小表达式并计算它们以查看它们产生的结果。
随时提出后续问题!
使用 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 获取任意数量的表达式并执行每个表达式,但仅 returns 正文中最后一个表达式的结果。
begin
将几个表达式包装成一个 block。使用 cond
而不是 if
的原因之一是结果自动包装在一个块中。
(define mystery2
(lambda (L)
(cond [(null? L)
L]
[else
(displayln L)
(append (mystery2 (cdr L))
(list (car L)))])))
(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))
在这里,我不确定 "begin" 函数的作用。
此外,当我写 "displayln L" 时,它只会给我们 ((1 2) (3 4) 5 6))
。 既然是递归,它不应该打印出递减的值吗?
请帮我理解为什么这里使用 "begin" 并且 displayln 是这样工作的。
代码本身没有问题
首先,让我回答你的问题:
begin
形式(它不是函数)只计算它的子表达式,returns 是最后一个的值。
因此,如果您评估 (begin 3 4 5)
,它将只是 return 5
。如果你评估 (begin (+ 3 4) (+ 9 1))
,你将得到 10
。
所以...您可能会振振有词地问为什么这会有用。答案是某些表达式会导致所谓的 "side effects"。 displayln
是其中之一;它会导致显示一个值。
不过,让我们退后一步。这里的秘诀是:尝试一下! Racket 是一种对实验非常友好的语言;几乎所有值都有直接的 "writable" 形式,您可以提取小表达式并计算它们以查看它们产生的结果。
随时提出后续问题!
使用 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 获取任意数量的表达式并执行每个表达式,但仅 returns 正文中最后一个表达式的结果。
begin
将几个表达式包装成一个 block。使用 cond
而不是 if
的原因之一是结果自动包装在一个块中。
(define mystery2
(lambda (L)
(cond [(null? L)
L]
[else
(displayln L)
(append (mystery2 (cdr L))
(list (car L)))])))