Racket 使用词法闭包

Racket using lexical closures

我在 Let over Lambda 中读到了有关词法 clojure 的内容,此代码示例是为 Common Lisp 提供的:

(let ((counter 0))
  (lambda () (incf counter)))

我尝试在 Racket 中将其写为:

(let ((counter 0))
  (lambda() (+ counter 1)))

当我在 REPL 中将它称为 counter 时,它给出了错误:

counter: undefined;
 cannot reference an identifier before its definition

据我所知,将 let/set 与 lambda 混合使您能够在 lambda 中存储一些可以由其他函数处理的状态,其方式与人类记忆可以被处理和更改的方式相同来自感官的输入。我感兴趣的是,在我的 LISP 程序中,有一些代码会因与其他函数的交互而​​发生变化。即使这不是由 lambda 完成的,我仍然想了解它(lambda 函数),因为它似乎是 Racket 和其他 LISP 方言的重要组成部分。

使用 scheme/racket,你需要使用 set! 而不是 incf 这是一个 Lisp 函数(顺便说一句,set! 不会 return 新值,不同于 infc).

Common Lisp中的

(incf x)并不等同于Racket中的(+ x 1),而是先自增x(set! x (+ x 1)),然后返回新值的组合.

所以,如果你想在 Racket 中定义一个类似的函数,你可以这样写,例如:

(define count
  (let ((counter 0))
    (lambda () (begin (set! counter (+ counter 1)) counter))))

(count)    ; returns 1

(count)    ; returns 2