在过程中定义一个变量

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