gallu’s blog

エンジニアでゲーマーで講師で占い師なおいちゃんのブログです。

ヨーダ記法を応援します

軽く各方面とバトりそうなネタなれど。


まず。
ヨーダ記法(ないしNTT記法…って、うちのまわりではいってたんだけど、ググるとあんまりでてこない)ですが。
これは「if等の比較演算において、左辺に定数、右辺に変数を置く」記法です。


とりあえず幾つかネットで拾ってみる。


http://uchidak.net/yoda-notation

このようにヨーダ記法とは、予期しない代入を防ぐために産み出された安全側へ倒すための書き方です。
しかしながら、現在はコンパイラがよしなにしてくれるため、あえてヨーダ記法で可読性を失うような書き方をすることをリーダブルコードでは推奨していませんでした。


http://qiita.com/moriturus/items/723eb17873381f94baf8

確かに、ヨーダ記法(1 == hogeのように記述する)は、発見しづらいミスを防ぐのに有用かもしれないが、明らかに英語として不自然である。(if 1 equals hogeよりもif hoge equals 1のほうが直感的)


http://www.tom-gs.com/weblog/27-web%E3%80%81web%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E9%96%A2%E9%80%A3/314-%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%A8%E3%82%B9%E3%82%BF%E3%83%BC%E3%82%A6%E3%82%A9%E3%83%BC%E3%82%BA%E3%83%BB%E3%83%BB%E3%83%BB%E3%82%AD%E3%83%BC%E3%83%9E%E3%83%B3%E3%81%AF%E3%83%A8%E3%83%BC%E3%83%80

ただプログラマからするとちょっと気持ち悪い。
プログラマ的には条件の対象となる値は左辺に、条件の値を右辺に書きたい。これは「Does $num equal to 1?」といった英語の文法に関わっていると思う。
ヨーダ記法だと「Does 1 equal to $num?」となる。変ではないが、「1は$numと等しいか?」とするより「$numは1と等しいか?」とするほうがわかりやすい。


http://mindia.jp/medicalcloud/%E3%83%A8%E3%83%BC%E3%83%80%E8%AA%9E

確かに、if(null==obj)...みたいな書き方はヨーダっぽいですね。意味が分かりにくいから書きたくないですが。


http://tsurujiro.blog.fc2.com/blog-entry-57.html

この記法はヨーダ記法というらしいです。この書き方なら定数に値を代入することができないため、コンパイルエラーとなります。しかし、僕はこの記法を初めて見たときには、とても奇妙な印象を受けました。おそらく、順序を逆にするとソースコードが不自然で読みにくくなるからです。


http://cloudsquare.jp/hibiki/?p=302

コンパイルでエラーになり、バグを減らすための工夫。
プログラムは文章であり、シナリオであると考える私は、嫌いな書き方なのでやらないが。


https://sanematsu.wordpress.com/2012/08/13/readable-code/

ヨーダ記法見たらリーダブルコード読んでない認定していい


http://sss.kitetu.com/F85E/A-84F5/%E3%83%A8%E3%83%BC%E3%83%80%E8%A8%98%E6%B3%95

利点は,主に代入と書き間違えたときにコンパイル エラーになること。欠点は,英語をはじめ多くの自然言語の語順に慣れた人間にとっては感覚的に不自然であること。


http://miffysora.wikidot.com/if

しかし、ヨーダ記法で書くと、読みにくくあるので、今風じゃない。


