我发现我很少let在Clojure中使用.出于某种原因,当我开始学习并从那时起就避免使用它时,我不喜欢它.当流动时,感觉流动停止了let.我想知道,你认为我们可以完全没有它吗?
Ron*_*ell 12
让我们提供一些好处.首先,它允许在功能上下文中进行值绑定.其次,它赋予了可读性好处.因此,虽然从技术上讲,人们可以废除它(在某种意义上你仍然可以在没有它的情况下进行编程),如果没有一个有价值的工具,语言就会变得贫穷.
关于let的好处之一是它有助于形式化指定计算的通用(数学)方法,在该方法中引入方便的绑定,然后引入简化的公式.很明显,绑定仅适用于"范围",并且它与更多数学公式的结合是有用的,特别是对于更多功能的程序员.
让阻塞出现在像Haskell这样的其他语言中并不是巧合.
Cub*_*bic 12
您可以更换任何发生(let [a1 b1 a2 b2...] ...)的((fn [a1 a2 ...] ...) b1 b2 ...)所以是的,我们可以.我虽然使用了很多,但我宁愿不做它.
让我在防止宏中的多次执行方面是必不可少的:
(defmacro print-and-run [s-exp]
`(do (println "running " (quote ~s-exp) "produced " ~s-exp)
s-exp))
Run Code Online (Sandbox Code Playgroud)
会运行两次s-exp,这不是我们想要的:
(defmacro print-and-run [s-exp]
`(let [result# s-exp]
(do (println "running " (quote ~s-exp) "produced " result#)
result#))
Run Code Online (Sandbox Code Playgroud)
通过将表达式的结果绑定到名称并引用该结果两次来修复此问题.
因为宏返回的表达式将成为另一个表达式的一部分(宏是生成s表达式的函数),它们需要生成本地绑定以防止多次执行并避免符号捕获.
我想我理解你的问题.如果错了,请纠正我.有时候"let"用于命令式编程风格.例如,
... (let [x (...)
y (...x...)
z (...x...y...)
....x...y...z...] ...
Run Code Online (Sandbox Code Playgroud)
这种模式来自命令式语言:
... { x = ...;
y = ...x...;
...x...y...;} ...
Run Code Online (Sandbox Code Playgroud)
你避免这种风格,这就是为什么你也避免"让",不是吗?
在一些问题中,命令式样式减少了代码量.此外,有时用java或c写入更有效.在某些情况下,"let"只保存子表达式的值,而不管评估顺序如何.例如,
(... (let [a (...)
b (...)...]
(...a...b...a...b...) ;; still fp style
Run Code Online (Sandbox Code Playgroud)