より良いプログラミングのための英語: 初級編

# 動機

これまでの自分の失敗だったり、レビューの中で感じたり、
書籍などで読んだ知識のまとめと共有。
特に書籍（リーダブルコードやクリーンコード）は「英語圏」の色合いが強いと感じたので、
もう少しその手前の「英語」を解説したいと思います。

サンプルはすべてPHPで書いていきます。

---

# Who are you

中・高で3年、帰国して高校卒業後に日本の大学を中退してのイギリスの大学で3年、
30歳の時にワーキングホリデーと、合計で7年半ほどイギリスに住んでました。

なので、多少は英語が分かる（つもり）。
でもそんなに友達も多くなく、英語力は在英歴ほどではない模様。

---

# 大前提

ちょっとだけ耳の痛い（かもしれない）大前提です。

- コードは英語である
- コードは文章である
- つまりコードは英語の文章である

---

## コードは英語である

コードは**英語**です。
これはもう、プログラミング言語の成り立ちとしてどうしようも無いことです。

腹を括りましょう。

## コードは文章である

コードは**文章**です。
特に人間が理解しやすい高級言語においては、**人が人に伝えるもの**です。

動けばいい、という考えを捨てましょう。

---

## つまりコードは英語の文章である

とどのつまり、プログラミングは究極的には
**英語で文章を書いて伝える**という作業だと思います。

というと、「英語できない、苦手」という声が聞こえてきそうですが、**甘えるな**！

なにも英語で卒論や長編小説を書くわけではないのです。
飽くまで「プログラミングとして処理を伝える」ための英語です。
"I have a pen. I have an apple." が言えれば大丈夫。

---

# 前置き

これから先の話は、飽くまで「すべてが上手くできている理想郷」の話です。
言語仕様、プロジェクトの制約、時間、工数、その他諸々による妥協はあると思います。
そういった外部制約に合わせる柔軟性も大事です。

とはいえ、「こうあるべき」という理想を理解しておくのは大事じゃないかと思います。

あと、個人の感覚も大きいので、
「*英語話すやつはみんなこう感じてるんだ*」
とまで言うつもりはないです。

---

# 文法

「英語の文法の話をします」
というと、一気に嫌がる顔が目に浮かびます。

学生時代に無理やり覚えた*SVO*だとか*SVC*だとか
*現在完了形*、*過去完了形*とかのせいかもしれません。

そこまでは覚えなくて大丈夫ですが、
これから紹介するものを頭に入れておくと良いでしょう。

---

## 名詞

広く「名称」を表します。主にクラス名や変数名に使われます。

### 単数形・複数形

1つの場合は**単数形**、2つ以上なら**複数形**。

日本語だと`ユーザー`という単語が単数か複数か気にしませんが、
英語では `user` と `users` には大きな違いがあります。

```php
function handle(array $user) {
    foreach($user as $u) { ... }
}
```

とかに（無理やり）なってると、「ん？？」となります。

---

では例えば、要素の数を数える場合はどうでしょう？
`$count` とするのか、`$counts`とするのか。

ちょっと分かりづらいですが、名前から受け取る印象は以下みたいな感じです。

```php
$count = 10; // カウントされた数
$counts = [
    'apple' => 10,
    'banana' => 15,
    'orange' => 20
]; // カウントされた数の集合
```

---

では、プロジェクトの命名規則で、複数の場合は`List`でなければいけないとしたら？
`$userList`でしょうか？`$usersList`にしますか？

言葉からイメージするものは、以下のような違いがあります。

```php
$userList = ['John', 'Paul', 'George', 'Richard']; // ユーザーのリスト
$usersList = [
    ['John', 'Paul', 'George', 'Richard'],
    ['Mick', 'Richard', 'Ronald', 'William', 'Charlie', 'Brian']
]; // 複数のユーザーのリスト
```

とはいえ、後者は`$userGroupList`みたいな名前のほうがより分かりやすいですね。
飽くまで *複数のユーザーの塊が入ってる可能性ある？* みたいな気持ちになるだけです。

---

ただし…
`of` で繋ぐときは複数形になります。

