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

# ある日の某Web制作会社
ワイ「おはようございます〜」

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

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

社長「（**ええでっしゃろか？**っていうか）」
社長「（もう、**来てもうてるやん・・・**）」
社長「も、もちろんええで・・・」

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

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

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

**ドサドサッ・・・**

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

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

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

ワイ「あの、よめ太郎はん・・・？」
ワイ「**Java**と**JavaScript**は違う言語やっていうたやん・・・？」

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

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

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

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

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

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

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

# 娘ちゃんの学びたいもの
ワイ「ほな、JSの何を勉強しよか」

娘（**3歳**）「**演算子なぞなぞ**したい！」

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

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

```javascript
const a = 1 !== 0;

console.log(a);
```

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

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

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

ワイ「でへへ」
ワイ「（**演算子なぞなぞ**、なかなか楽しいやないかい・・・）」

娘「次は**論理演算子！**」

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

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

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

娘「うーん、まあ**正解でいいや！**」

ワイ「**ワーイ！**」
ワイ「（ん？なんか引っかかるけど**まあええか・・・**）」

娘「じゃあ、もう一つ**論理演算子！**」

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

console.log(a);
```

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

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

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

ワイ「**ヒィッ！！**」

ハスケル子「（**急に何・・・？**）」

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

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

ハスケル子「（わ、私？）」
ハスケル子「か、かしこまりました・・・」

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

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

ハスケル子「**ではなくて**」

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

ハスケル子「なんです」

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

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

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

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

ワイ「ほえ〜」

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

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

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

ワイ「なるほどなぁ」

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

ワイ「え、そうなん？」

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

ワイ「ほうほう」

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

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

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

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

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

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

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

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

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

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

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

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

ハスケル子「つまり」

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

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

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

ハスケル子「例えば」

```javascript
const a = 1 && 0;
```

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

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

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

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

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

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

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

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

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

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

console.log(a);
```

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

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

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

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

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

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

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

```javascript
const a = 4 && 5 && 0;
```

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

```javascript
const a = 5 && 0;
```

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

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

ハスケル子「ですね」
ハスケル子「結果的に、**全ての値が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**。