内外还原,结果一样吗?
inner and outer reduction, same result?
内缩减和外缩减是否总是产生相同的值,如果不是,会导致不同的值吗?
我说的是 Racket,一种函数式语言。
我知道有可能它在 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 ;(*)
我不了解 Racket,但一般来说,如果您的任何表达式有副作用,例如修改变量、执行 input/output 等,您可能 运行 会遇到麻烦
举个例子:
(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
即结果是 4
而 x
的最终值是 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
即结果是 6
而 x
的最终值是 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'
...
这永远不会终止。
内缩减和外缩减是否总是产生相同的值,如果不是,会导致不同的值吗?
我说的是 Racket,一种函数式语言。
我知道有可能它在 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 ;(*)
我不了解 Racket,但一般来说,如果您的任何表达式有副作用,例如修改变量、执行 input/output 等,您可能 运行 会遇到麻烦
举个例子:
(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
即结果是 4
而 x
的最终值是 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
即结果是 6
而 x
的最终值是 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'
...
这永远不会终止。