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
我在 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
).
(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