「プログラマー脳」のchapter4「複雑なコードの読み方」

# 目次
[1.初めに](#1-初めに)
[2.プログラミングの認知負荷](#2-プログラミングの認知負荷)
[3.リファクタリング](#3-リファクタリング)
[4.状態遷移表](#4-状態遷移表)
[5.【プログラマー脳】Chapter](#5-プログラマー脳chapter)


# 1. 初めに
「プログラマー脳」という本を読んでいます。
その中で印象に残ったことや大事だなと思う部分をまとめています。
自分の理解の必要に応じて自分が慣れているJavaScriptで処理を書いています。

# 2. プログラミングの認知負荷

脳のワーキングメモリが処理できる限界を超えた場合に認知負荷が高くなります。
複雑なコードを読むことで認知負荷が発生して脳の中でコードを適切に処理できなくなる。

コードを処理するのが難しく、メモを取ったり、１ステップずつ追いかけたりする必要があった場合は、高い認知負荷がかかっている可能性がある。

- 課題内在性負荷
    - コード固有の複雑さによって生じる
    - 事前の知識の有無によっては解きにくい問題であるが、問題を変えようとするとこれ以上単純化することができない。
    - 例. ピタゴラスの定理を知っていれば容易に解くことができる、三角形の残りの1辺を求める問題
- 課題外在性負荷
    - コードを書いた人と読む人の知識のギャップによって生じる
    - 例. 上記の例の２辺が定義されているaとbの変数をa=8,b=6のように頭の中でつなぎ合わせる必要がある

認知負荷の例

全てのユーザーをfor文またはfor of 分を用いてlog出力する関数`showUserByFor`と`showUserByForOf`を用意しました。

```typescript
const users = [
  {name:'taro', age:12},
  {name:'hana', age:10},
  {name:'ziro', age:22}
]

const showUserByFor = () => {
  for (let i = 0; i < users.length; i++) {
    console.log(user[i])
  }
}
showUserByFor()

const showUserByForOf = () => {
  for (const user of users) {
    console.log(user)
  }
}
showUserByForOf()
```

全てのユーザーをlog出力するという要件はどちらのメソッドも満たしていますが、`showUserByFor`と`showUserByForOf`のどちらが読みやすいコードになるでしょうか？

答えは読み手が持っている知識よって異なります。

`showUserByFor`のメソッドで行われる処理に慣れている人は`showUserByForOf`を理解するため課題外在性負荷はそれに慣れている人に比べてずっと大きくなるはずです。

【個人的な感想】コードのチャンク化ができれば、何を行いたいのかを瞬時に理解できる気がします。


# 3. リファクタリング

**リファクタリング**は課題外在性負荷を軽減する方法の1つ

- コードを書き換えて事前知識との整合性を高める

リファクタリングされてた保守性の高いコードが必ずしも読みやすいコードであるとは限らない

- 関数や定数がさまざまなファイルから呼び出されているプログラムは読みやすいコードと言えるのか？
    - 切り出された関数や定数を検索したり見つけ出すことがワーキングメモリに負荷をかける

- ラムダ式や三項演算子のような省略する手段がときには課題外在性負荷を与える
    - 省略前のコードに戻すことで負荷を減らす(悪い状態にリファクタリングするという考え方)

# 4. 状態遷移表

複雑な計算処理が行われているコードを読み解くのに役立つ手段として変数の中間値を記録した状態依存グラフや状態遷移表を作成すると良い

- 複雑な構造を持つコードがワーキングメモリに負荷をかけるパターン
    - コードのどの部分を読むべきかわからない
        - 必要以上にコードを読む必要が発生
            - ワーキングメモリが処理しきれない
    - 同時に2つのことを行おうとしてしまう
        - コードの理解とコードの構造を理解して読み進めるか決めること
            - コードを読む中で処理内容を知らないメソッドの処理を見にいくかどうか
            - 
        - 5回繰り返し読んでみても理解が進まなければ、
            - どのコードに注目して、どのような順序で読めばいいのかを理解できていない
            - 1行1行は理解できても、全体像の把握が不十分

ワーキングメモリの限界に達したときに可能な対処法が依存関係グラフ(or 状態遷移表)を作成すること

- 状態依存グラフ
    1. 全ての変数をまるで囲む
    2. 同じ、あるいは関連した変数を線でつなぐ
    3. 全てのメソッド/関数の呼び出しをまるで囲む
    4. メソッド/関数呼び出しをその定義場所と線でつなぐ
    5. クラスのインスタンスを全て丸で囲む
    6. クラス定義とそのインスタンスの間に線を引く

- 状態遷移表
    1. 全ての変数の一覧を作成
    2. 表を作り、全ての変数の列を作成
    3. コードの実行の区切りとなる部分ごとに表に行を追加
    4. コードを頭の中で実行し、各変数が持つ値を状態遷移表のそれぞれの行に記入


# 5. 【プログラマー脳】Chapter

[「プログラマー脳」のchapter1「コーディング中の混乱を紐解く」](https://qiita.com/kosuke-17/items/b64f9450ebbd99b274d5)
[「プログラマー脳」のchapter2「コードを速読する」](https://qiita.com/kosuke-17/items/645babd7445203f4734a)
[「プログラマー脳」のchapter3「プログラミング言語の文法を素早く習得する方法」](https://qiita.com/kosuke-17/items/67220ced21104ddda933)
Now →[「プログラマー脳」のchapter4「複雑なコードの読み方」](https://qiita.com/kosuke-17/items/4b1348afe3ba74d6d4de)
[「プログラマー脳」のchapter5「コードの深い理解に到達する」](https://qiita.com/kosuke-17/items/77794aa78c9b8d51a1aa)
【TODO】「プログラマー脳」のchapter6「プログラミングに関する問題をよりうまく解決するには」
【TODO】「プログラマー脳」のchapter7「思考に潜むバグ」
【TODO】「プログラマー脳」のchapter8「より良い命名を行う方法」
[「プログラマー脳」のchapter9「汚いコードとそれによる認知的負荷を避けるための2つのフレームワーク」](https://qiita.com/kosuke-17/items/e5750ba01fc742a3b142)
【TODO】「プログラマー脳」のchapter10「複雑な問題をより上手に解決するために」
【TODO】「プログラマー脳」のchapter11「コードを書くという行為」
【TODO】「プログラマー脳」のchapter12「より大きなシステムの設計と改善」
【TODO】「プログラマー脳」のchapter13「新しい開発者のオンボーディング」