【あるある】こんなコードは嫌だ【JavaScript】

次回作もよろしくやで！
→**[Array.mapが分からないからArray.mapもどきを作ってみた](https://qiita.com/Yametaro/items/dbc30861b912f4eacef7)**

## その1: `const`が使われていない
ワイ「さあ、今日はこのショッピングサイトのJSを修正するで」
ワイ「どれどれ、コードはどんな感じかいな」

```javascript
let totalPrice = getTotalPrice() - point;
```

ワイ「ふむふむ」
ワイ「この`point`いう変数が関係ありそうやけど、この`point`には何が入ってんのかいな」
ワイ「ええっと、`point`を定義しとる部分は」

```javascript
let point = 300;
```

ワイ「↑ここやな」
ワイ「`point`には`300`が入っとるんか」
ワイ「でも・・・」

```javascript
let point = 300;

/* ----------- */
/* 約300行の処理 */
/* ----------- */

let totalPrice = getTotalPrice() - point;
```

ワイ「`point`を定義した後に**300行ほど**のコードが挟まっとるから」
ワイ「途中で`point`の値が上書きされて**変わっとるかもしれへん**な」
ワイ「いま`point`はどんな値を参照してんねやろ・・・」
ワイ「しゃあない、途中のコード全部追ってくか・・・」

**〜2時間後〜**

ワイ「け、結局どこでも再代入してないんかい」
ワイ「**ほな`const`にしとかんかい！！！**」
ワイ「`const`なら再代入されへん事が保証されとるからな」
ワイ「間の**300行**のコードを読まんでもええわけや」

## 教訓
+ `var`や`let`より、できるだけ`const`を使うように気をつけよう
+ でも`const`を使っていてもオブジェクトのプロパティは変更できてしまうので気をつけよう

#### ハスケル子「Elmなら**デフォルトで再代入できない**ので、**気をつける必要すらない**ですよ」
ハスケル子「そもそも**再代入という概念がない**ので」

```elm
point = 300
```

ハスケル子「これだけです」
ハスケル子「`var`も`let`も`const`もないです」
ハスケル子「代入というより**定義**です」

ハスケル子「JSでいうオブジェクトみたいなのは、Elmでは**レコード**っていうんですけど」
ハスケル子「Elmでは**レコードも不変**です」
ハスケル子「**今このプロパティ[^1]はどんな値を参照してたっけ・・・？**」
ハスケル子「っていうことがありません」

ワイ「お、おう・・・」

ハスケル子「ていうか途中の処理を**300行ぜんぶ**読まなくても」
ハスケル子「`point`の中身を`console.log()`で確認すればよかったんじゃないですか？」

ワイ「それが、最近**`konsooru.Rogu()`**の調子が悪くて」
ワイ「エッラーばっかり吐くねん」

社長「（**そんだけタイポしてりゃな・・・**）」

ハスケル子「（あと**エッラー**って何）」
ハスケル子「（**唯一神**・・・？）」

## その2: JSDocと実装が違う
ワイ「次はこの関数を修正しよか」
ワイ「ん、なんか関数の上にコメントが書いてあるで」

```javascript
/**
 * @param  {Number} price
 * @return {Number}
 */
function displayUserName (userId) {
    /* 〜処理内容〜 */
}
```

ワイ「おお、関数の使い方についてのコメントか」
ワイ「**JSDoc**いうやつやな」
ワイ「この関数は引数として`price`という数値を受け取って、戻り値も数値ですよ、ってことやな」
ワイ「こういうコメントが書いてあると、修正する側としては大助かりや」
ワイ「ありがたいこっちゃな」

ワイ「・・・ありゃ？」
ワイ「実際に関数の中身を見てみたらJSDocと**全然ちゃうやん！！！**」
ワイ「どうやら他の関数のJSDocを**コピペ**して、**編集し忘れた**っぽいで・・・」
ワイ「勘弁してや・・・」
ワイ「逆に**トラップ**になってもうとるやん・・・」

## 教訓
+ JSDocを書くのはええけど、間違えると逆にトラップ化
+ コードだけ修正してJSDocが古いまま、というミスにも気をつけよう

#### ハスケル子「Elmなら**型注釈**がJSDocの代わりになりますよ」

```elm
displayUserName : Int -> String
displayUserName userId =
    -- ここに処理内容
```

ハスケル子「こんな感じです」
ハスケル子「**型注釈で書いた通り**に実装しないと**コンパイルが通らない**ので」
ハスケル子「**間違いないです**」

ワイ「お、おう・・・」

## その3: ユーザが変な値を入れると、変な表示になる
ワイ「なんやこの注文画面」
ワイ「数量を入力する部分に`ウン`て入力してみたら」
ワイ「**`数量: ウン個`**って表示されとるやないかい」

ハスケル子「（なんで試したんだろう・・・）」

ワイ「ちゃんとバリデーションが効いてない**くさい**で」
ワイ「**`ウン個`**だけに」

ハスケル子「（**何でそんなにつまんない事が思いつくんだろう・・・**）」

ワイ「お客様が見る画面に**なんてモノ**を表示させてんねん」

社長「（いや、そのお客様、**表示させに行ってるやん**）」

## 教訓
+ どんな値を入力しても変な表示にならないように、注意してブラウザテストしよう

#### ハスケル子「ElmならInt型の変数に文字列は入れられないので安心ですよ」

ワイ「でも**ユーザが文字列を入れて来たらどうすんの**」

ハスケル子「**[Maybe型](https://qiita.com/Yametaro/items/7988b7dd2728cc2b9456)**があるので、そういう**不確実な値も事前に検査**できます」

ワイ「ま、まじか・・・」

## その4: 関数ネストし過ぎ
ワイ「なんやこれ・・・」

```javascript
let displayName = suitCase(rareCase(camelCase(name)));
```

ワイ「関数が入れ子になり過ぎて可読性が・・・」
ワイ「でもこれは、しゃあないか・・・？」

```javascript
let camelCasedName = camelCase(name);
let rareCasedName = rareCase(camelCasedName);
let suitCasedName = suitCase(rareCasedName);
```

ワイ「こんな感じに書き変えるのも冗長やしなあ・・・」

## 教訓
+ 諦めよう

#### ハスケル子「Elmなら**パイプライン**でこう書けますよ」

```elm
displayName = 
    name |> camelCase |> rareCase |> suitCase
```

ワイ「おお、なんと読みやすい・・・」
ワイ「でもJSにも**[そのうち導入される可能性がある](https://qiita.com/remew/items/b35587a7c411d855dd33)**らしいで？」

ハスケル子「いきなりパイプラインだけ導入しても」
ハスケル子「関数が**[カリー化](https://qiita.com/Yametaro/items/99cc1c8ebcfc703b1410)**されてないと」
ハスケル子「あんまり使い所ないですよ」
ハスケル子「あと、あらかじめパイプラインありきで」
ハスケル子「引数の順番を考えておかないと使えないです」

ワイ「そうなんか・・・」

## でもさ・・・
ワイ「でも、そんな便利な言語だと、お値段もお高いんでしょう・・・？」

ハスケル子「実は・・・」

#### ハスケル子「なんと無料です！」

####ワイ「ええぇっ！！！」

#### ハスケル子「しかもElmはコンパイルしてJavaScriptに変換できるんです」

#### ワイ「ま、まじか・・・」

## まとめ
ワイ「ハスケル子ちゃん・・・」
ワイ「ワイも、もっと早くハスケル子ちゃんオススメの**Elm**を勉強しとけばよかったわ・・・」
ワイ「人生の選択間違えたわ・・・」
ワイ「ああ・・・また心がダークモードになってきたで・・・」

ハスケル子「あんまり完璧で眩しい人より、**ダークモードの方が目に優しいですよ**」

ワイ「ハスケル子ちゃん・・・」
ワイ「でもなんか、ワイは人間関係とかでも」
ワイ「いつも選択を間違って後悔ばかりなんや・・・」

ハスケル子「逆に選択を間違えない人っているんですか？」
ハスケル子「いつも答えが分かってて選択してる人なんて、多分いませんよ」
ハスケル子「間違ってるかもしれない選択をし続けていく」
ハスケル子「それが人生ですよ」

ワイ「ハスケル子ちゃん・・・！」

ハスケル子「今日も、明日も、やめ太郎さんに出来ることをしましょう」

ワイ「ワイにできること・・・」
ワイ「それってなんやろか・・・」

ハスケル子「・・・」
ハスケル子「**ちょっと思いつかないですけど**」

ワイ「**何もないんかい！！！**」

**〜おしまい〜**

## 追記： ビギナーにお勧めのElm記事たち
**[Elmで体験する関数型言語の面白さ](https://qiita.com/pxfnc/items/542e0f6705182a9f93ad)**
**[VS Code で Elm の開発環境を構築する on Windows 10](https://qiita.com/ossan_pg/items/5c3ce00b74036139507e)**
**[値が制約を満たしていることを型で保証する](https://qiita.com/arowM/items/0106f2b66a6a446bad38)**

## 次回作もよろしくやで
→**[Array.mapが分からないからArray.mapもどきを作ってみた](https://qiita.com/Yametaro/items/dbc30861b912f4eacef7)**

[^1]: Elmのレコードの場合は、プロパティでなく「フィールド」と呼びます。