clojure-japan

2015-06-24T01:47:59.000590Z

面白そうですね。yagniって久しぶりに聞きました ;-)

athos 2015-06-24T01:55:37.000591Z

実装を見る感じだと、デッドコードを洗い出すっていうよりは、使われていない関数をリストアップするツールなんですかね

ayato_p 2015-06-24T04:48:03.000592Z

(when false (bar)) みたいなコードは bar を呼び出しているとみなすのかな。ブログ記事に Weaknesses ってあるのでそこみると無理そうな気がしますね。

ayato_p 2015-06-24T04:49:23.000593Z

Clojure ってこういう解析系のツール作るの難しそうというか、役に立たないケースが結構目立つ気がする

athos 2015-06-24T05:36:39.000594Z

Clojureのコードを解析するのに、まず障壁になるのがマクロの存在で、どのシンボルがローカルな束縛を表し、どれがVarの参照になるっていうのはマクロを展開して解析していくcode walkerを書くかtools.analyzerなんかを使う必要があります。

athos 2015-06-24T05:39:56.000595Z

静的解析ツールなんかでさらに問題になるのは、そうやってマクロを一旦展開しきってしまうと、マクロの展開形の中のどのシンボルが展開前のコード中のどのシンボルに対応するかが分からなくなってしまうことですね。

athos 2015-06-24T05:40:34.000596Z

なんか前にもrewrite-cljのときに似た話をしましたけど

athos 2015-06-24T05:48:25.000597Z

(when false (bar)) とかについては無理でしょうね。yagni自体は、コードから関数のコールグラフを作って、他の関数から呼び出されない関数をリストアップするのみで、フロー解析みたいなことには踏み込んでなさそうです。

ayato_p 2015-06-24T05:50:23.000599Z

似た話を僕は前にハレイクでミュータントテストの話をしたときにも聞いたような気がします(笑)

athos 2015-06-24T05:53:26.000600Z

😅

athos 2015-06-24T05:54:45.000601Z

まぁでも、最近Clojureのコードを解析する需要は増えてる印象で、実際今年のGSoCのプロジェクトでもそんなようなテーマで一歩走ってましたね http://dev.clojure.org/display/community/Project+Ideas#ProjectIdeas-Sourcemetadatainformationmodel

ayato_p 2015-06-24T06:02:20.000602Z

興味深いですねー

t_yano 2015-06-24T06:37:43.000603Z

condのネストが深くなる問題、たぶんこういうコードのことを言っているのだと思うのだけど、

(cond
  (= my-val 1)
    (do-something1)
  (= my-val 2)
    (do-something2))

t_yano 2015-06-24T06:40:18.000606Z

いくつかのオープンソースのライブラリ読むと、

(cond
  (= my-val 1)
  (do-something1)

  (= my-val 2)
  (do-something2))
みたいに書いてる例がありました。というか、最初の方の書き方でパッチを送ったら、マージ後に下の方式に書き換えられたことがあります。

ayato_p 2015-06-24T06:44:16.000607Z

最初の例の書き方って僕はあまり見たことないですね。

ayato_p 2015-06-24T06:44:42.000608Z

test/expr のペアはだいたいインデントの位置が同じになるのが普通な気がします(それか同じ行

athos 2015-06-24T06:45:51.000610Z

1つめの書き方もどこかでは見たことがありますね

ayato_p 2015-06-24T06:46:17.000611Z

そういう流派が存在するんですね

athos 2015-06-24T06:46:49.000612Z

あと

(cond
  (= my-val 1)
  ,(do-something1)
  …)
みたいにカンマをはさむスタイルもあったような

t_yano 2015-06-24T06:46:53.000613Z

まあ、(if (= my-val 1) とかで次の行でひとつネストするのと同じって考えると上みたいになる。

ayato_p 2015-06-24T06:51:10.000615Z

ネスト深い問題てどこで出たっけって思ったんですが、もしかして reader conditionals の話からきてるんですかねー http://clojurians-log.mantike.pro/clojure-japan/2015-06-18.html

athos 2015-06-24T06:51:50.000617Z

いずれにしろ、

(cond [(= my-val 1)
       (do-something1)]
      [(= my-val 2)
       (do-something2)]
      …)
より見やすくなってるかというと、個人的には疑わしい気がします。

ayato_p 2015-06-24T06:53:15.000622Z

それともこっち?

athos 2015-06-24T06:53:22.000623Z

僕も同じくcondのインデント問題が何なのか把握できてない

t_yano 2015-06-24T06:54:25.000624Z

ああ、私も > そういえばかなり前に出てた話題ですが、condのインデントが深くなる問題、自分は勝手に cond* という名前のマクロを書いて使ってます。ただこれを他の人もいじるコードでも使うべきかはかなり悩むところ 見て、インデントが深くなるといえばってことで書いた程度なので、もともとどの話題なのかは不明。。。

ayato_p 2015-06-24T06:56:37.000625Z

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を使うと。

t_yano 2015-06-24T07:02:25.000626Z

インデント位置を述語と式で揃えると、区切りがよくわからんようになるんで、結局述語のあとに空行いれて区切りを表現しなくちゃいかんのですよね。例えば

(cond
  (keyword? value)
  (keyword (hyphenate (name value)))
  (string? value)
  (if (empty? value)
    value
    (hyphenate (rest value) (lower-case (first value))))
  :else
  value)))

t_yano 2015-06-24T07:02:42.000627Z

(cond
  (keyword? value)
  (keyword (hyphenate (name value)))

  (string? value)
  (if (empty? value)
    value
    (hyphenate (rest value) (lower-case (first value))))
  
  :else
  value)))

t_yano 2015-06-24T07:03:27.000628Z

同じ行に述語と式を書かない場合、下が一般的ですかね?

t_yano 2015-06-24T07:06:25.000629Z

私は前は式をインデントしてましたけど、今は下の書き方をしてます。

athos 2015-06-24T07:06:33.000630Z

個人的には、括弧をなくしたことで

(cond [(short-test) (do-something1)]
      [(loooooooooooong-test)
       (do-something2)]
       …)
みたいな感じに、testの式とthenの式の間に改行を入れたり入れなかったりといった書き方がしにくくなったのが不自由だなぁと思うことが多いですね

athos 2015-06-24T07:09:01.000632Z

caseの場合はさらに、デフォルト節にはtest-constantが書けなくてバランスが悪い問題がありますけど、それはまだ別の話かな?

ayato_p 2015-06-24T07:14:07.000633Z

確かにどっちかに揃えないと読みにくくなりますよね

athos 2015-06-24T07:19:53.000634Z

letに対してはそこまでの不満感がないのは、letの場合は結局ローカルな名前をつけるだけなので(自分でそこまで長い名前をつけなければ)1行が長くなって改行を入れたくなるような状況が少ないことによるのかなぁという自己分析

tnoda 2015-06-24T14:22:26.000636Z

cond もそうですが extend-protocol するときにも一行空けしますね。こちらはあまり一般的ではないかも。

ayato_p 2015-06-24T23:05:25.000637Z

extend-protocol はたしかに1行空けをよく見ますね

ayato_p 2015-06-24T23:13:05.000638Z

いっそ cond くらいだったら、どうせ test/expr の対なんですから Emacs とかのエディタ支援を受けて test と expr の背景色を変えるとかしてしまってもいいのかもしれませんね(エディタがないと読めないコードとは…