うんうん面白いなぁ。
いやまぁあえて「否定的見解ばかり」切り抜いたわけなのですが(笑
幾つかを除いて「自然じゃない」「読みにくい」としか書いてない。


いったい、先人達が「なぜ」わざわざ、ンな読みにくい書き方を「会得するに至ったのか」って背景とか、なんにも考えてないんじゃないかなぁ? としか。


んと…とりあえず、ここ。
http://under-siege.jugem.jp/?month=201311

==を=に誤ったとして、
if (obj = null) {
は、trueになり、
if (null = obj) {
コンパイルエラーになるので安全なのだけれど、不自然で読みにくいし、いまのコンパイラは警告を出してくれるので、もうやめちまおうぜ!という意見。


で、ここ。
https://gist.github.com/ajiyoshi-vg/d72b2cae129d73a405e4

貫禄のPHPは、なんの警告もつけないし、黙って実行する。いいね?

JavaPHP、および昔のCなどの環境では、残念なことに「老害」の意見には一理ある。


「自然じゃないからキモチワルイ」とかいう方々の意見はドン無視するとして。
…一回だけ書いておくと「そもそもプログラム自体、見る人がみたら自然じゃない」わけだし、「自分の感性と実利と、どっちを優先するの?」ってのもある。
別所で「プログラミングが上達するかしないかの分岐点の一つに"ルールをある程度無条件に受け入れられるかどうか"っていう適正のはかり方がある」的な話を読んだ記憶があるのも、なんか色々とうなずけたりする。


で、本題。
文脈的に「コンパイラなどが警告を出してくれる」環境においては、ヨーダ記法は「メリットが失われている」し、その状態で「より多くの人が"読みやすい"と感じる記法 vs "読みにくい"と感じる記法」なら、当然ながら、読みやすい方がいい。
ちなみに「左辺値に定数」がそんなに読みにくいのか? と聞かれると正直おいちゃんは「別に?」としか思わないんだけど、こんだけ多くの人が「感情的に騒いでる」んだから、きっと「多くの人達にとっては読みにくいんだろうなぁ」と思う訳なので、特にそこに対して反論はなし。別に「右辺に定数だと読みにくい」って訳でもないし。


ただ、残念なことにおいちゃんが扱っているのはPHPだ。
if内で代入が「出来る」し、正直「それを一つのテクニックとして使う事もある」ような状態だ。
なので、気をつけないと「代入が、間違いなのか意図しているのか」が、判断しにくい状況だってあるのだ。
例えば、こーゆー構文で「判定式で代入使う」ケースを、PHPerなら、見たことがあると思う。

while($row = $res->fetch(PDO::FETCH_ASSOC)){
  なんか、処理;
}


なので。
ヨーダ記法には、正直「十分なメリットが存在する」のだ。PHPの場合。
で…実際、PHPの界隈においても「ヨーダ記法は時代遅れの老害テクニックだ」とか騒ぐ連中がいる。


ふと思い返すと…


例えば「global変数」で同じような話をきく。
「地獄を実体験している」と「global変数とその使用者、死すべし!」となるわけなんだけど、その辺の実感がないと「便利でいいぢゃん」とか言い出す。


例えば「動的な型」で同じような話をきく。
そも、一度、マシン語やってからC言語にいってみたまへ。型という概念がどれだけ恩恵にして福音であるかが、身に染みると思うっていうかおいちゃんは身に染みている。
あんど、2a問題( http://d.hatena.ne.jp/gallu/20061108/p1 )も参照のこと。比較演算子は === であって、== ではないのだ!(あえての断言)
あと、戻り値が「状況によって型が違う」とかやめてマジで orz
# 久々の(?)PHP disり発言(笑


個人的には最近、この方角で「関数切りすぎ問題」に割とちょいちょい出くわすので、それは別に改めて書いてみたい。
メリットが見えきれない(0たぁ言わんが、そのメリットを使っていないんならそれは0だ)上に、メンテがしにくい。


まぁ…別に「老害だなんだ」騒ぐのはいいんだけど。
それで痛い目にあって泣いた後に「同じ事が言えるのかねぇ?」とか、量的にはそれなりの経験をもつ(んだと思う多分)おいちゃんは、思ってみたり思い返してみたり思い出してみたりする。


多分、定期的にヨーダ記法の話は出てきそうだなぁ、と思ったので、よいタイミングなんで、メモり。


追伸
………Javaコンパイルエラーになるって信じてたのに orz