mentally Lisp/Clojureのコードの読み方
質問
たくさんの素敵な回答をありがとうございました。1つだけ正解としてマークすることはできません
注:すでに wiki になっています
私は関数型プログラミングの初心者です。関数型プログラミングの簡単な関数、例えば数の階乗の計算などは読むことができますが、大きな関数を読むのは難しいと感じています。
その理由の一つは、関数定義内のコードの小さなブロックを把握することができないからだと思います。
( )
にマッチさせるのが難しくなってきているからです。
誰かが私にいくつかのコードの読み方を教えてくれて、いくつかのコードを素早く解読するためのヒントを教えてくれたら最高です。
注:このコードは10分凝視すれば理解できますが、これと同じコードがJavaで書かれていたら10分もかからないと思います。だから、Lispスタイルのコードに安心するためには、もっと速くやらなければならないと思うのです
注:私はこれが主観的な質問であることを知っています。そして、私はここで証明できる正しい答えを求めているわけではありません。このコードをどのように読み取るかについてのコメントだけでも歓迎しますし、非常に役に立ちます。
(defn concat
([] (lazy-seq nil))
([x] (lazy-seq x))
([x y]
(lazy-seq
(let [s (seq x)]
(if s
(if (chunked-seq? s)
(chunk-cons (chunk-first s) (concat (chunk-rest s) y))
(cons (first s) (concat (rest s) y)))
y))))
([x y & zs]
(let [cat (fn cat [xys zs]
(lazy-seq
(let [xys (seq xys)]
(if xys
(if (chunked-seq? xys)
(chunk-cons (chunk-first xys)
(cat (chunk-rest xys) zs))
(cons (first xys) (cat (rest xys) zs)))
(when zs
(cat (first zs) (next zs)))))))]
(cat (concat x y) zs))))
どのように解決するのですか?
Lispのコードは、特に、規則的な構文のため、他の関数型言語よりもさらに読みにくいです。Wojciechは意味理解を向上させるための良い答えを与えてくれます。構文に関するヘルプはこちらです。
まず、コードを読むときに、括弧を気にしないでください。インデントを気にしてください。一般的なルールは、同じインデントレベルにあるものは関連しているということです。ですから
(if (chunked-seq? s)
(chunk-cons (chunk-first s) (concat (chunk-rest s) y))
(cons (first s) (concat (rest s) y)))
次に、1行にすべてを収められない場合は、次の行を少しインデントしてください。これは ほとんど は常にスペース2つです。
(defn concat
([] (lazy-seq nil)) ; these two fit
([x] (lazy-seq x)) ; so no wrapping
([x y] ; but here
(lazy-seq ; (lazy-seq indents two spaces
(let [s (seq x)] ; as does (let [s (seq x)]
第三に、関数への複数の引数が一行に収まらない場合、最初の開始括弧の下に第二、第三などの引数を並べます。多くのマクロは、重要な部分が最初に表示されるようにするためのバリエーションを持つ同様のルールを持っています。
; fits on one line
(chunk-cons (chunk-first s) (concat (chunk-rest s) y))
; has to wrap: line up (cat ...) underneath first ( of (chunk-first xys)
(chunk-cons (chunk-first xys)
(cat (chunk-rest xys) zs))
; if you write a C-for macro, put the first three arguments on one line
; then the rest indented two spaces
(c-for (i 0) (< i 100) (add1 i)
(side-effects!)
(side-effects!)
(get-your (side-effects!) here))
これらのルールは、コード内のブロックを見つけるのに役立ちます。
(chunk-cons (chunk-first s)
括弧を数えないでください 次の行を確認してください。
(chunk-cons (chunk-first s)
(concat (chunk-rest s) y))
次の行がその下にインデントされているので、最初の行が完全な式でないことがわかります。
もし
defn concat
を上から見た場合、同じレベルに3つのものがあるので、3つのブロックがあることがわかります。しかし、3行目以下はその下にインデントされているので、残りはその3番目のブロックに属しています。
Schemeのスタイルガイドはこちらです。 . Clojureは知りませんが、他のLispはどれもあまり変わらないので、ほとんどのルールは同じはずです。
関連
-
[解決済み】ClojureでWebアプリケーションを作るには?[クローズド]
-
[解決済み] REPLでclojureファイルを再読み込みする方法
-
[解決済み] Clojure CoreやContribでZip関数に相当するものはありますか?
-
[解決済み] Clojure、Scheme/Racket、Common Lispの違いは何ですか?
-
[解決済み] clojureのキーワードを文字列に変換するには?
-
[解決済み] Lisp-1とLisp-2の違いは何ですか?
-
[解決済み] Clojureのフューチャーとプロミスはどう違うのか?
-
[解決済み] ベクトル中のある項目のインデックスを見つけるにはどうすればよいですか?
-
[解決済み] 関数型プログラミングはWeb制作に適しているか?[クローズド]
-
Clojure - 名前付き引数
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] clojureの "let "の例を理解しようとすること
-
[解決済み] REPLでclojureファイルを再読み込みする方法
-
[解決済み] 実社会で活躍するLisp【クローズド
-
[解決済み] clojureプロトコルの簡単な説明
-
[解決済み] ClojureでStringを数値に変換するにはどうしたらいいですか?
-
[解決済み] Clojureのブロックコメント
-
[解決済み] Clojureで遅延シーケンスを非遅延シーケンスに変換する方法
-
[解決済み] Clojureでは、リストタイプを変換する簡単な方法はありますか?
-
[解決済み] 関数型プログラミングはWeb制作に適しているか?[クローズド]
-
[解決済み] コマンドラインインターフェースでClojureアプリを作る?