在Clojure中我相当于I ++

Enr*_*que 12 clojure

我是Clojure的新手.

是否有在Clojure中增加变量的快捷方式?

在许多语言中,这将起作用:

i++;
i += 1;
Run Code Online (Sandbox Code Playgroud)

在Clojure中,我可以这样做:

(def i 1)    
(def i (+ i 1))
Run Code Online (Sandbox Code Playgroud)

这是在Clojure中增加绑定的正确方法吗?

有快捷方式吗?

Kin*_*aro 17

您可以编写(inc i)增加整数或长整数.

(def i 1)
(def i+1 (inc i))
Run Code Online (Sandbox Code Playgroud)

如果您需要分配(inc i)i自己,那么请告诉您为什么要这样做.在大多数情况下,clojure中会有更优雅(或惯用)的解决方案.

  • 它只是一个变量名.'+'在clojure中没有特殊含义. (4认同)

Ham*_*aya 11

你可以使用一个原子并交换它的值,


(let [i (atom 0)]
  (println @i)
  (swap! i inc)
  (println @i))

会给你

0
1
Run Code Online (Sandbox Code Playgroud)


lur*_*her 5

你不能i在clojure或任何其他lisp中分配一个新值,因为它很重要.i在当前上下文中将具有一个且仅有一个值.(inc i)返回一个新值,该值可能会或可能不会绑定到新的局部变量.

这就是为什么在lisp语言中尾递归优化如此重要的原因; 因为模拟循环的唯一方法是使用递归,在每次函数调用时索引都有一个新值.尾递归优化通过转换平坦的旧循环中的递归来避免人们用一个非常长的循环来耗尽堆栈

clojure通过使用该recur函数再次调用相同的函数来保证尾递归优化.如果无法进行尾递归优化,recur则会产生编译时错误

编辑这是不可改变成语的本质.在inmutability和功能风格的编程之间有很强的联系.原因是函数式编程意味着"没有副作用的代码",或者确切地说,函数在计算中的唯一影响是通过其返回值.实现这一目标的一种方法是默认在上面的意义上使参数和变量不可变.虽然到目前为止,从其他海报中你已经意识到有很多方法可以解决这个问题,而不是依赖于clojure中的不可变性

  • 尾递归不是循环/迭代的唯一解决方案; 懒惰是另一种.`recur`是低级的; Clojure中的大部分循环需求可以通过懒惰的seqs +`doseq`,`for`,`map`,`reduce`和朋友来处理. (3认同)
  • 您可以直接在常见的lisp中更改变量的值,例如使用setq/setf/etc函数 (3认同)
  • 我认为大多数lisp方言允许可变变量,使用虚假陈述来鼓励良好行为毫无意义. (3认同)