`$listOfUsers` === `$userList` です。

これは「ユーザーリスト」での「ユーザー」は
**形容詞**（赤い、美しいなどと同じ）として扱われるからです。
対して、「ユーザーのリスト」の「ユーザー」は名詞です。

詳しく解説すると以下ですが、ここまで覚えなくても大丈夫です。

| 変数名 | 文法 |
|:-:|:-:|
| `$userList` | 形容詞 + 名詞 |
| `$listOfUsers` | 名詞 + 前置詞 + 名詞 |

---

### 冠詞について

名詞といえば、定冠詞 `the` や、不定冠詞 `a`, `an` について、
学生時代に悩まされた人も多いんじゃないでしょうか。
難しいですよね。僕も未だに悩みます。

ただ、プログラミングにおいては冠詞は忘れて大丈夫です。

理由は色々ありますが、*不定冠詞 `a` がキャメルケースで見にくい*ってのもあるかなと…
`findACSVFile` `createAFileInADirectory` とか。

もし、単数形を表現するために `a` を使いたい場合があれば、
`single` とか `one` とかで代用してあげるといいかなと思います。

---

## 動詞

「動き」を表す言葉です。
「動き」といっても、「走る」「食べる」みたいな体の動きだけでなく、
「その状態になること・その状態であること」なども「動詞」に含まれます。
いわゆる**Be動詞**ってやつです。

**----2022/06/20追記----**

状態動詞ってBe動詞以外にもあるよね、とコメントいただきました。
勉強不足でした…

確かに、 `have` や `exist` なんかも状態を表す動詞ですね。

**----追記ここまで----**

ですが、基本的にはプログラミングにおいて重要なのは「動きを表す動詞」です。
主に関数に対して使われます。
シンプルなところでは `get()` や `create()`, `delete()` なんかです。

---

### 動詞の活用

動詞と言えば「活用」ですよね。
`walk` が `walked` や `walking` になったり、
`study` が `studies` や `studied` になったり、
`run` `ran` `run` だったりを
必死に覚えたと思います。

極論ですが、 **基本的** には、 **関数は現在形** と考えておけば大丈夫です。
なぜなら、プログラムは基本的に「今現在の処理」のことを伝えるからです。

**----2022/06/09追記----**

「命令形」と考えるとスッキリするのでは？とコメントいただきました。
確かに！
「オブジェクトに命令を伝えている」というのは、文法的にも違和感ないため、ベターかもしれません。

**----追記ここまで----**

「えー、でも三単現とか、現在進行形とかもあるよね？」と思うかも知れません。
はい、あります。
でも、**基本の基本は現在形** と考えてもらって差し支えないです。
それ以外は応用です。


---

## 疑問形

ものすごく平たい言い方をすると、人に何かを尋ねるときの文章の形です。

「あれはなに？」
「元気ですか？」
「これはジョンですか？」「いいえ、それはペンです」

みたいに質問する文章ですね。

"What is it?"
"How are you?"
"Is this John?" "No, it is a pen."

---

プログラミングで疑問形を使うときの基本は **YES, NOで答えられる質問にする** ということです。
つまりは、Boolean（TRUE, FALSE）ですね。

以下はよく見るパターンだと思います。
| 単語 | 意味 | 使用例 |
|:-:|:-:|:-:|
| is, are  | である | `isActive`, `areAllSuccessful` |
| can | できる | `canWrite` |
| should, must | すべき | `shouldFetch` |

---

以下は使えなくはないですが、「取得する」という風に言い換えたほうが明確になるパターンが多いと思います。
| 単語 | 使用例 | 言い換え |
|:-:|:-:|:-:|
| what  | 何色か？ | 色を取得する |
| how  | どのくらいの大きさか？ | 大きさを取得する |
| where | どこにあるか？ | パスを取得する |
| when | いつ作られたか？ | 作成日時を取得する |
| which | どの方向か？ | 方向を取得する<br>（状況によってはwhichも可かも） |
| who | （権限判定で）これは誰？ | 権限を取得する |
| why | なぜ？ | 理由を取得<br>（「なぜ」を聞く場面ある…？） |

---

