This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2015-06-24
Channels
- # admin-announcements (5)
- # beginners (19)
- # boot (48)
- # cider (36)
- # clojure (116)
- # clojure-berlin (2)
- # clojure-italy (2)
- # clojure-japan (40)
- # clojure-russia (11)
- # clojure-sg (2)
- # clojure-spain (11)
- # clojurescript (53)
- # docs (2)
- # editors (14)
- # euroclojure (57)
- # events (2)
- # instaparse (11)
- # ldnclj (14)
- # onyx (2)
- # reading-clojure (4)
- # reagent (28)
(when false (bar))
みたいなコードは bar を呼び出しているとみなすのかな。ブログ記事に Weaknesses ってあるのでそこみると無理そうな気がしますね。
Clojureのコードを解析するのに、まず障壁になるのがマクロの存在で、どのシンボルがローカルな束縛を表し、どれがVarの参照になるっていうのはマクロを展開して解析していくcode walkerを書くかtools.analyzerなんかを使う必要があります。
静的解析ツールなんかでさらに問題になるのは、そうやってマクロを一旦展開しきってしまうと、マクロの展開形の中のどのシンボルが展開前のコード中のどのシンボルに対応するかが分からなくなってしまうことですね。
(when false (bar))
とかについては無理でしょうね。yagni自体は、コードから関数のコールグラフを作って、他の関数から呼び出されない関数をリストアップするのみで、フロー解析みたいなことには踏み込んでなさそうです。
まぁでも、最近Clojureのコードを解析する需要は増えてる印象で、実際今年のGSoCのプロジェクトでもそんなようなテーマで一歩走ってましたね http://dev.clojure.org/display/community/Project+Ideas#ProjectIdeas-Sourcemetadatainformationmodel
condのネストが深くなる問題、たぶんこういうコードのことを言っているのだと思うのだけど、
(cond
(= my-val 1)
(do-something1)
(= my-val 2)
(do-something2))
いくつかのオープンソースのライブラリ読むと、
(cond
(= my-val 1)
(do-something1)
(= my-val 2)
(do-something2))
みたいに書いてる例がありました。というか、最初の方の書き方でパッチを送ったら、マージ後に下の方式に書き換えられたことがあります。ネスト深い問題てどこで出たっけって思ったんですが、もしかして reader conditionals の話からきてるんですかねー http://clojurians-log.mantike.pro/clojure-japan/2015-06-18.html
いずれにしろ、
(cond [(= my-val 1)
(do-something1)]
[(= my-val 2)
(do-something2)]
…)
より見やすくなってるかというと、個人的には疑わしい気がします。ああ、私も > そういえばかなり前に出てた話題ですが、condのインデントが深くなる問題、自分は勝手に cond* という名前のマクロを書いて使ってます。ただこれを他の人もいじるコードでも使うべきかはかなり悩むところ 見て、インデントが深くなるといえばってことで書いた程度なので、もともとどの話題なのかは不明。。。
cond そのものについてならこういう話を昔、 shiro さんが書かれてますね http://practical-scheme.net/wiliki/wiliki.cgi?Lisp%3AS%E5%BC%8F%E3%81%AE%E7%90%86%E7%94%B1 > 個人的には、condは (Paul GrahamがArcで 提案しているように) 括弧をひとつ省いて、(cond 述語 式 述語 式 ...) で いいんじゃないかという気がします。式に複数の処理を書きたければbeginを使うと。
インデント位置を述語と式で揃えると、区切りがよくわからんようになるんで、結局述語のあとに空行いれて区切りを表現しなくちゃいかんのですよね。例えば
(cond
(keyword? value)
(keyword (hyphenate (name value)))
(string? value)
(if (empty? value)
value
(hyphenate (rest value) (lower-case (first value))))
:else
value)))
(cond
(keyword? value)
(keyword (hyphenate (name value)))
(string? value)
(if (empty? value)
value
(hyphenate (rest value) (lower-case (first value))))
:else
value)))
個人的には、括弧をなくしたことで
(cond [(short-test) (do-something1)]
[(loooooooooooong-test)
(do-something2)]
…)
みたいな感じに、testの式とthenの式の間に改行を入れたり入れなかったりといった書き方がしにくくなったのが不自由だなぁと思うことが多いですね