【问题标题】:How to translate this code from common lisp to clojure如何将此代码从 common lisp 转换为 clojure
【发布时间】:2012-07-22 01:47:17
【问题描述】:

在 common lisp 中,我可以将多个 defun 放在同一个闭包中,并让它们全部设置函数。

(let ((number 0))
  (defun get-number () number)
  (defun set-number ( arg ) (setq number arg)))

如果我在 clojure 中使用相同的语法,那么只有最后一个函数最终会被定义。

(let [ number 0 ]
  (defn get-number [] number)
  (defn set-number [ arg ] (def number arg)))

有没有办法将此代码翻译成 clojure 以便您可以访问这两个函数?

【问题讨论】:

  • 您可以在 Common Lisp 的 LET 中使用 DEFUN,但我一般不会推荐它。 DEFUN 不再是 LET 内部的顶级表单,它在编译方面略有不足。
  • @RainerJoswig - 谢谢,我不知道。

标签: clojure common-lisp


【解决方案1】:

user593508 gives a good answer 直译。

但这在 Clojure 中有点不习惯,不鼓励使用封装在副作用 setter 和 getter 函数后面的数据。 Clojure 倾向于强调纯函数,并通过托管引用显式控制状态(参见 excellent video by Rich Hickey on data structures and managed references

另一种方法是直接使用原子来存储可变数字:

(def number (atom 0))

@number
=> 0

(swap! number + 5)
=> 5

@number
=> 5

除了更简洁和更惯用的 Clojure 之外,您还可以获得 swap! 可以对原子的值执行任意函数的额外优势,而不仅仅是获取和设置(参见上面 +5 的示例)

【讨论】:

    【解决方案2】:

    这是您的代码的一种可能的翻译 - 可以访问 get-number 函数。

    (let [number (atom 0)]
      (defn get-number []
        @number)
      (defn set-number [arg]
        (reset! number arg)))
    
    (get-number) => 0
    (set-number 5)
    (get-number) => 5
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-09
      • 2018-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-14
      相关资源
      最近更新 更多