### プログラミング特有な疑問形

厳密に言うと「疑問形」ってわけではないけれど…
プログラミング特有の疑問形**的な**表現というのがあります。
（これに関しては後述します。）

それは **三単現はBooleanを返す** という（暗黙の？）ルールです。

Laravelを例に取ると、[exists()](https://laravel.com/docs/9.x/queries#determining-if-records-exist)や[has()](https://laravel.com/docs/9.x/collections#method-has)なんてのがあります。

これらは*クエリの結果が存在していればTRUE*、*コレクションがキーと対になる値を持っていればTRUE* になります。
`doesExist` や `doesHave` となるのではなく、三単現にするようです。

ただし、何でもかんでも三単現でBooleanを表現できるわけではありません。
`gets()` とかだったら素直に `has` や　`exists` を使ったほうがいいです。
`runs()` であれば `isRunning` のほうが分かりやすいですね。

**----2022/06/20追記----**

以下の理解がふさわしいのではないかとコメントいただきました。
- **状態動詞であれば三単現**
- **動作動詞であれば現在形**（命令形）

こちら、目からウロコでした。
状態動詞を意識することで、三単現を使う「特殊な疑問形」が理解しやすくなりました！

**----追記ここまで----**

---

#### 閑話

---

分かりやすいから Boolean を返すものを**疑問形**と紹介しているけれど、実は疑問形なのかどうかというのは怪しいところ。

このあたりの記事でネイティブでも議論してたりする。

https://dev.to/michi/tips-on-naming-boolean-variables-cleaner-code-35ig

実は考えれば考えるほど**疑問形じゃない**です。
むしろ**断定**であり、それに対して「○か✕か」っていう答えが返ってくる、という理解のほうが的確だったりします。
ただ、その辺りは上級編で……

---

#### 閑話休題

---

### それは疑問詞じゃない

ところで、`where` とか `when` と聞いて、「え？あれも？」って思ったかもしれません。

例えばSQLは以下みたいに書きますね。

```sql
SELECT * FROM users WHERE id = 1;
```

Laravelのコレクションには [when()](https://laravel.com/docs/9.x/collections#method-when)というメソッドがあります。

```php
$collection->when($canPush, function ($collection, $value) {
    return $collection->push(4);
});
```

これらは **疑問詞ではありません。**

**接続詞** です。

---

## 接続詞

長くなるので今回は割愛。

`If`, `Where`, `Unless` みたいに、文をつなげる役割を持つ品詞です。

---

# やりがちな間違い

最後によく見る間違いを紹介して終わりたいと思います。
これを読んだ後には決してやらないでください。

---

## 疑問形をとりあえず `is` にする

**Boolean返すのは全部 is でええんや**ってなってしまうパターン。
身に覚えはありませんか？

例えば `isCheck` が TRUE の場合って、どういう意味でしょう？
「チェックした」なのか、「チェックする」なのか、「チェックできる」なのか。
流れによって意味が変わる表現は避けたほうがよいです。

| 伝えたいこと | 表記 |
|:-:|:-:|
| 現在チェックしているかどうか | `isChecking` |
| チェックしたかどうか | `isChecked` （`checked`も可） |
| チェックすべきかどうか | `shouldCheck` |
| チェックできるかどうか | `canCheck` |

---

## `I`, `My`, `Me` などを使う

特に処理の対象となるオブジェクトなどに対して
`$myList`、 `$me` や `$isMyUser` みたいな命名をしてしまったことはないでしょうか？

そういうコードを読んでいると、「**お前だれやねん**」って感じちゃうんですよね...w
特にプログラミングっていうコンテキストで考えると、
「*システムが意思を持っている…！？*」と読み取れることがあります（笑）

対象の場合は `$target` だったりを使って、
言い換えられるようにしたほうが伝わりやすくなります。

---

# まとめ

名詞、動詞などの品詞や、疑問形などの文法を正しく意識して、
「伝わりやすい」プログラミングを心がけましょう！

---

# 上級編（予定）

- 文章を作ろう
- 品詞を使って表現力を広げよう
  - 動詞の活用を使おう
  - 接続詞を使おう