保留在程序中定义的变量?

时间:2014-01-24 00:36:41

标签: mit-scheme guile

我写了一个程序(do-test)。 由于测试可能会对变量env产生一些影响, 我在env内定义do-test,希望env不会被携带 随着程序,所以每次我运行它,我将获得一个新的环境来工作。 令我惊讶的是,我的测试程序实际上是前一个env。 请找到以下代码:

(define (do-test)

  (define env '(1))
  ;(define env (list 1))

  (display env)
  (if (not (equal? (car env) 1))
    (error "assertion failed.")
    'ok)

  (set-car! env 2)
  'ok)

(do-test)
(do-test)

我尝试使用mit-scheme / guile / codepad.org运行此代码,以及所有这些代码 告诉我两次跑(do-test)会产生不同的结果。

但如果我将行(define env '(1))更改为(define env (list 1)),我会得到预期的结果。 (您可以在codepad.org中找到我的代码beforeafter

据我所知,'(1)(list 1)应该相同,只是第二个是调用程序list

我想知道为什么会发生这种情况,如何防止程序重复使用以前的值?

1 个答案:

答案 0 :(得分:0)

请查看R5RS,其中说明了

  

更改常量(即文字的值)是错误的   表达式)使用像set-car!或。string-set!这样的变异过程   '(1)

因此(list 1)(define (f) (list 1)) (define (g) '(1)) (display (eq? (f) (f)))(newline) (display (eq? (g) (g)))(newline) 并不完全相同:当您打算构建将来会发生变异的某些数据时,请不要使用引号。

如果您尝试这样做:

#f
#t

你会得到:

f

这表明g会在每次调用时生成一个列表。但是'(1)会将其列表{{1}}视为常量,并且该列表只会被分配一次,无论它被调用多少次。