「コーディングを支える技術」を読んだ - プログラミング言語の選び方

[コーディングを支える技術 ~成り立ちから学ぶプログラミング作法 (WEB+DB PRESS plus) | 西尾 泰和 |本 | 通販 | Amazon](https://www.amazon.co.jp/dp/477415654X) を読んだ。

![](https://images-na.ssl-images-amazon.com/images/I/51nXP3TKXVL._SX351_BO1,204,203,200_.jpg)


読みながらメモした要点と感想（筆者のポエム）です。初学者にとってプログラミング言語何を選ぶか問題とは、を考えるとともに、言語そのものの思想を知るともっと蘊蓄を語りたくなったりもっと好きになったりするよなあと思います。


## 要点

### 第1章　言語を深く効率的に学ぶには
- 比較から学ぶ
    - 決め事は言語によって異なる
        - C言語とRubyにおける真偽値
        - Javaにおける真偽値
            - [各言語におけるtrue/falseまとめ - 昼メシ物語](https://blog.mirakui.com/entry/20090604/truefalse)
- 歴史から学ぶ
    - 言語設計者の意図を理解する
    - どの言語を学ぶべきかは誰にもわからない
    - 言語に依存しない普遍的な知識を学ぶこと
### 第2章　プログラミング言語を俯瞰する
- プログラミング言語誕生の歴史
    - ケーブルをつなぐ
    - プログラム内蔵方式へ
    - そしてFORTRANの登場
- プログラミング言語の生まれた目的
    - 無精 ──プログラマの三大美徳の一つ
        - [仕事に必要なのは怠惰さ、短気さ、傲慢さ | ベイジの日報](https://baigie.me/nippo/2021/04/28/loveperl_imanishi/)
        - 言語により異なる「楽さ」の意味は異なる
        - 何を楽にしたいのか見極めること
    - どんなプログラムを書くのを楽にしたいのか考えよう
    
### 第3章　文法の誕生
- 文法って何だろう？
    - 演算子の優先順位は言語により異なる
    - 文法は言語設計者が決めたルール
- 例えば
    - スタックマシンとFORTH
    - 構文木とLISP
    - 中置記法
        - 構文解析器
- 何を作るか目的を明確にしよう
- プログラムのエラーは間違いを指摘してくれている

### 第4章　処理の流れのコントロール
- 構造化プログラミングの誕生
- ifが生まれる前
    - ifはなぜあるのか
    - if……elseはなぜあるのか
        - trueとfalseがある場合の条件分岐
- アセンブリ言語での表現方法
    - C言語での表現方法
    - if……elseを使うメリット
- while ──繰り返しのifを読みやすく表現
    - whileを使った表現方法
    - whileを使わない表現方法
        - いずれも「goto」の複雑さを解決している
        - [「有害なgoto」「時期尚早な最適化」、そしてプログラミングにまつわる神話は諸悪の根源である | POSTD](https://postd.cc/programming-myths/)
- for ──数値を増やしながらのwhileを読みやすく表現
    - forを使った表現方法
        - whileの散らばった箇所をまとめたもの

### 第5章　関数
- 関数の役割
    - **理解** ──組織のたとえ
    - **再利用** ──部品のたとえ
- 戻る命令
    - 関数の誕生で戻ることができるようになった
    - スタック
    - 再帰呼び出し
        - 入れ子構造のデータを効率的に処理


### 第6章　エラー処理
- プログラムも失敗をする
- 失敗をどうやって伝えるか
    - 返り値で失敗を伝えることが考えられる。しかし
        - 失敗を見落とす
        - エラー処理のせいでコードが読みづらい
    - なので
        - ジャンプでエラー処理をまとめる
        - 失敗したらジャンプする
- 失敗しそうなコードを囲む構文
    - John Goodenough の主張: [Catch as catch can • The Register](https://www.theregister.com/2006/01/11/exception_handling/)
    - try, catch, except, finally
- 出口を1つにしたい
    - なぜfinallyを導入したのか
    - 対になる処理を確実に行いたい
    - finallyによる解決
- どういうときに例外を投げるか
    - 関数呼び出し時に引数が不足している場合
    - 配列の範囲外を取得しようとした場合
    - 間違えたらすぐに例外を投げてほしい
        - **間違いに気付けるメリット**
- 例外の伝搬
    - 例外が伝搬する問題点
    - Javaの検査例外
    - 検査例外が普及しない理由
        - 難しいこともある。関数の出口が分かれること

### 第7章　名前とスコープ
- 名前はなぜ必要だったか
    - どうやって名前を付けるか
    - 名前の衝突
    - 衝突を回避するには
    - 長い変数名を付ける
    - スコープを利用する
- スコープの進化
    - 動的スコープ
        - 動的スコープは対応表がコード全体から読める
    - 静的スコープ
        - 静的スコープは関数ごとに対応表を分ける
- 静的スコープは完成形？
    - ネストした関数の問題
    - 外のスコープへの再束縛の問題
        - Pythonでの解決方法
        - Rubyでの解決方法

### 第8章　型
- 型とは何か
- 数値をオンとオフで表現する方法
    - 位取りの発明
    - そろばん
- 1つの位に必要なランプはいくつか？
    - 10進法から2進法ヘ
    - 8進法と16進法
        - 8進法
        - 16進法
- 実数はどうやって表現しよう
    - 固定小数点数──小数点がどこに付くか決める
    - 浮動小数点数──どこからが小数部かの情報自体を値に含める
    - どのような考え方か
    - IEEE 754で定められた浮動小数点数のしくみ
- 型は何のため？
    - 言語処理系に変数の種類を教える
    - 暗黙の型昇格
    - 整数同士，浮動小数点数同士の演算
    - 片方が整数で片方が浮動小数点数の演算
    - 書き方で区別する言語
- 型のいろいろな展開
    - ユーザ定義型とオブジェクト指向
    - 仕様としての型
    - 公開と非公開を分ける
    - インタフェースへの発展
    - 型ですべての仕様を表現する世界が来るか
    - 総称型，ジェネリクス，テンプレート
        - C++の場合
        - Javaの場合
        - Haskellの場合
    - 動的型付け
    - 型推論
        - 強い型でバグのないプログラムが作れるか
        - **「虫を早く見つけて殺す」**

### 第9章　コンテナと文字列
- なぜいろいろな種類のコンテナ（= 配列やリスト）があるのか
    - 配列と連結リスト（LinkedList）の違い
    - 配列に値を挿入する場合
        - 連結リストに値を挿入する場合
        - 連結リストの模式図
        - 連結リストの長所と短所
    - 言語による違い
- 辞書、ハッシュ、連想配列
    - ハッシュテーブル
    - 木
    - 要素を取り出す時間
        - 木の場合
        - ハッシュテーブルの場合
        - **万能のコンテナはない**
- 文字とは何か
    - 文字集合と文字符号化方式
    - コンピュータ以前の符号化
        - モールス符号
        - ボーコード
        - EDSACの文字コード
        - ASCIIとEBCDICの時代
- 日本語エンコーディング
    - ISO-2022-JP
    - Shift_JIS
    - EUC-JP
    - Unicodeによる統一
- 文字列とは何か
    - 長さの情報を持つPascal文字列，持たないC文字列
        - NUL文字で文字列の終わりを表現する
        - NUL文字にまつわる不具合の例
    - 1文字16bitのJava文字列
    - Python 3で行われた設計の変更
    - Ruby 1.9の挑戦
- 問題を実装で解決しようとするPythonやRubyのアプローチと、標準化で解決しようとするGoogleやAppleのアプローチ。

### 第10章　並行処理
- 並行処理
    - 細かく区切って実行する
- 処理を切り替える2通りの方法
    - 協調的マルチタスク──切りの良いところで交代する
    - プリエンプティブマルチタスク── 一定時間で交代する
- 競合状態を防ぐには
    - 競合状態の3条件
    - 共有しない──プロセスとアクターモデル
- プロセスではメモリを共有しない
    - 共有しないアプローチは成功したか
    - アクターモデル
    - 書き換えない──const，val，Immutable
    - 割り込まない
    - 協調的なスレッドを使う──ファイバー，コルーチン，グリーンスレッド
    - 割り込まれると困る処理中は印を付ける──ロック，ミューテックス，セマフォ
- ロックの問題点と解決策
    - デッドロックが発生してしまう
    - トランザクショナルメモリによる解決

### 第11章　オブジェクトとクラス
- オブジェクト指向とは
    - 言語によって違う「オブジェクト指向」の意味
        - オブジェクトは現実世界の模型
        - クラスとは
- 変数と関数を束ねて模型を作る方法
- 方法1　モジュール，パッケージ
    - Perlのパッケージでオブジェクトを作る
- 方法2　関数もハッシュに入れる
- 方法3　クロージャ
- 方法4　クラス
    - Hoareの考えたクラス
    - C++のクラス
    - 仕様としての役割
    - クラスが持つ3つの役割
        - まとまったものを作る生成器
        - どういう操作が可能かという仕様
        - コードを再利用する単位

### 第12章　継承によるコードの再利用
- 継承とは
    - 継承に対するさまざまな考え方
        - 一般化／特殊化
        - 共通部分の抽出
        - 差分実装
    - 継承は諸刃の剣
    - リスコフの置換原則
- 多重継承
    - 1つのモノを複数の分類に
    - 実装の再利用に便利な多重継承
- 多重継承の問題点──またしても衝突！
- 解決策1　多重継承を禁止する
- 解決策2　メソッド解決順序を工夫する
- 解決策3　処理を混ぜ込む（Mix-in）
- 解決策4　トレイト
    - 名前が衝突したときの振る舞い
    - 提供するメソッドと要求するメソッド
    - ほかにもいろいろな機能が……
    - トレイトが広まりつつある

## 感想: 言語をどうやって選ぶか

言語にまつわる話題をひとしきり読んだが、言語の好き嫌い、あるいは使う言語はどう選ぶだろうか。

### 好きなもので選ぶ

[最初に覚えるプログラミング言語は何がいいですか？ - Qiita](https://qiita.com/kaizen_nagoya/items/590704e76e287707637b)

### 大事なのは言語でなくプログラミング的思考だという説

[テキシコー | NHK for School](https://www.nhk.or.jp/school/sougou/texico/)
[「アルゴリズム図鑑」を読んだので、その要点 - Qiita](https://qiita.com/e99h2121/items/6b66cf79e01e95647a29)

### 人気のもので選ぶ

#### 総合的に人気

[プログラミング言語の人気ランキング、順位変動は縮小傾向にある――RedMonkが調査：DartがRustに並ぶ - ＠IT](https://atmarkit.itmedia.co.jp/ait/articles/2204/13/news040.html)

JavaScript、Python、Java

#### 最近人気

[2022年、バックエンドのWeb開発で学ぶべき言語は？ - Qiita](https://qiita.com/e99h2121/items/98edea4e4a462a7dcf81)

#### 長く人気

[index | TIOBE - The Software Quality Company](https://www.tiobe.com/tiobe-index/)

Python、C、Java

### やりたいことから選ぶ

https://roadmap.sh/

https://roadmap.sh/frontend


### 必要だから選ぶ

[paizaが「プログラミング言語に関する調査」（2021年上期）の結果を発表。2021年エンジニアが学びたい開発言語1位はPythonで企業が求める言語と乖離｜paizaのプレスリリース](https://prtimes.jp/main/html/rd/p/000000077.000012063.html)
[平均年収が一番高いプログラミング言語、20～40代で「R」が1位：キャリアニュース - MONOist](https://monoist.itmedia.co.jp/mn/articles/2101/14/news007.html)
[エンジニア白書2021 - Qiita](https://qiita.com/white_papers/2021)

### 理由は色々

[Java屋さんの私がPythonをはじめる理由 - Qiita](https://qiita.com/HyunwookPark/items/68d029dd33807fc69ca4)
[Pythonがプログラミング初学者に嬉しい理由 - Qiita](https://qiita.com/e99h2121/items/fc94960448cb3341f80b)
[なぜHaskellを学ぶと良いか - Qiita](https://qiita.com/arowM/items/0305d4f439752f285438)
[Node.jsとはなにか？なぜみんな使っているのか？ - Qiita](https://qiita.com/non_cal/items/a8fee0b7ad96e67713eb)
[そろそろTypeScriptに入門するから、TypeScriptとは何なのか、どう良いのか書いておく - Qiita](https://qiita.com/e99h2121/items/09892779dcb26a70bc97)

ということでポエムに近い感想文になったが言語の思想を知ると感情移入できるなという話。
以上です～