在过程中定义一个变量
define a variable inside procedure
我可以在过程中定义变量吗?在我看来,我只能在程序内部定义另一个程序。我在 SICP 做练习时想到了这个问题,(rand)
不是我想要的,因为它会生成两个不同的随机数,而我想在这两个位置使用相同的数字。
(define (try x)
(define (rand) (+ 1 (random (- x 1))))
(= (rand) (expmod (rand) x x)))
我在下面包含了 expmod
的代码。
(define % remainder)
(define (square a) (* a a))
(define (even? a) (= (% a 2) 0) )
(define (expmod base pow mod)
(cond
((= pow 0)
1)
((even? pow)
(% (square (expmod base (/ pow 2) mod)) mod))
(else
(% (* base (expmod base (- pow 1) mod) ) mod))))
(define (try x)
(define rand (+ 1 (random (- x 1))))
(= (rand) (expmod (rand) x x)))
(define (try x)
(let ((rand (+ 1 (random (- x 1)))))
(= (rand) (expmod (rand) x x))))
这些作品中的任何一个。
是的,当然可以。特别是
(define (x ...) ...)
只是shorthand
(define x (lambda (...) ...))
所以你已经定义了一个变量:rand
,它的值是一个函数。
您可能想要的是:
(define (try x)
(define rand (+ 1 (random (- x 1)))
(= rand (expmod rand x x)))
这又与
相同
(define (try x)
(let ([rand (+ 1 (random (- x 1)))])
(= rand (expmod rand x x))))
是的,你可以。
(define (try x)
(define rand (+ 1 (random (- x 1))))
(= rand (expmod rand x x)))
您还必须知道 =
和 try
也是变量,它们对过程求值。通常一个过程是这样创建的:
(define double (lambda (n) (+ n n)))
但是有一个简短的写法L
(define (double n) (+ n n))
现在看看你的代码。您不是使用短语法为 lambda 创建变量 rand
吗?
(define (rand) (+ 1 (random (- x 1))))
评估 rand
应该给你某种程序输出,如 #<procedure: rand>
并调用它 (rand)
将执行 (+ 1 (random (- x 1)
。这些类型的程序称为 thunk,通常用于延迟评估。
在 Scheme 中不能做的一件事是从过程中定义顶级变量。例如
(define (make-test v)
(define test v))
(make-test 5)
(displayln test) ; unbound variable
原因是在一个过程中,它总是会创建一个仅存在于该闭包内的本地绑定。可以定义一个顶级变量然后设置它:
(define test 0) ; make a top level variable
(define (update-test v)
;; since no other that top level is named test,
;; that is the binding this is updating.
(set! test v))
(update-test 5)
(display test) : prints 5
我可以在过程中定义变量吗?在我看来,我只能在程序内部定义另一个程序。我在 SICP 做练习时想到了这个问题,(rand)
不是我想要的,因为它会生成两个不同的随机数,而我想在这两个位置使用相同的数字。
(define (try x)
(define (rand) (+ 1 (random (- x 1))))
(= (rand) (expmod (rand) x x)))
我在下面包含了 expmod
的代码。
(define % remainder)
(define (square a) (* a a))
(define (even? a) (= (% a 2) 0) )
(define (expmod base pow mod)
(cond
((= pow 0)
1)
((even? pow)
(% (square (expmod base (/ pow 2) mod)) mod))
(else
(% (* base (expmod base (- pow 1) mod) ) mod))))
(define (try x)
(define rand (+ 1 (random (- x 1))))
(= (rand) (expmod (rand) x x)))
(define (try x)
(let ((rand (+ 1 (random (- x 1)))))
(= (rand) (expmod (rand) x x))))
这些作品中的任何一个。
是的,当然可以。特别是
(define (x ...) ...)
只是shorthand
(define x (lambda (...) ...))
所以你已经定义了一个变量:rand
,它的值是一个函数。
您可能想要的是:
(define (try x)
(define rand (+ 1 (random (- x 1)))
(= rand (expmod rand x x)))
这又与
相同(define (try x)
(let ([rand (+ 1 (random (- x 1)))])
(= rand (expmod rand x x))))
是的,你可以。
(define (try x)
(define rand (+ 1 (random (- x 1))))
(= rand (expmod rand x x)))
您还必须知道 =
和 try
也是变量,它们对过程求值。通常一个过程是这样创建的:
(define double (lambda (n) (+ n n)))
但是有一个简短的写法L
(define (double n) (+ n n))
现在看看你的代码。您不是使用短语法为 lambda 创建变量 rand
吗?
(define (rand) (+ 1 (random (- x 1))))
评估 rand
应该给你某种程序输出,如 #<procedure: rand>
并调用它 (rand)
将执行 (+ 1 (random (- x 1)
。这些类型的程序称为 thunk,通常用于延迟评估。
在 Scheme 中不能做的一件事是从过程中定义顶级变量。例如
(define (make-test v)
(define test v))
(make-test 5)
(displayln test) ; unbound variable
原因是在一个过程中,它总是会创建一个仅存在于该闭包内的本地绑定。可以定义一个顶级变量然后设置它:
(define test 0) ; make a top level variable
(define (update-test v)
;; since no other that top level is named test,
;; that is the binding this is updating.
(set! test v))
(update-test 5)
(display test) : prints 5