2012-07-22 57 views
2

在常见的lisp中,我可以将多个defun放置在同一个闭包中,并让它们具有所有设置的功能。如何将此代码从常见lisp转换为clojure

(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,以便您有权访问这两个函数?

+1

你可以在LET中使用DEFUN Common Lisp,但我通常不会推荐它。 DEFUN不再是LET中的顶级表单,它在编译时有轻微的缺陷。 – 2012-07-22 02:11:30

+0

@RainerJoswig - 谢谢,我不知道。 – zellio 2012-07-22 02:16:15

回答

6

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!可以执行对原子的价值,而不仅仅是获取和设置(对+ +上面的例子)swap!

+0

+1显示习惯clojure。不同的Lisp有不同的风格... – Gert 2012-07-22 05:11:50

5

以下是您的代码的一种可能的翻译 - 可以访问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