671
376

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

3歳娘「いつから論理式が真偽値のみを返すと錯覚していた?」

Last updated at Posted at 2019-05-02

ある日の某Web制作会社

ワイ「おはようございます〜」

社長「ん?やめ太郎」
社長「今日は有休とるんやなかったっけ?」

ワイ「そうなんでっけど、娘ちゃんがJavaScriptを教えてほしい言うもんでっから」
ワイ「よめ太郎と娘ちゃんと一緒に来たんですわ」
ワイ「会社のPC、勉強に使ってもええでっしゃろか?」

社長「(**ええでっしゃろか?**っていうか)」
社長「(もう、来てもうてるやん・・・)」
社長「も、もちろんええで・・・」

お勉強開始

ワイ「さあ、JavaScriptのお勉強開始や」

よめ太郎「ちゃんと本も買うてあるで」

ワイ「おう、気が利くやないけ〜」

ドサドサッ・・・

オライリー
詳解 Javaプログラミング
【全巻】

ワイ「Oh... Java...」

よめ太郎「2冊で10,000円近くしたわー」
よめ太郎「でもまあ、娘ちゃんの将来のためや!」

ワイ「あの、よめ太郎はん・・・?」
ワイ「JavaJavaScriptは違う言語やっていうたやん・・・?」

よめ太郎「どっちもプログラミング言語やろ?」

ワイ「いやいや、全然ちゃうねん」
ワイ「例えるなら大切な人排泄の音くらい違うねん」

ハスケル子「(インドインドネシアとかじゃないんだ・・・)」

よめ太郎「なんやそれ」
よめ太郎「ほな、どっちが排泄の音なん」

