给出以下代码:
(define (my-if condition iftrue iffalse)
(cond (condition iftrue)
(else iffalse)))
'-----example1
(my-if #t
(display "my if was true!")
(display "my if was false!"))
(newline)
'-----example2
(my-if #t
(display "my if was true!")
(+ 2 3))
为什么示例1会立即评估两个参数,并给出输出
my if was true!my if was false!
仅在示例2中
my if was true!
是输出?
这是因为display
永远不会被延迟,但算术运算符是,还是其他的呢?
答案 0 :(得分:3)
在两个案例两个参数得到评估 - 过程的工作原理,函数调用的所有参数都被评估在执行函数体之前,它们从不延迟! (除非明确这样做)。
这就是为什么你不能将my-if
作为一个程序来实现的原因,它必须是一种特殊形式,例如if
和{{ 1}},仅评估对应于真实条件的部分,或cond
部分,如果没有为真。另外,请记住else
只是在控制台上打印其参数,但它不会返回任何值。
您的第二个示例打印了该消息,但无论如何添加也已执行,只是因为第一个条件为真,它的值未被返回,因此{{ 1}}返回其第一个参数的值,该值是从display
调用返回的值(输入 my-if
之前的),这是无效的。例如,看看它在控制台上的输出结果:
display
正如预期的那样,两个参数都会被评估,但只会返回第一个值:
my-if
答案 1 :(得分:1)
不确定您是否可以使用lazy racket,但如果是,则可以使用
#lang lazy
(define (my-if p t f)
(cond [p t]
[else f]))
(my-if #t (display 'true) (display 'false))
; => true
如果你在普通球拍中运行......
#lang racket
(define (if p t f)
(cond [p t]
[else f]))
(if #t (display 'true) (display 'false))
; => truefalse
另一种可以实现懒惰的方法是将参数包装在lambdas中:
#lang racket
(define (my-if p t f)
; this calls the correct function with zero arguments
((if p t f)))
; wrap the delayed arguments in zero-argument functions
(my-if #t (λ () (display 'true)) (λ () (display 'false)))
; => true