内外减少,同样的结果?

时间:2017-02-04 11:11:58

标签: lisp racket operator-precedence

内部和外部缩小是否总是创建相同的值,如果不是会导致不同的值?

我在谈论Racket,一种功能语言。

我知道可能会更有效率,就像在球拍中但实际上会导致不同的结果。我无法创造一个发生这种情况的案例,但我觉得它应该是可能的,而且可能很危险,不知道。

示例:

;inner reduction
    (sqr (* 3 (+ 1 (sqr 2))))
        ->(sqr (* 3 (+ 1 (* 2 2))) ;(sqr)
        ->(sqr (* 3 (+ 1 4)) ;(*)
        ->(sqr (* 3 5)) ;(+)
        ->(sqr 15) ;(*)
        ->(* 15 15) ;(sqr)
        ->225 ;(*)

;outer reduction
    (sqr (* 3 (+ 1 (sqr 2))))
        ->(* (* 3 (+ 1 (sqr 2))) (* 3 (+ 1 (sqr 2))) ;(sqr)
        ->(* (* 3 (+ 1 (* 2 2))) (* 3 (+ 1 (sqr 2))) ;(sqr)
        ->(* (* 3 (+ 1 4)) (* 3 (+ 1 (sqr 2))) ;(*)
        ->(* (* 3 5) (* 3 (+ 1 (sqr 2))) ;(+)
        ->(* 15 (* 3 (+ 1 (sqr 2))) ;(*)
        ->(* 15 (* 3 (+ 1 (* 2 2))) ;(sqr)
        ->(* 15 (* 3 (+ 1 4))) ;(*)
        ->(* 15 (* 3 5)) ;(+)
        ->(* 15 15) ;(*)
        ->225 ;(*)

1 个答案:

答案 0 :(得分:1)

我不知道Racket,但一般来说,如果你的任何表达都有副作用,比如修改变量,输入/输出等,你就会遇到麻烦。

采用以下示例:

(define x 1)
(sqr (begin (set! x (add1 x)) x))

内部减少:

; x = 1
(sqr (begin (set! x (add1 x)) x))

; x = 2
(sqr (begin x))

; x = 2
(sqr (begin 2))

; x = 2
(sqr 2)

; x = 2
(* 2 2)

; x = 2
4

即。结果为4x的最终值为2

通过外部减少,你得到:

; x = 1
(* (begin (set! x (add1 x)) x)
   (begin (set! x (add1 x)) x))

; x = 2
(* (begin x)
   (begin (set! x (add1 x)) x))

; x = 2
(* 2
   (begin (set! x (add1 x)) x))

; x = 3
(* 2
   (begin x))

; x = 3
(* 2
   (begin x))

; x = 3
(* 2
   3)

; x = 3
6

即。结果为6x的最终值为3

还有另一个不同之处。随着内在的减少,你可能根本没有得到结果:

(define (my-if c t e)
  (if c t e))

(define (loop)
  (loop))

(my-if #t 42 (loop))

外部减少:

(my-if #t 42 (loop))
; definition of 'my-if'
(if #t 42 (loop))
; built-in 'if'
42

内在减少:

(my-if #t 42 (loop))
; definition of 'loop'
(my-if #t 42 (loop))
; definition of 'loop'
(my-if #t 42 (loop))
; definition of 'loop'
(my-if #t 42 (loop))
; definition of 'loop'
...

这永远不会终止。