我发现自己以这种方式编写了很多 Clojure:
(defn my-fun [input]
(let [result1 (some-complicated-procedure input)
result2 (some-other-procedure result1)]
(do-something-with-results result1 result2)))
这个let
语句看起来非常……势在必行。我不喜欢。原则上,我可以像这样编写相同的函数:
(defn my-fun [input]
(do-something-with-results (some-complicated-procedure input)
(some-other-procedure (some-complicated-procedure input)))))
问题在于它涉及重新计算some-complicated-procedure
,这可能是任意昂贵的。你也可以想象 some-complicated-procedure
实际上是一系列嵌套的函数调用,然后我要么必须编写一个全新的函数,要么冒着第一次调用中的变化得不到的风险应用于第二个:
例如这行得通,但我必须有一个额外的浅层顶层函数,这使得很难进行心理堆栈跟踪:
(defn some-complicated-procedure [input] (lots (of (nested (operations input)))))
(defn my-fun [input]
(do-something-with-results (some-complicated-procedure input)
(some-other-procedure (some-complicated-procedure input)))))
例如这很危险,因为重构很难:
(defn my-fun [input]
(do-something-with-results (lots (of (nested (operations (mistake input))))) ; oops made a change here that wasn't applied to the other nested calls
(some-other-procedure (lots (of (nested (operations input))))))))
考虑到这些权衡,我觉得除了编写冗长的命令式 let
语句外,我别无选择,但当我这样做时,我无法摆脱这样一种感觉,即我不是在编写惯用的 clojure .有没有一种方法可以解决上面提出的计算和代码清洁问题和编写惯用的 clojure?命令式 let
语句是惯用的吗?
最佳答案
您描述的那种 let
语句可能会让您想起命令式代码,但它们并没有什么命令式的。 Haskell 也有类似的语句将名称绑定(bind)到主体中的值。
关于clojure - "let"的功能替代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63983468/