質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

コーディング規約

コーディング規約とは、コードの書き方についての決め事のことです。 文法のことではなく、そのチームなどの中の約束事としてどのような書き方で行うかを定めるもの。 項目の例として、関数や変数の命名規則、コーディングのスタイル、括弧やインデントの書き方などが挙げられます。

Q&A

解決済

18回答

22839閲覧

ヨーダ記法は本当に不要なのか?

raccy

総合スコア21737

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

コーディング規約

コーディング規約とは、コードの書き方についての決め事のことです。 文法のことではなく、そのチームなどの中の約束事としてどのような書き方で行うかを定めるもの。 項目の例として、関数や変数の命名規則、コーディングのスタイル、括弧やインデントの書き方などが挙げられます。

11グッド

11クリップ

投稿2017/02/01 13:11

編集2017/02/02 11:52

11

11

プログラミングのコード記法のひとつにヨーダ記法と言う物があります。定数を前に持ってくることで、代入になるような記述ミスやヌルポ発生を防ぐという物です。

C

1if (42 == val) { 2 // ... 3}

もし、42 = valと記述ミスをしても、コンパイルエラーになるため、そのミスを防ぐことができます。

Java

1if ("42".equals(str)) { 2 // ... 3}

もし、strがnullであったとしても、NullPointerExceptionが発生せずに、falseとなるだけです。

しかし、この記法は「SVO」ではなく「OVS」になるため、一般的な言語として考えたときのコードとしては違和感が強く、わかりにくいとされています。

さて、このヨーダ記法について、わかりにくいとか、生理的に受け付けないとか、嫌いだとか、主観的な意見を__求めてはいません__。私が求めるのは本当にこの記法が必要なのかという事です。

ほとんどのコンパイラでは、適切なオプションが付いていれば、if (val = 42) {...}のような記述に対して警告を発します。また、優れたエディタで適切なlinterを使用していれば、コンパイルすることも無く、おかしな書き方をしていることを警告してくれるでしょう。言語によっては、代入が値を返さない、if文の条件式は真偽値しか受けてつけない、などの動きとすることで防止する物もあります。

しかし、JavaのNullPointerEcextion防止については、そのような防止をしてくれるわけではありません。かといって、毎回次のように書くことも冗長だと思われます。

Java

1if (str != null && str.equals("42")) { 2 // ... 3}

そもそもnull安全では無いJavaを使うのが悪いというもっともな意見もあるかと思いますが、このように言語や使いどころによってはヨーダ記法は未だに有用では無いのでは無いかと思っています。

上記のJavaのNullPointerEcextion防止のように、適当な回避策が無いため、ヨーダ記法が有用になる場面は他にあるのでしょうか?それとも、Javaの書き方も実は他に良い回避策があって、ヨーダ記法が有用になる場面など既に存在しないと言えたりするのでしょうか?ヨーダ記法を使うべきか、使うのであれば、どの言語のどのようなときなのかを教えていただきたいと思います。


この質問は、c - ヨーダスタイルについて - スタック・オーバーフローを見かけて、回答を書こうとしたときの疑問からです。該当の質問は主観的とされて閉じられていますが、ヨーダ記法の是非は問うべきとして、今回の質問をしました。なお、私自身の回答は「代入演算子に=を使うのが悪い」という斜め下の結論になったため、投稿はしていません。

naoyan, i50, catsforepaw, T_sa, hitsujimeeee, s8_chu, fullmated, windsky, x_x, ikuwow, 他1名👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答18

0

ベストアンサー

本質の回答にはなりませんが、Java7からObjects.equalsというメソッドが登場したので、nullチェックせず同値判定できるようになりました。

投稿2017/02/01 13:34

swordone

総合スコア20669

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

raccy

2017/02/01 13:41

おお、ということは、Javaもすでにヨーダ記法は要らないと言うことですね。やはり、忘れ去られる過去の遺物と化すと言うことでしょうか…。
swordone

2017/02/05 07:49

こんなのがベストアンサーでいいんですかい、raccyさん。
raccy

2017/02/05 08:19

swordoneさんの回答が一番早かったですし、聞きたかったJavaでもヨーダ記法を使わない安全な方法あるよって教えて貰ったので!
swordone

2017/03/03 07:35 編集

補足しますと、Javaでも徐々にnullセーフ、あるいはnullフリーの思想が出てきています。ここで出したObjectsクラスはnullに対してObjectクラスのメソッドが使えるかのようなメソッドがあったり、値がないかもしれないコンテナOptionalというクラスもあります。
guest

0

こんにちは。

ツールのできが悪い時やツールに頼らないケースでは有用と思います。
Visual Studioは警告レベル4でないと警告してくれませんが、4にすると未使用パラメータなども警告してきてたいへんウザいです。そして、デフォルトは3のようです。このようなケースでは警告レベルを4にするよりヨーダ記法を使う人もいるのではないかと思います。

C++はifの条件式で変数宣言を書けます。ここに書くことでその変数のスコープをif文内に限定できます。
条件判定に使った結果をthen節やelse節でも使いたい場合もそこそこあるので便利です。(実はclangのソースを読んでいる時に初めてこの使い方を見て衝撃でした。)
それとひと目で判別したい場合にもヨーダ記法は有用だろうと思います。

といいつつ、私自身はどうも馴染めないのでヨーダ記法は使わないですけどね。

私自身の回答は「代入演算子に=を使うのが悪い」

なるほど。PASCALなら:=だから良いですね。
C言語が:=を選択していれば不幸になるプログラマがそこそこ減ったでしょう。

投稿2017/02/01 14:35

編集2017/02/01 14:43
Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

raccy

2017/02/01 22:27

警告レベル上げるとウザいはよくわかります!ただ、いまは慣れてしまいました。ちゃんと書く時は、たとえウザくても、未使用パラメータ警告等を外さない方がいいのではと最近は思っています。 ifの中で代入はよく使います。ただ、ちゃんと戻り値の意味のチェックを考えると int *p; if ((p = (int *)malloc(...)) != NULL) {...普通処理...} then {...エラー処理...} みたいな書き方の方の方がいいかなと思っています。 ちょっと調べたところ、BCPLまでは`:=`だったようですが、B言語から`=`になったようです。それがそのままC言語に受け継がれ、そして他の言語にも受け継がれていったのかと…。
Chironian

2017/02/02 03:07

> int *p; > if ((p = (int *)malloc(...)) != NULL) {...普通処理...} then {...エラー処理...} は > int *p = (int *)malloc(...); > if (p != NULL) {...普通処理...} then {...エラー処理...} の方が良いような気もします。 ところで、↓の使い方なら、インデントを深くしないでpのスコープを制限出来るのでありがたいですよ。 > if (int* p = (int *)malloc(...)) {...普通処理...} then {...エラー処理...} ↓は残念ながらコンパイル・エラーになります。式の中に変数宣言を書けないので。 > if ((int* p = (int *)malloc(...)) != NULL) {...普通処理...} then {...エラー処理...}
guest

0

既に解決済みではありますが、結構深く考察されている記事を見つけたので、後から参照する方の為にリンクしておきます。

エラー防止のためだけに敢えて採用する必要も無いけれど、コーディングスタイルについて考察する上では面白いテーマかもしれません。

ヨーダ記法とは 〜定数を左辺に記述するメリットと流行らない理由〜
ヨーダ記法のススメ ─ 比較対象を左辺に記述するメリット

いずれも同じ方の書かれた記事です。

投稿2017/02/07 04:18

pi-chan

総合スコア5936

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

raccy

2017/02/07 10:26

とても面白かったです。何が、よりも、何をするのかが重要というのは言い得て妙だなと思いました。なんとなくですが、オブジェクト指向の無い関数型言語の書き方に近いような気がします(最初に動詞が来るのが正しいのだ!)。
guest

0

直接質問への回答となるものではありませんが、Basic系の言語では、代入はであるとして、式中の代入自体を不可能とすることで、両者を=で表現してある例がありました。

※ Basicのシンタックスハイライトがないようです ' 上の文は下の文の短縮形 a = 1 Let a = 1 ' 代入以外の文脈では、= 1つで比較として扱われる If a = b Then ' 略 End

VB.NETではどうなっているのかと思ったら、やはり代入も比較も=のままでした。ということで、a = b = cは、他言語のような「abcを代入する」のではなく、「b = cの比較結果をaに代入する」となります。

投稿2017/02/01 14:25

maisumakun

総合スコア145930

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2017/02/01 14:35

あと、Rubyには「===」という演算子がありますが、オーバーロードできる都合上左辺の側で動作が変わるので、「正規表現 === 文字列」や「クラス === インスタンス」のような、ヨーダ記法的な書き方でないと動きません。 もっとも、Rubyで===を直接使うこと自体、コーディングスタイルとして疑問符は付きます。
raccy

2017/02/01 22:15

そういえば、VBの`=`は場所によって意味が違うと言う物でしたね。とあるVB.NET批判の記事(VB.NET使うならC#を使えという趣旨のもの)でも、この`=`は酷評されてました。ある意味、ヨーダ記法を使わなくても済む方法だと思ってますが、VBを使いたくなくなることの一つだったと覚えています。 Rubyの`===`はcase-when文が内部でお世話になるメソッドですが、たしかに、直接使う事ってない気がします。単独なら`=~`や`is_a?`使いますし。
guest

0

a == 0の形には、単にそういう慣習が多いという以上の積極的な理由はないと思います。

当初、この定数を後に書く形が好まれたのは、演算命令の後にオペランドが置かれるという、機械語やニーモニックからの類推によるのでしょう。仮にコンピュータというものが最初からスタックマシンとして構想されていたら、定数を先に書くほうが一般的になっていたかもしれませんよね。

私は、言語の構文規則で許されていることであれば、基本的にやっていいと思っています。ここまで前置き。


定数との比較では、比較される定数の値が重要なことが多いので、定数を前にすることはよくやります。後ろに回すと比較対象の違いが見つけにくいです。

大小関係や範囲の比較のとき、32 < c && c < 128128 <= cのようなのは頻繁に使います。不等号の向きがそろうようにしておけば、条件を追加・除外・反転させるときも、間違いが起きにくいです。

投稿2017/02/02 03:25

編集2017/02/02 03:33
ikedas

総合スコア4443

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ikedas

2017/02/02 03:26

英語の語順に沿っているほうがいい (これは質問者さんの主張というわけではないようですが) というのは、一種の都市伝説だと思います。多くのプログラミング言語の構文規則は、なにか特定の自然言語の語順に沿ってはいません。 そもそも、すべてがオブジェクトであるような言語の場合、そのうちのどれが主語〔サブジェクト〕であるかを問題にするのは言語の仕様外のことですし。
raccy

2017/02/02 11:50

私が欲しいのは、ヨーダ記法を採用しない積極的理由では無くて、ヨーダ記法を採用する積極的理由なのですが…。どちらも理由無しなら、理由無しでいいかと思っています。主観的な感情論で語れば、結論は出ないと思っています。 話がずれてしまいますが、プログラミング言語は自然言語に近い方が良いと個人的に思っています。私自身が、神言語であるはずのLispをあまり触らずに、Rubyばっかり触っている所為で洗脳されただけなのかもしれませんが。
ikedas

2017/02/02 12:19

私が最初に書いたのは、*非*ヨーダ記法が優れているという証拠はないと思う、ということです。 脱線ついで。自然言語に近いプログラミング言語って、無理なんじゃないかと個人的には思っています。自然言語は、意味論の源泉が「話者の世界認識」という定義不可能なものなので。
raccy

2017/02/02 13:18 編集

つまりikedasさんは 1. 非ヨーダ記法が優れている 2. ヨーダ記法が優れている 3. 優劣はつけられない のどれなのでしょうか? 2.であれば、是非、その理由を教えて欲しいと言うだけです。1.や3.であるなら、別にそういったことは聞いてなかったので、ikedasさんが勝手に聞いてないことを答えているだけのような気がします。
raccy

2017/02/02 13:22

あと、不等号を揃えるかどうかはまた別の話だと思っています。不等号を揃えることもヨーダ記法と言うのであれば、どこかでそう言っているような資料があれば教えて欲しいです。(といっても、ヨーダ記法の文献があやしいWikipediaぐらいしか私も持ち合わせていないんですが)
ikedas

2017/02/02 15:30

私としては、それっぽい記法についてこういう利点があると示したまでです。ヨーダ・非ヨーダのどちらかが優れていて他方は劣るとかは考えたことがないです。 不等号の例がその名前で呼ばれているかどうかは私も知りません。でも、この手のジャーゴンというのは確定的な定義はないと思いますから、多少の解釈のぶれは認めてもらえればと思います。
raccy

2017/02/02 21:29

等号の話では特に優劣なんてないですが、不等号の話になると定数が前や後ろになるというよりも、記号の向きを揃えることは有用という事ですね。 私自身は、主観的な感情論を除けば、ヨーダ記法が優れていると思っていていました。しかし、ツールが揃えばそうでも無いと言うことがわかって、そしたら、Javaの所為で大逆転されて、なら、ヨーダ記法は結局いいもんなのか?というのが質問の趣旨です。そこにヨーダ記法ではない書き方のほうが優れているわけでは無いと言われても、うーん、何?と思ってしまった次第でした。
guest

0

あの忌々しい書き方はヨーダ記法というのですね。初めて知りました。
あれが有用な場面など想像がつきませんが、イコールならまだ良いです。たまに不等号でも定数を左にしているのを見かけますが、混乱するのでやめていただきたいと思います。経験の浅い人がヨーダ記法を見て定数は左に書くものだと誤解したのでしょうか……。

投稿2017/02/01 14:54

catsforepaw

総合スコア5944

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Chironian

2017/02/01 15:16

こんにちは。 > たまに不等号でも定数を左にしているのを見かけますが、混乱する そのような考え方もあるのですね。 私は左から右へ大きくなるのが好みなので、下限値が定数の場合、左に定数が来てしまいます。
catsforepaw

2017/02/01 15:30

> 私は左から右へ大きくなるのが好みなので、 大なり(>)は使わないという方針なのですね。変数が書かれている位置で大小を判断するというのが私にはしっくりこないのですが、理系の人にとってはその方が自然とかあるのでしょうか。
Chironian

2017/02/01 15:54

大なりを使わないと言う方針を持っているわけではないですが、結果として大なりはあまり使わないですね。 if ((100 <= x) && (x < 200)) や if ((x < 100) || (200 <= x)) は私にとってイメージしやすいです。 if ((x >= 100) && (x < 200)) や if ((x < 100) || (x >= 200)) を読み取るのは苦労します。 理系かどうかではなく「向き」についての適用力の問題っぽい気がします。カーナビの地図は進行方向を上にする人なのですよ。
catsforepaw

2017/02/01 16:21

> if ((100 <= x) && (x < 200)) や if ((x < 100) || (200 <= x)) は私にとってイメージしやすいです。 ああ、変数の「範囲」を判定したいときのその書き方なら理解できます。そうではなくて、`if(100 > x)`のような書き方だと混乱するのです(「xが100より小さい場合」と読み取るのにワンテンポ遅れる感じ)。 > if ((x >= 100) && (x < 200)) や if ((x < 100) || (x >= 200)) 自分で書くときはこのように書きます。頭の中で条件を読みながらコードを書くとこうなってしまいますね。 ちなみに、私の車にはカーナビは搭載していないのですが、スマホとかで歩きながら地図を見るときは常に北を上にしてます。たぶんカーナビを搭載したとしてもそうすると思います。進行方向に合わせて動かすとかえって方向が判らなくなってしまうのです。
Chironian

2017/02/01 18:56 編集

if(100 > x) は私も好きではないです。 でも、if(100 <= x) が好みです。 そして、if(100 == x)より、if(x == 100)の方がしっくりします。 私の優先順位は①小さい方が左、②主語が左ということになりそうです。 私は地図上で自分がどっち向いているのか直ぐには分からない人なので、自分から見た向きを固定したいのですよ、きっと。 raccyさん。好き嫌いの話をしてしまって、ごめんなさいね。
raccy

2017/02/01 22:33

いえいえ、感情論で話をするとスタック・オーバーフローでは閉じられてしまいますが、ここはteratailですので、主観的だろうがいいのではと個人的には思っています。 不等号はあまり考えていませんでした。Pythonなんかだと`100 <= x < 200`と書けたりするのですが、初心者にはこの方がわかりやすいのかも知れません。
guest

0

古くからヨーダ記法を慣習として定着させているプロジェクトであり、かつそれが大規模であれば、ヨーダ記法が効力を発揮すると思います。大きなプロジェクトは様々な関係者が習慣や慣れを最適化の指針にしているケースが多く、その慣れを撤廃するのが工程ロスを誘発しかねないからです。
言い換えると、記法の差というより習慣の差として顕現しやすい話であり、バグ総数や可読性に対してヨーダ記法は定量的な改善効果をもたらす話では無いと私は考えています。

投稿2017/02/01 14:10

nebi

総合スコア14

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

raccy

2017/02/01 21:40

ヨーダ記法そのものについてはそれほど効果が無く、習慣としてですか…。結局、あってもなくてもさほど変わらない感じでしょうか…。
guest

0

有用な場面は特に思いつきませんが、「変数が定数と一致する」というよりも「定数と変数が一致する」という考え方の方が私にはしっくり来ます。

投稿2017/02/01 14:04

yona

総合スコア18155

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

raccy

2017/02/01 14:07

Ruby脳な人間には`42 == val`が`42.==(val)`に見えるのが困ったところなのです。もう、私は毒されていて戻れません。
guest

0

代入に = を使うのが悪いというのは私もプログラミングを始めた頃に思いました。
A = A + 1 というイコールでないものをイコールで繋ぐ表現を大変気持ち悪く思ったことです。
日常的に馴染みのある = の使い方とプログラミングでの使い方の乖離がそもそもバグの原因となっていそうです。

本題ですが、自分の使っているツールがいつも使えるとは限らないので、ツールに関わらず間違いを少しでも減らす可能性があるなら使って悪い理由はないと思います。

また同様に使わない人を責める理由もないと思います。

特定の言語の使用時に於いてヨーダ記法を使うべき、使うべきでない、存在すべき、存在すべきでない、という議論は無意味に感じます。どちらにも決定的な材料はありません。

ただ、バグを減らす一助となるならその議論が警鐘を鳴らす役割はあるのかも知れません。

投稿2017/02/01 13:44

編集2017/02/01 13:50
Zuishin

総合スコア28662

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

raccy

2017/02/01 13:57

つまり「ツールを使えない状況があり得る場合は有用」と言うことでしょうか?逆に言うと、ツールが揃っていない環境でプログラミングをすることがあり得ないような場合、たとえば、継続的インテグレーション等で常にチェックする、決められた開発環境で行う、等が開発の規約として組み込まれているとかだと、有用性は消えると言うことでいいのでしょうか? 質問の言い方が悪かったのかも知れませんが、使うべき云々…というよりも、ヨーダ記法を使うことが有用な場面が未だに存在するのかというのが疑問だったのです。
guest

0

1 == a は a == 1 より読みにくい というのは
私にはよくわかりません。対称な式なのに。

英語の

a equals to 1 は 1 equals to a と同じ意味でやはり対称。

どちらも SVCで CVS と順が転倒するわけでは有りません。

比較対象の左が変数でないと読みにくくなるというのはぴんとこないです。

1 < a && a < 10 は普通ですよね。

有用性ですが、今まで何度も助けられたので、有用だと思います。
ツールで判定できるのは環境次第ですし代入を意図的に行うことも有ります。
コンパイルエラーで弾けるのは有用だと思います。

投稿2017/02/07 12:22

tknakamuri

総合スコア62

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

raccy

2017/02/07 12:47

感覚論で話をすると結論が出ないので、そういう所は「そう思う人がいる」程度で知っていて貰ったらと思います。 ツールが使えない場合は…結構出している人がいて、tknakamuriさんもそういった所が有用で役に立ったとのことですが、ツールが使えなかったとは一体どんな環境だったのでしょうか?差し支えなければ、教えて欲しいです。
tknakamuri

2017/02/07 14:14

ifやwhileの中の代入は検出しても、三項演算の先頭とか、 兎に角論理式が必要とされるところにうっかり代入書いて 検出されないケースは言語によっては結構あったと記憶してます。 それと、プロジェクトが大きくて、ビルド系をおいそれと 触れないケースかな。 警告レベル上げると警告の洪水になってしまって、 ソースのクリーンナップの許可も時間もとれないケース というのも有ります。 うろ覚えで申し訳ない。
tknakamuri

2017/02/07 22:35

蛇足ですが、逆にツールで yodaを強制された経験も あります。 Javaでー件。phpでは数件かな。 phpではコーディング標準として、yoda はかなり 一般的なようですね。
guest

0

正解がなさそうで難しい議題ですね。

最近の言語だったり、
古い言語でもメジャーバージョンアップで改良されつつあります。

もうすでにswordoneさんが回答されていますが、
Java7より同値判定できるメソッドが用意されました。

Java7以前では回避する方法として、
ヨーダ記法(という名前は初めてしりました)は回避策の一つとして、
有用でした。

ご存知だと思いますが、
HaskellやRustなどの関数型言語の大半は、
デフォルトでイミュータブルになっていると同時に、
仕様により、一昨日来やがれと言われるのでヨーダ記法ができません。

Rust

1fn main() { 2 const X: i32 = 1; 3 4 if X = 1 { 5 println!("X: {}", X); 6 } 7}

Elixirは代入+マッチという仕様になっていたりしますが、
コンパイルエラーとなります。

Elixir

1defmodule Yoda do 2 @teisu 1 3 4 if @teisu = 1 do 5 IO.inspect @teisu 6 end 7end

<<<使えないのです>>>

私も人のこと言えませんが、
現在所属している現場の人間は「プログラミングできます!(できるとは言ってない)」
みたいな人しかおらず、
こんな私が一番知識ある人間となっています。

以前のソースを見たりすると、
ヨーダ記法もへったくれもありません。
ごっちゃごちゃです。

そういう人の為には、
ヨーダ記法とか使わない(感じさせない)ほうが良いです。

1人または、スペシャリストと開発する分にはよいかもしれませんが、
その場合はもっと良い書き方ができるでしょう。

と私個人は思います。

投稿2017/02/03 03:37

mukkun

総合スコア882

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

raccy

2017/02/03 11:58

やはりこれからはHaskellを使うべきだ…うんうん、じゃなくて、Haskellのように再代入という概念がそもそも無い言語ではヨーダ記法は無意味ですよね。こうなるとヨーダ記法が流行った(?)言語は欠陥だらけだったとも思えなくなってしまいます。
mukkun

2017/02/03 14:53

本当に面白い観点をお持ちですね〜。大好きです。 ペーペーの私が言っても説得力ありませんが、欠陥でしょうね。 私が同じような言語を作るとなったら長い年月が必要、はたまた無理かもしれません。 バグや抜けがないコードなんて人間には99%無理だと思っています。 でもそれでいいとも思っています。 欠点を補うために新しい言語が出てきて進化していきます。 多分ヨーダ記法は先人たちの回避策(知恵)なのでしょう。 回避策は策としてではなく標準化して行くのがマイナーバージョンアップだとも思っています。 時代の移り変わりで使用するしないを判断するのが最良なのかもしれません。 また個人の意見になってしまいますが、いろいろな言語を勉強した私としては、もう休んでいいんだよと言ってあげたいです。 浅く広くなので特殊な言語によってはどうしても「できれば」必要という場合があるかも分かりませんが、「絶対に」必要という場面はないと思います。 結局のところ、人それぞれ、チームそれぞれ。なんでしょうかねぇ。
mukkun

2017/02/03 15:26

すみません。。一応修正を。 「マイナー」じゃなくて「メジャー」です。
guest

0

結論を言えばケースバイケースと私は考えています。これは、コーディングの際に何を優先するのかによると言い換えていただいて問題ありません。
私はコーディングの際、特に以下のことを気をつけています。

  • 読みやすいこと
  • 改修が容易であること
  • ミスをし辛い書き方であること
  • 高速に動作すること

「読みやすいこと」とは、コーディングがコメント文の代わりになるような、センテンスなものであることを指しています。raccyさんが記載されている通り、ヨーダ記法は慣れていないと文章に起こしにくく、この部分を優先する必要がある、特にロジック周りの箇所でこの記載は受け入れられづらいものです。


「改修が容易であること」とは、読みやすさと混同されがちですが、”同様の記法を1つの機能セットで統一できる”ことを指しています。ヨーダ記法では関係が薄いので省略しますが、ユーティリティをプロジェクトで統一する / しない理由になったりします。


「ミスをし辛い書き方であること」とは、raccyさんが記載されている通りのことです。NullPointerExceptionなどを避けたい場合に有用ですね。ただし、他の方も軽く記載していますがNull値のまま処理が進んでいくことはリスクのある事です。Javaなどでは”Null”と文字列で出てしまいますから(笑)(いや、これが結構よくあって笑い事では済まないんですけどね・・・)
私の場合はNull値に四則演算が発生しない場合にヨーダ記法を用いることがあります。


「高速に動作すること」とはそのままの意味ですが、これがヨーダ記法が用いられる最大の理由ではないかと私は考えています。
私がシステム全体から呼び出されるユーティリティメソッドなどを作る際にはほぼこの記法で記載しています。呼び出される回数が尋常では無いメソッドでは、1つの条件文が大きなパフォーマンス低下を呼びます。今のCPUは良くわからないのですが、昔Z80というCPUの命令セットでは判定に7、条件分岐に10クロックを必要としました。おそらく今もそう変わらないはずですし、パフォーマンス結果にも現れています。


色々書きましたが、人間側から離れるほどヨーダ記法はより優れた記法になると私は考えています。前置記法、中置記法、後置記法などと同じでしょう。
高機能なコンパイラはこれらの優劣を大分緩和してくれるようになりました。人間が努力するのではなく、コンパイラ側で対応するのがより良いという思想ですね。これは一般的なプログラマーはヨーダ記法を避けるべきとも思えますが、結局根本の部分ではこの記法、または別の「一般的」に使われない記法で高速化している機構があるはずで、つまりはこの記法は要らなくならないということです。

大分見かける機会が増えましたが、ワークフローをマウス操作で作れるようになっているサービスがあります。(「テーブルのカラム名」「次の文字列に一致」「テスト」のようなものです)
これがより一般的となれば、コーディング部分を書くことが「古い記法」となる未来があるかも知れません。でもそのときでも裏側はコーディングで支えられていて、記法自体が不要とはならないだろうと思います。

見返してみると冗長ですね。質問の回答になっていれば幸いです。

投稿2017/02/02 14:21

windsky

総合スコア12

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

raccy

2017/02/02 21:50

「ミスをし辛い書き方であること」を採用するにしても、なんでもヨーダ記法にすることが必ずしも有用とは限らないと言うことですか…。無条件で全て適用すると、エラーにすべき所もエラーにならず、逆に危ないのかも知れません。 「高速に動作すること」ですが、C/C++なんかだとコンパイラが頑張ってくれるので同じコードになると思っていますし、他言語でもさほど変わらないような気がします。実際に差が出るような言語と例がもしあったら、例示してくれると助かります。
guest

0

わかりきった回答かもしませんが、プログラミングをはじめて間もない人にとっては有用ではないでしょうか。
サンプルコードなどを見よう見真似で書いている内はタイピングミスも多く、バグが起こったらそれがどこで発生しているのかがわからないものだと思いますので、そうした混乱を多少は防げると思います。

また、記事を書く側も対象者がそうであれば、サンプルコードを記述する際、あえてそのようにしても良いかとも思います。(といっても自分もあまりしませんが・・・)

それなりに意義を持って生み出された手法ですから、今をもっても必要とされると考えます。
一方、古き時代の産物にすがらず、今ある望ましい形に慣れることも必要だとは思います。

投稿2017/02/02 03:21

rrryutaro

総合スコア146

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

raccy

2017/02/02 11:40

初心者に、警告見ろとか、linter使えとか、最初からいきなり要求するのは確かに厳しいかもしれません。そういうときにバグが起きにくい記法と言うことでは有用と言ってもいいですね。
guest

0

個別言語のタグが付いてないので、言語に依らない話だとすると、「わかりやすさを犠牲にして、トリッキーに書けば短く書けるよ」ということの一例だと思うので、それを有用と思うかどうかと言う価値観の問題ではないでしょうか?

例に挙げておられるJavaの例についても、strがnullの時に例外でなくif条件を偽にしたいのであればif (str != null && str.equals("42"))と書けば良いだけの話で、短く書く事を有用と思うかどうかはやはり価値観(主観)の問題でしかないと思います。

投稿2017/02/01 14:20

otn

総合スコア85766

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

raccy

2017/02/01 22:04

なるほどー。Javaは色々と冗長な書き方を強制する言語だと思っていますが、他言語に比べて冗長に見えるだけで、読みやすさ、わかりやすさで言えば、そう書いておくべきなのかも知れませんね。
guest

0

代入記号は数学における等号の意味ではありません。ここまでは共通事項だと思います。ですが、以下の記述には賛成できません。

この記法は「SVO」ではなく「OVS」になるため、一般的な言語として考えたときのコードとしては違和感が強く、わかりにくいとされています。

数学のおける等号や、プログラミングにおける関係演算子「==」は対称性をもちます。また、「状態」を意味するものであるので、英文法で例えるならば「SVC」型の文型と考えることが自然と思います。一方、「動作」を意味する代入演算の場合の方が「SVO」型であり、非対称性を持つことにも妥当性があると思います。

投稿2017/02/01 14:11

HogeAnimalLover

総合スコア4830

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

swordone

2017/02/01 14:18

OVSと言ってるのはequalsの件なのですが…。
raccy

2017/02/01 21:55

違和感の話は「そう言われている」という類いの物で、そこは人によりけりなので、議論しても無駄かと思っています。いわば、「下記の式を満たすxを求めよ」という問題に対して「42 = x」と答えるようなものかと。 「SVO」なのか「SVC」なのかはわりとどうでもいいと思っています。ただ、私は`==`をメソッドとして捉えるため、「SVO」という表現を使いました。
guest

0

JavaScriptも仲間に入れていいんでしょうか。

phpや他の代入後の値をbooleanとして型変換できるスクリプト言語はありますが、
開発ルールとしてわかりやすさを優先することはできます。
ですがサーバで読み出しブラウザで実行するJavaScript(Node.jsやNashornを除くような)は
通信量を削減するために余計な文を削るインセンティブがあり、
わかりやすさを犠牲にする理由が残ります。

JSで検査内容が検査先より左に来る例外を一つあげると、RegExpがあると思います。
if (/^[0-9A-F]+$/.test(username))... のようなケースで、
usernameがnullやundefinedになり得るなら、
if (username!=null&&username.match(/^[0-9A-F]+$/))...
としないといけませんが、長くなります。
if ((username+"").match(/^[0-9A-F]+$/))... としてもまだ最初より長いです。

また定数ではないですが、if(a=func())... のようなコードが、
代入と評価を同時に行うことを目的として
a=func();if(a)... のかわりとして使用されることがあるので
これを if(func()==a) として書くことで
代入を意図していないことがはっきりするでしょう。

JSはJavaやCのように実行前にコンパイルをするのではなく、
異なる開発元が提供するクライアントの実行環境に、
副作用のある他のライブラリとともにロードされてから初めて
必要な機能が揃っているかどうかがわかります。

汎用的なライブラリを作成する時などは Object.is() があることを仮定できず
Javaよりも深刻なのではないでしょうか。
Cの場合はマクロを組んでしまえば長いコードを短縮することもできます。

投稿2017/12/20 03:30

TakeoSaki

総合スコア97

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

raccy

2017/12/20 12:02

JavaScriptについてはUglifyJSのようなツールを使って最適化と圧縮をすべきであると考えています。ソースコードの時点で可能な限り短く書くというのは、保守の観点から見てもあまり良い方法とは思えません。第一、コード量から見ると、&&や?:を使った方が少なくなりますので、そもそもif文を使わないとなるような気がします。
TakeoSaki

2017/12/20 12:41

レスどうもです。 そうですね。圧縮ツールが使えるなら使ったほうがいいですね。 ただ第三者にスクリプトをツールとして提供するときは、変数が実行時まで予測できず、予期しない内容がセットされているかもしれず、消去法で潰すしかないときがあります。 まあ可変なものをあえて右に後置することで、人が読めるレベルの文の削減をして、変更の意図がないことを示すのはさほど悪いアイデアではないと思います。これは別に推奨しているわけではなく、そういうアプローチを否定はしないというレベルです。 個人的には代入と比較を同時に行うコードはあまり行儀がいいとは思いません。
guest

0

Javaに限ると。
strにnullがありえるなら短いコードで書け、テストの際の全網羅分岐確認も少なくて済む。
(null時にエラーとしない前提)
私は好きなので使ってますが、使ってた人は1人しか知らないので、多数決で不要。

投稿2017/02/02 00:34

tantanegg

総合スコア213

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

raccy

2017/02/02 11:37

Javaでnullの場合と言っていますが、質問文であげているJavaの例と何か違うのでしょうか?具体的なコード例を教えてくれませんか?
tantanegg

2017/02/03 00:17

違いません。同じです。その例のJavaの場合のことを挙げました。 Cで挙げている書き方は行っていませんでしたので、回答は避け、Javaの場合のことを挙げました。 そもそもヨーダ記法という概念を知りませんでした。 Cで挙げている書き方も取り込もうかなと思案しています。
guest

0

この書き方、名前があったんですね。
始めてみた時、混乱して全然理解出来なかったのを覚えています。

回答から全く離れていきますが、「代入演算子に=を使うのが悪い」に非常に共感を覚えたので、どうしてもコメント残したくて書き込んでしまいました^^;
いろいろスッキリしました。

投稿2017/02/01 14:16

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

raccy

2017/02/01 22:01

私もスタック・オーバーフローの質問で初めて名前を知りました。どこかのコーディングスタイルか何かで書いてあって、あるのは知っていて、これは便利だと一時期使おうとしたこともあったのですが、警告はいてくれるしーってことで、いつの間にか使わなくなりました。 代入演算子の件は暇なときにでもQiitaにポエムろうと思います。
退会済みユーザー

退会済みユーザー

2017/02/01 22:07

あ、警告はくんだw ポエム待ってます。荒れないかなぁ。荒れると面白そうなんだけどw
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問