首页 文章

使用词法封闭的球拍

提问于
浏览
1

我在Let over Lambda中读到了关于lexical clojures的内容,这个代码示例是针对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方言的重要组成部分 .

2 回答

  • 0

    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
    
  • 4

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

相关问题