ルールズ・オブ・プログラミング
https://gyazo.com/ce50e60f913bbd708061d01970119b23
https://www.oreilly.co.jp//books/9784814400416/
ルール1できるだけ単純であるべきだが、単純化してはいけない
アインシュタインの言葉
実際は、違うが格言っぽくなったようだ
単純さの計測
書かれているコードが短いのは単純である傾向がおおいし、持ち込んでいる概念の数が少ないといい
新しい考え方や新しい用語を持ち込まないのが単純なコード
説明するのに時間がかからない
再帰<メモ化<動的計画法の順番に高速に処理することがある
ただこれだけでは解き方に対するアプローチだけで問題の解決には至っていない
指数関数的に増えると数字が最大を超えたとき当然オーバーフローする
自前でこういう対処をするコードを書いてもいいけどそれってコード増えるだけやん。問題の解決になってなくない?
最初から上限値を決めることができれば解決することもあるよね
効果的なプログラミングとは不可避な結末を遅らせること
ルール2バグは伝染する
バグ少なくていいではなく、バグが多くて面倒
ユーザーの声を信じてはいけない
ユーザからの報告や様々な声も大事だが例えばバグ報告の内容と見当違いなこともある
何ならバグを修正したら違うバグが顕在化したみたいなこともある
自動テストとかはインフラにものすごい投資しないと絶対うまいかない
すべて自動テストするなんて不可能なのでよしなに計画たてることが重要
テストしやすいコードを書くことはできる。副作用を減らすこと状態を減らすこと
呼び出す方がミスってしまうケースがほとんどなので呼び出し側をまずは疑る
そして呼び出し側を信じてはいけない
ルール3優れた名前こそ最高のドキュメント
名前に意味はない
少し補足するとその名前をつけた変数や関数がどんなものなのかそしてどんな使われ方をするかには意味がある
命名からは逃れることはできない
Numerical Recipes
Cでアルゴリズム、計算を学ぶ古典的な本らしいがここで1文字変数が結構使われているみたい。。。
規則を混ぜない
統一性を大事に
どうしてもライブラリとかの規則に沿わないといいけないこともあるけど
とにかく頭を使わないように機械のように読み取れるよいうにすることが理想
ルール4一般化には3つの例がある
YAGNI
https://ja.wikipedia.org/wiki/YAGNI
機能を実装するときに実際に必要となるまで追加するな!という考え方
ルール5 最適化に関する教訓その1は、「最適化するな」
最適化をするのは難しいって言っている
幕間のパフォーマンスの最適化がまさにそう
ルール6コードレビューが役に立つ3つの理由
コードレビューはバグを未然に防ぐだけではない
知識の共有である
シニアコーダーがジュニアコーダーにレビューするのはOK
通常通り要件通りかなどの確認
シニアコーダーがシニアコーダーにレビューするのはOK
バグを発見する機会になる
ジュニアコーダーがシニアコーダーにレビューするのはOK
ここで知識が増える
ジュニアコーダーがジュニアコーダーにレビューするのはNG
仕様の把握が理解されないままレビューするのは危険
ルール7失敗が起こる場合をなくす
要するにコンパイラーなどに任せることが大切
どんなに気をつけたコードでも使用する側が間違えて使うことなんて当たり前である。
ルール8実行されないコードは動作しない
その名の通り実行されないコードがいつの間にか増えることがある
レビュー時には変更差分のあるコードしか注目しないので目に止まらないことが多い
まさにシュレディンガーの猫
観測者が箱の中を開けるまで生きているのか死んでいるのかは決まらないというパラドクス
テストでも限界がある
ルール9集約可能なコードを書け
エラトステネスの篩
コードを読む時は自然言語と同じように読む
しかし読んでいく中でわからない部分がある
そういうときは一回脇においておき最後まで理解できることがある
これは短期記憶に関係する
人間はものごとを7つプラス2ぐらいしか覚えられないことが多い
コードの断片もこの数を超えるとわからなくなる
考える量が増えることがコード1行ごとに増えていくことがある
さっきの変数はまだ使うのかな
この処理を抜け出したらどうなるんだろう
一方で減ることもある
変数がスコープから抜けて考えなくてもよくなった
いいコードとは短期記憶に収まるコードである
コードジャンプとか何回もするのしんどいよね
コードを塊で捉えることがある。そういうときコメントが有効
誰もが知っているメソッドなどを変に抽象化するのはダメ
仮にそれがパフォーマンス良くてもコードの品質をとれ!
長期記憶としてチーム全員が保持することができればやってもいい
ルール10複雑性を局所化せよ
その名の通りで条件がふえていけば複雑性が増す
なので変に抽象化することは避けたほうがよい
ルール11 2倍良くなるか?
例えばリファクタリングとかリアーキテクチャなどの例
斬新的発展派と反復的再発明派がある
斬新的発展派は問題だけをみて既存のコードを微調整する
反復的再発明派は問題と解法を一緒に考えて目の前のこと以外にもシステム全体を考えて調整する
どちらも一長一短。究極的には大惨事になりかねない場合がある
そして日々この2つの種類の人間がチームにいると中々方向性が決まらない
このときその変更をすることで2倍よくなるのかを常に考えて行動することが重要
計測と推測が必要になってくるがその修正をすると2倍よくなるのか考える
良くならない結論がでたら目先の微調整を行うようにする
ルール12 大きなチームには強い規則が必要
様々なプログラミング言語のスタイルがあるからコードの品質が悪いではなく混在しているのが悪い
なのでチームで書き方を強制することが大事
これはESLintとかBiomeでリントするのかと同じかも
ルールの変更もみんなで決めれる
過半数の投票によって決まるなど
ルール13 雪崩を起こした小石を探せ
バグの究明は大変だけど少しずつ前に戻っていくことで解決できる
いつもバグの報告にはWhy?がない
というかこれを探す作業である
特に状態に依存しているものは注意
副作用がない関数といってもその内部の関数のシンプルなミスの場合もあるので入出力は確認する
時々起きるバグなどはさらにデバッグが難しいことがある
ルール14 コードには種類が4つある
https://gyazo.com/e52f980640c82fe6e48aad22169b3eb8
やさしい問題を単純な解法で解くか
これが平凡なプログラマーと優秀なプログラマーとを見極めるポイント
偉大なプログラマーのスキル
一見難しいように見える問題でも適切な観点から検討すると実は「やさしい」問題であることを見抜けるスキル
ルール15 雑草は抜け
変更しても安全そうなコード(影響のないコード)は削除したり可読性をあげるために常に変更していく
放って置くと雑草みたいにどんどん無駄なコードが増えていずれプロダクトの息の根を止めることもある
仕様の変更などがあるものは雑草とは呼ばない
しかしあるコーダーからは雑草とみえてもあるコーダーから花にみえることもある
大事なのは雑草をレビューする時間をなくすこと
ESLintとか[Cspell Checkerなどで事前にコミットさせないように雑草を防ぐ
ルール16 コードから先に進むのではなく、結果から後ろ向きにたどれ
なんだろう。観点を変えて実装すると見えてくるものが違うっていうことなのだろう
JSONパーサーの例をとって解説されていたがイマイチピンと来なかった
ルール17 大きな問題ほど解決しやすいこともある
黄金分割最適化アルゴリズム
黄金分割探索
ルール18 コードに自らの物語を語らせろ
自明なコメントを書いても仕方がない
コメントが嘘をついていることもある
コードについて明白じゃない何かを読者に伝えることが重要
ルール19 作り直しは並列で行うこと
あまり印象に残らなかった
ルール20 計算をやっておけ
タイトルの通り
例えばハードリミットが決まっているものは上限値が決まっているので計算しやすい
自動化することでどれぐらい良くなるのか計算しておくことができる
ルール21 とにかく釘を打たなきゃいけないこともある
リファクタリングをしないといけなそうな箇所でも調査の結果とりあえず杭を打ってそのままにしておくことも必要かもしれない
結論
コーディング哲学を議論する時間は決して無駄ではない
チームで話し合いが必要である
どういうふうに話し合うのが良いのか気になるな。。
いつもなんとなく決めている感覚がどうしてもあるので
いつか言語化してみたい
#読書 #プログラミング #読んだ本