let
Clojure で使用することはめったにありません。学習を始めたとき、何らかの理由でそれが嫌いになり、それ以来使用を避けていました。let
来ると流れが止まった感じ。私は疑問に思っていましたが、それなしでできると思いますか?
6 に答える
Let にはいくつかの利点があります。まず、機能コンテキストでの値バインディングが可能です。第二に、読みやすさの利点をもたらします。したがって、技術的には (それがなくてもプログラミングできるという意味で) それをなくすことはできますが、価値のあるツールがなければ言語は貧弱になります。
let の優れた点の 1 つは、計算を指定する一般的な (数学的な) 方法を形式化するのに役立つことです。この方法では、便利なバインディングを導入し、結果として単純化された式を導入します。バインディングがその「スコープ」にのみ適用されることは明らかであり、特により機能的なプログラマーにとって、より数学的な定式化と結びついていることが役立ちます。
Haskell のような他の言語でブロックが発生するのは偶然ではありません。
(let [a1 b1 a2 b2...] ...)
の出現を置き換えることができる((fn [a1 a2 ...] ...) b1 b2 ...)
ので、そうです。私は多くの let を使用していますが、それなしではやりたくありません。
私はあなたの質問を理解していると思います。間違っている場合は修正してください。「let」は、命令型プログラミング スタイルに使用されることがあります。例えば、
... (let [x (...)
y (...x...)
z (...x...y...)
....x...y...z...] ...
このパターンは命令型言語から来ています。
... { x = ...;
y = ...x...;
...x...y...;} ...
あなたはこのスタイルを避けているので、「let」も避けていますね。
一部の問題では、命令型スタイルによりコード量が削減されます。さらに、Java や C で記述した方が効率的な場合もあります。また、場合によっては、「let」は評価順序に関係なく部分式の値を保持するだけです。例えば、
(... (let [a (...)
b (...)...]
(...a...b...a...b...) ;; still fp style
let
-bindingsには少なくとも 2 つの重要な使用例があります。
まず、let
適切に使用すると、コードがより明確で短くなります。複数回使用する式がある場合は、それを a にバインドするlet
と非常に便利です。map
を使用する標準関数の一部を次に示しますlet
。
...
(let [s1 (seq c1) s2 (seq c2)]
(when (and s1 s2)
(cons (f (first s1) (first s2))
(map f (rest s1) (rest s2)))))))
...
式を 1 回しか使用しない場合でも、意味的に意味のある名前を付けると、(後でコードを読む人にとって) 役に立ちます。
第二に、Arthur が述べたように、式の値を複数回使用したいが、一度だけ評価したい場合は、式全体を単純に 2 回入力することはできません。何らかのバインディングが必要です。純粋な式がある場合、これは単に無駄になります。
user=> (* (+ 3 2) (+ 3 2))
25
しかし、式に副作用がある場合、実際にはプログラムの意味が変わります。
user=> (* (+ 3 (do (println "hi") 2))
(+ 3 (do (println "hi") 2)))
hi
hi
25
user=> (let [x (+ 3 (do (println "hi") 2))]
(* x x))
hi
25