计划延迟评估

时间:2016-03-07 03:21:44

标签: if-statement scheme evaluation short-circuiting delayed-execution

给出以下代码:

(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永远不会被延迟,但算术运算符是,还是其他的呢?

2 个答案:

答案 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