ワイ「・・・それは・・・Javaや」
ワイ「**ジャバーーー!**いうてな(震え声

よめ太郎「どんだけお腹ユルいねん、そいつ」

ワイ「まあええわ、本なしで勉強してみよか」

娘ちゃんの学びたいもの

ワイ「ほな、JSの何を勉強しよか」

娘(3歳)「演算子なぞなぞしたい!」

ワイ「お、ええな〜!(何やそれ・・・)」
ワイ「(近ごろの幼稚園児はひらがなより先に演算子おぼえるんか・・・?)」

娘「じゃあ行くよ〜」
娘「まずは比較演算子ね!」

const a = 1 !== 0;

console.log(a);

娘「これを実行するとコンソールには何て表示される?

ワイ「ええと、イコールの右側の1 !== 0は・・・」
ワイ「10違いまっせって意味やから・・・やな」
ワイ「せやから、**trueaに代入されるな」
ワイ「コンソールに出力されるのは
true**や!」

娘「正解〜!
娘「パパ、すごーい!!」

ワイ「でへへ」
ワイ「(演算子なぞなぞ、なかなか楽しいやないかい・・・)」

娘「次は論理演算子!

if (0 || 1) {
    console.log("aaa");
} else {
    console.log("bbb");
}

娘「これは、どっちがコンソールに出力されるでしょう?」

ワイ「ええと」
ワイ「||はOR演算子やから」
ワイ「左の値右の値、どちらかがtruthy1であれば」
ワイ「OR演算の結果は**trueになるはずや」
ワイ「せやから、コンソールに出力されるのは
"aaa"**や!」

娘「うーん、まあ正解でいいや!

ワイ「ワーイ!
ワイ「(ん?なんか引っかかるけどまあええか・・・)」

娘「じゃあ、もう一つ論理演算子!

const a = 1 && 2 && 3 && 4 && 5 && 0;

console.log(a);

娘「これはどうでしょう?」

ワイ「ぬぬぬ・・・?」
ワイ「&&はAND演算子やから」
ワイ「この論理式は、ぜんぶの値がtruthyやったら**trueを返すし」
ワイ「1つでも
falsyな値があればfalseを返すはずや・・・!」
ワイ「一番右に
0があるから・・・」
ワイ「コンソールに表示されるのは
false**や!!!」

娘「false・・・?」
娘「・・・・・・」
娘「いつから論理式が真偽値のみを返すと錯覚していた?

ワイ「ヒィッ!!

ハスケル子「(急に何・・・?)」

ワイ「ふ、不正解いうこと・・・?」

娘「そうです」
娘「ハスケル子さん、説明して差し上げなさい

ハスケル子「(わ、私?)」
ハスケル子「か、かしこまりました・・・」

論理演算子の挙動

ハスケル子「JavaScriptの論理演算子の挙動についてなんですけど」
ハスケル子「たとえばOR演算子は」

左右の値どちらかがtruthyなら、**true**を返す。

ハスケル子「ではなくて

左側がtruthyな場合は左側の値を返す。
逆に、左側がfalsyな場合は右側の値を返す。

ハスケル子「なんです」

ワイ「え?trueかfalseを返すんちゃうの?」

ハスケル子「はい」
ハスケル子「左または右の値そのものを返すんです」
ハスケル子「なので、例えば」

const a = 0 || "こんにちは";

ハスケル子「この場合、**aにはtrueとかじゃなくて」
ハスケル子「
"こんにちは"**が代入されるんです」

ワイ「ほえ〜」

ハスケル子「結果として、if文等のカッコの中では**"こんにちは"が評価されて、trueの扱い**になります」

ワイ「なるほどな〜」
ワイ「論理演算子を使うと自動的に**truefalse**に変身するのかと思うてたわ」

ハスケル子「そう思いがちなんですが、実際には論理演算によって真偽値に変換されるのではなくて
ハスケル子「論理演算によって返された値が、if文等の**()の中に入ると真偽値に型変換**されるんです」

ワイ「なるほどなぁ」

ハスケル子「左側がtruthyだった場合は、左側の値を返す」
ハスケル子「その場合、右側の内容はチェックすらされません

ワイ「え、そうなん?」

ハスケル子「はい」
ハスケル子「この、右側の評価を行わないことを短絡評価またはショートサーキット評価と言うんです」

ワイ「ほうほう」

ハスケル子「短絡評価を利用すると、パフォーマンスのいいコードを書けたりもするんですよ?」
ハスケル子「例えば・・・」

const a = lightFunction() || heavyFunction();

ワイ「なるほど」
ワイ「まず軽い処理を実行して、その結果がfalsyな場合のみ、右側の重い処理を実行する、いうことやな?」

ハスケル子「そういうことです」

ワイ「でも、両方の値をちゃんとチェックせんでも大丈夫なん?」
ワイ「if文とかの条件として正しく機能するん・・・?」

ハスケル子「左側がtruthyな時点で」
ハスケル子「左 OR 右のどちらかがtruthy、という条件は満たされるので」
ハスケル子「右側をチェックしなくても条件として問題ありません」

ワイ「ああ・・・言われてみれば、せやな」

ハスケル子「ほかにも、こんな書き方もよく見かけますよね」

const name = user.name || "名無しさん";

ワイ「ああ、なんかワイも見たことあるわ」
ワイ「ユーザーの名前が存在すれば、その名前を代入するし」
ワイ「存在しなければ取り敢えず**"名無しさん"**を代入しとく、いうやつやな」
ワイ「if文とか使わずスッキリ書けるな」

ハスケル子「はい」
ハスケル子「そして、肝心のAND演算子の挙動ですが・・・」
ハスケル子「OR演算子です」

ワイ「逆と言いますと・・・」

ハスケル子「つまり」

左側がfalsyな場合は左側の値を返す。
逆に、左側がtruthyな場合は右側の値を返す。

ハスケル子「っていうことなんです」

ワイ「ほえ〜」
ワイ「よう分からんけど、具体的にはどんな感じ?」

ハスケル子「例えば」

const a = 1 && 0;

ハスケル子「この場合は**aには0**が代入されます」

ワイ「ええと」
ワイ「左側の値が**1で、truthyやから」
ワイ「右側の
0a**に代入される、と」

ハスケル子「そういうことです」
ハスケル子「ちなみにAND演算子の場合は、左側がfalsyな場合に右側の評価が省略されます

ワイ「さっきの短絡評価いうやつやね」
ワイ「そこもOR演算子いうことか」

ハスケル子「はい」
ハスケル子「左側の値がfalsyであれば、その時点で」
ハスケル子「左 AND 右が両方truthyという条件は成り立たないので」
ハスケル子「右側の値を評価するまでもなく左側のfalsyな値を返します」

ワイ「その場合、if文的には**false**扱いか」

ハスケル子「はい」
ハスケル子「そして左側の値がtruthyな場合には、右側の値を返します」

ワイ「そうすると、左も右もtruthyであれば」
ワイ「右側のtruthyな値が返されて、if文的には**true扱い**」
ワイ「左側がtruthy右側がfalsyの場合にも右側の値が返されて」
ワイ「その場合、右側の値はfalsyやから」
ワイ「if文的には**false扱い**いうことか」

ハスケル子「はい」
ハスケル子「ルール的には凄くシンプルなんですけど」
ハスケル子「最初はちょっとややこしく感じますよね」
ハスケル子「そしてようやく、さっきの娘ちゃんの問題に戻ります」

const a = 1 && 2 && 3 && 4 && 5 && 0;

console.log(a);

ハスケル子「まず一番左端の**1 && 2が評価されます」
ハスケル子「左右ともに
truthyなので右側の2**が返されます」
ハスケル子「なので、式全体は↓こうなるイメージですね」

const a = 2 && 3 && 4 && 5 && 0;

ワイ「左端にあった**1 && 2が、2**に変身したんやな」

ハスケル子「そういうことです」
ハスケル子「そして今度は」
ハスケル子「次に左端になった**2 && 3が評価されて3**になります」

const a = 3 && 4 && 5 && 0;

ワイ「左右ともtruthyの場合は、右側の値になるんやもんな」
ワイ「なるほどな〜」

ハスケル子「次は**3 && 4が評価されて4**になるので」

const a = 4 && 5 && 0;

ハスケル子「↑こうです」
ハスケル子「最終的には」

const a = 5 && 0;

ハスケル子「**5 && 0**が評価されて・・・どうなりますか?」

ワイ「ええと、左側の**5truthyやから、右側の0a**に代入されることになるわ!」

ハスケル子「ですね」
ハスケル子「結果的に、全ての値がtruthyなら、一番右のtruthyな値が返されて」
ハスケル子「if文的には**true扱い**になりますし」

ワイ「ほうほう」

ハスケル子「逆に、1つでもfalsyな値があれば、そのfalsyな値が返されるので」
ハスケル子「if文的には**false扱い**になるんです」

ワイ「ほぉ〜」
ワイ「そんな仕組みやったんやね」
ワイ「娘ちゃんとケル子ちゃんのおかげで今日も勉強なったわ・・・!」

社長「(結局、娘ちゃんやなくてやめ太郎が勉強してるやん・・・)」

そんなこんなで帰る時間

ワイ「ところで・・・」
ワイ「このオライリーの分厚いJava本(×2)どないしよ・・・」
ワイ「10,000円近くも払うてもうて・・・」

よめ太郎「メ、メルカリで8,000円で売ったらええやろ!」

ワイ「メルカリ勢がオライリーのJava本買うか?」

よめ太郎「誰か1人くらいJAVA TEAと勘違いして買うやろ」

ワイ「どこに8,000円のJAVA TEAがあんねん」

よめ太郎「120本入りいうことにしけば、誰か勘違いしてくれるんちゃうか?」

ワイ「もうそれ勘違いというか」
ワイ「騙しに行ってるやん

よめ太郎「なんや、文句ばかり言うて!」

娘「ママ、また怒っちゃったの〜?

ワイ「(娘ちゃん、アカン・・・)」

よめ太郎「何やて!?

ワイ「いやいや、声を荒げたらアカンて」
ワイ「まだ会社内なんやから」
ワイ「一応空気を読んで・・・」

娘「空気をよめ太郎!
娘「キャハハハ!」

よめ太郎「」

何かが切れる音がした

よめ太郎「やめさしてもらうわ!」

ワイ「ああ・・・」
ワイ「1人で帰ってもうた・・・」

残された娘ちゃんとワイ

ワイ「はあ・・・またよめ太郎とモメてもうた・・・」

娘「それでいいんだよ」
娘「たまにはケンカしたっていい」
娘「何度もぶつかり合って、少しずつ」
娘「互いに合う形に変わって行くんだよ」

ワイ「娘ちゃん・・・!」
ワイ「ほんまその通りやな・・・」
ワイ「でもな・・・」
ワイ「今日のは君のせいやないかい!

〜おしまい〜

  1. truthy: 真偽値に変換された場合に**trueとみなされる値のこと。falseとみなされる値はfalsy**。

671
376
12

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
671
376

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?