Webエンジニアはそろそろ日本語変数名の利用を検討してもいいのでは？

[自ブログからの転載です](https://blog.hedrall.work/posts/jp-coding-20230308)

## 概要

言うまでもありませんが、プログラムを書く場合は英単語を利用するのが一般的であり、普段それについて疑いを持つことはほとんどないのではないかと思います。私自身、新規プロダクトを設計する際 にも「日本語で書くか？」という議論した経験はありません。
しかしながら、`DX`(Digital Transformation)や`DDD`(Domain Driven Design)の潮流を考えると、多くの場面で`単語`の持つ`細かなニュアンス`への重みが増してきていると感じます。
(ソースコードに日本語を使うことを議論すること自体、トンデモ論と憚られる様な若干の恐怖を感じつつ)
本記事では、日本語でプログラミングすることに関する周辺環境と`個人的な見解`をまとめます。

## 前提

- 想定読者 => 国内産業向けのサービス開発おいて日本人のエンジニアで構成された開発チーム
    - 平均的なメンバーはTOEIC500~700点程度の所謂英語が読めるレベルのエンジニアで構成される
- 技術スタック => Webエンジニア
    - 言語: TypeScript, HTML, CSS
    - FW: React
    - ドメイン駆動設計をベースとします

また、あくまで個人的な見解なので、意見が違う部分があれば冷静に読み飛ばして下さい。

## 何を日本語で書くべきか？

本記事で検討したいのは主に `変数名`・`関数名`・`クラス名` などを日本語に置き換えることに関してです。逆に以下の点は英語のままにした方が良いと考えています。

### 制御文

`if`, `for` などの制御文は日本語化する必要がありません。なぜなら、これらは`TypeScript`(プログラミング言語)というドメインの固有の`ユビキタス言語`と捉えられるので、`if`は他の何者でもなく(`もし`ではなく)、`if`文なのです。`なでしこ`などプログラムのドメインすら日本語にするPJはありますが、それが読みやすいと感じるか否かは個人差があります。

### システムドメインの単語 (専門用語)

プログラムより上の階層で、`システムドメイン`の用語も日本語化する必要がありません。例えば、`id => 識別子`, `トークン => 証拠`など言い直す必要はなく、`id`, `token`自体がシステムのドメインで確立した`専門用語`です。

## (圧倒的)メリット

日本語変数名を利用するメリットに関してまとめて行きます。
初めに、日本語を利用することに関する想定される想定される反論を検討しておきます。

1. 「英語でも問題を感じない」
1. 「英語の方が本来の意味を捉えていてわかりやすい」

以下でこれらに関して考察をしていきます。

### 認知コストの低下

`認知コスト`とは、認識に必要な時間や労力を指しますが、やや感覚的な面があり意外と難しい議論だと思います。

そこで、ひとまず`認知コスト = 読解スピード`として検討してみたいと思います。
[こちら](https://karikusa-gakuin.com/%E3%80%90%E9%80%9F%E8%AA%AD%E8%81%B4%E8%8B%B1%E8%AA%9Ea%E3%80%91wpm%E3%82%92%E6%B8%AC%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86/#:~:text=%E8%8B%B1%E8%AA%9E%E3%83%8D%E3%82%A4%E3%83%86%E3%82%A3%E3%83%96%E3%81%AE%E5%B9%B3%E5%9D%87%E3%81%8C,%E3%81%A8%E8%A8%80%E3%82%8F%E3%82%8C%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82&text=%E5%A4%A7%E4%BD%93%20120%EF%BD%9E150wpm%20%E3%81%8C%E5%BF%85%E8%A6%81%E3%81%A8%E8%A8%80%E3%82%8F%E3%82%8C%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82)のサイトによると、英語のネイティブスピーカーの平均が`200～250WPM`に対して、日本人の平均は`80～100WPM`前後と言われているそうです。
つまり、日本人が英語を読む速度はネイティブの`1/2倍速`がベースになります。(確かに、0.5倍速にするとリスニングもよく聞こえてくるという経験はあると思います)。この比をそのままネイティブと非ネイティブの差を考えると、日本人プログラマーにとって英語より日本語で記述されたプログラムの方が`読解速度`が`2倍`になるということになります。

また、英単語でつけられた変数名を読む時、みなさんは英単語の意味を暗黙に日本語に変換して理解していないでしょうか？例えば、`ID`や`User`はそのまま理解できますが、`Account Balance`という単語は`口座残高`と暗黙に変換して理解してないでしょうか？私たちの普段の生活にない概念なので、現実世界と紐づけるには一段変換の作業が必要になります。逆方向の変換を考えても、日本人プログラマーは最初に日本語で思考してから、コードへの落とし込みを考えた段階で英単語に変換していくと思います。このように、英単語を利用するということは、日本語と英語で`二重の知識`が要求されることになり、`認知負荷`が倍増します。

念の為に補足しますが、英語が読める？読めない？ではなく、`認知負荷`がどうか？を焦点としています。個人の`認知`には当然ながら限界があり、うまく抑制することが本当に価値があることに注力し成果に繋げるために重要であると言う点は、多くのモダンな組織論で説かれています。

以上のことから、`1. 「英語でも問題を感じない」`を思う場合は、英語を利用することで生じる`認知負荷`に気づいていない、もしくは暗黙の内に許容してしまっている可能性があります。

### ドメイン駆動設計の良い実践

`ドメイン駆動設計`は`ドメイン`にフォーカスした`設計手法`であり、`問題領域`をどれだけ適切に過不足なくうまく言い得ていくか？(つまり上手に`モデリング`すること)というのが重要な要素となります。

ここで、一般的論ですが言語は網目のようなもので、英語辞典には単語ごとに日本語訳が記載されていますが、多言語間で正確に一致する単語は`あったりなかったり`します。

そのため、`問題領域`が`国内`にあるシステムに関しては、日本語を使うことで最も正確に`モデリング`することができると考えられます。近年では国内産業を対象とする`バーティカルSaaS`や`DX系SaaS`プロダクトをコアに開発している企業が増えてきており、多くの場面で日本語でコードに落とすことの価値が得られると考えいます。
もちろん、グローバル企業や英語圏のエンジニアが多く在籍する企業では英語でコーディングする方が認知コストの総和を最小化できるため合理的です。

補足をすると、`2.「英語の方が本来の意味を捉えていてわかりやすい」` と感じる方は、「**問題領域の日本語化**」ではなく「**解決領域におけるシステム基盤固有の用語の日本語化**」に違和感を覚えているのではないでしょうか？ 先述の通り`get/fetch`, `add/update/delete`, `list/collection` などの用語は日本語に変換する必要がga薄い(case by case)と考えています。

### ドキュメンテーションの向上

日本語でプログラミングをしない理由を検索すると、

- 「エディタ上で変換がめんどくさい」
- 「記述量が増える」

などの理由が多く見られ、事実としてはその通りです。

ここで検討したいのが、そもそもエンジニアがプログラムを書く`目的`ってなんでしょうか？

エンジニアは`時間軸に沿って`適切なシステムを設計・構築・運用するロールです。成果物であるシステムはデジタル企業にとってのコアバリューとなります。そして、「進化的アーキテクチャー」などに記載がある様に、ソフトウェアは`ソフト`であることに価値があり、「DevOpsとLeanの科学」や「チームトポロジー」がいうように、システムそのものよりも高速な価値提供を実現するバリューストリームを維持する組織・チームに価値があります。
そういった潮流の中で、`ドメイン駆動設計`が注目を集めているのは、バリューストリームに参加する（ビジネスパートを含む）多くの関係者の力を借りながら、`進化的(疎結合)`なシステムをスムーズに構築していくのに上手く機能する手法であるからです。

そんな`ドメイン駆動設計`のコアな概念として、`ユビキタス言語`があります。`ユビキタス言語`は`ドメインモデル`に現れ、(ちょっと抽象的な概念ですが)`境界づけられたコンテキスト`という重要な概念を構成します。`DDD`では`問題領域`の分析から的確な`ユビキタス言語`を蒸留することが重要かつ前提的な作業になります。また、この作業はエンジニアだけでなく、ドメインエキスパートやビジネスパートとの協業となり、`ユビキタス言語`は双方の認識を一致させるためのツールとしても機能します。コーディング作業は、こうして得られた概念(`ユビキタス言語`)に沿って、`ドメインの振る舞い(ロジック)`をプログラムに落とし込む作業でるため、**(書きやすさより) 意味的な正しさや読みやすさが重要**です。

別の視点でも考えてみたいと思います。ある意味プログラムコードは「`機械が解釈可能なほど明確な仕様書`」と捉えることができます。所謂、`設計資料`は多少の飛躍や誤字脱字があっても人間の脳ミソが上手く補完してくれますが、コードは1文字でも間違えるとうまく動作しません。
コードはそれほど詳細なドキュメントであるため、すぐに複雑性が増大しいわゆるスパゲッティと呼ばれるようなカオス状態になってしまいます。そのため、数々のアーキテクチャーやコーディング原則、TypeScriptなどの(漸進的)型付言語などの力を借りて適切に構造化することで`認知負荷`の改善が図られます。このように仕様書の認知負荷を最小限に保つことに価値をおくのであれば、日本語で記述することも多くの日本人にとって効果的な認知負荷の軽減方法になるのではないでしょうか。

例えば、新規のメンバーやプロダクトオーナーに対してソースコードを共有する場面で、相手は既存のコードをすぐに理解できるでしょうか？おそらく、ドメイン固有の知識が強く求められるプロダクトほど、英語そのままでは意味を捉えることが難しく、`英語 => 日本語`の変換ステップを踏まなくてなならないために余計な認知コストを支払い、有限な脳みそというリソースを不必要に消費してしまっている可能性があります。

### 直観で理解できる

多少英語が得意なエンジニアでも、日常的に英語を利用して生活している方はごくわずかなのではないでしょうか？
プログラマーは開発をする際に、お気に入りのエディターやTerminalソフトを利用し、膨大なプラグインを投入することで**やりやすい環境**を維持しています。
つまり`認知負荷`を軽減させるために労力をかけているのにもかかわらず、そもそもの利用する`言語`に無頓着では「木を見て森をみず」な状態といえます。

### コメントにWhatを書かなくなる

コードを書く時に、最小限で的確なコメントを残すことは`可読性`の意味で重要ですが、よく「`What`を書かず`Why(Why not)`をかけ！」と言った議論があったります。では、なぜそもそも`What`を書いてしまうかというと、(あくまで1つの理由としては)周辺の説明変数や関数名などだけでコードの意図を的確に表現することができていないという点が挙げられます。つまり、一般的な日本人の英語力で複雑なロジックや`ドメイン知識`をコードという`厳密な仕様書`に落としていく作業に`一定のハードル`があります。

例えば以下のようなシチュエーションを想像してみてください。

「皆さんの作業デスクにマグカップが置いてあります。それをきき手でつかんで口に運び、グラスを傾けて中のコーヒーを啜ります。」

この一連の描写はもちろん簡単に理解ができますし、皆さんも記述することができると思います。
では、上記の描写を英語に置きかえることはできますか？

ちなみに、ChatGPTの回答は以下です。

<details>There is a mug on your work desk. Pick it up with your gripping hand and bring it to your mouth, tilting the cup and sipping the coffee inside.</details>

もちろん置き換えること自体できたと思いますが、日本語では簡単に記述できていたことが、英語で表現するのに当たってはある程度のハードルを感じるのではないでしょうか？
(そうでなければ大学の試験問題に出題されることもないはずです。)

この様に、英語で`What`を正確に記載することは普通に難しいことです。また、複雑なロジックや高度なドメイン知識を含んだりしている場合は、日本語であっても`What`の描写が難しくなります。

以上から、日本語で変数名をつけていれば`What`をより**簡単かつ的確**に表現することができ、コード内のコメントには自然と`Why`が多くなっていくと期待されます。

### PRレビューの時間を削減

レビュー時の観点の一つに変数の命名があります。既存のコードとコンテキストを照し合わせながら適切な命名をしていきます。しかし、複雑な処理を行う関数・モジュールの命名に関してしばしば英語での表現方法を議論することがあるのではないでしょうか？特に初心者エンジニアに関してはよくあることです。

## 論より証拠

日本を変数名を利用する場面やpros/consは多種多様のため、例示することに少し悩みましたが、ここでは `認知負荷` を直感的に感じていただくため `英語 => 日本語`に書き直したコードの例を示したいと思います。
テーマとしては不動産管理会社が、管理不動産の情報を入力して、DBに保存するコードです。
(コード生成と翻訳は`chatgpt`にお願いしています。)

まずは普通の英単語を利用したコード

```typescript
import mysql from 'mysql';

// MySQL接続情報
const connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: 'password',
  database: 'your_database_name',
});

// 物件情報の型定義
interface Property {
  address: string;
  owner: string;
  type: string;
  price: number;
  area: number;
  layout: string;
  age: number;
  structure: string;
  rooms: number;
  bedrooms: number;
  bathrooms: number;
  parking: boolean;
  access: string;
  condition: string;
  rentalIncome: number;
  vacancy: boolean;
  documents: string;
}

// 物件情報をMySQLに格納する関数
function addProperty(property: Property): void {
  const sql = `
    INSERT INTO properties (address, owner, type, price, area, layout, age, structure, rooms, bedrooms, bathrooms, parking, access, condition, rental_income, vacancy, documents)
    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
  `;
  const values = [
    property.address,
    property.owner,
    property.type,
    property.price,
    property.area,
    property.layout,
    property.age,
    property.structure,
    property.rooms,
    property.bedrooms,
    property.bathrooms,
    property.parking,
    property.access,
    property.condition,
    property.rentalIncome,
    property.vacancy,
    property.documents,
  ];

  connection.query(sql, values, (error, results, fields) => {
    if (error) {
      console.error('Failed to add property to database:', error);
    } else {
      console.log('Property added to database:', results);
    }
  });
}
```

どうでしょう？もちろん簡単に読めると思うのですが、ぱっと見であなたの脳ミソに染み込んできましたか？
次は日本語を活用した場合です。

**↓ 開く**

<details>

```typescript
import mysql from 'mysql';

// MySQL接続情報
const 接続情報 = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: 'password',
  database: 'your_database_name',
});

// 物件情報の型定義
interface 物件情報 {
  住所: string;
  所有者: string;
  種別: string;
  価格: number;
  面積: number;
  間取り: string;
  築年数: number;
  構造: string;
  部屋数: number;
  ベッドルーム数: number;
  バスルーム数: number;
  駐車場有無: boolean;
  アクセス: string;
  状態: string;
  賃料収入: number;
  空室有無: boolean;
  書類: string;
}

// 物件情報をMySQLに格納する関数
function 物件情報を追加(物件情報: 物件情報): void {
  const sql = `
    INSERT INTO 物件情報 (住所, 所有者, 種別, 価格, 面積, 間取り, 築年数, 構造, 部屋数, ベッドルーム数, バスルーム数, 駐車場有無, アクセス, 状態, 賃料収入, 空室有無, 書類)
    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
  `;
  const values = [
    物件情報.住所,
    物件情報.所有者,
    物件情報.種別,
    物件情報.価格,
    物件情報.面積,
    物件情報.間取り,
    物件情報.築年数,
    物件情報.構造,
    物件情報.部屋数,
    物件情報.ベッドルーム数,
    物件情報.バスルーム数,
    物件情報.駐車場有無,
    物件情報.アクセス,
    物件情報.状態,
    物件情報.賃料収入,
    物件情報.空室有無,
    物件情報.書類,
  ];

  接続情報.query(sql, values, (error, results, fields) => {
    if (error) {
      console.error('物件情報のデータベースへの追加に失敗しました:', error);
    } else {
      console.log('物件情報をデータベースに追加しました:', results);
    }
  });
```

</details>



## 実際に利用可能か？

利用可能: ✅, 利用不可: ❌

- JS (✅)
    - [ECMAScript source text is a sequence of Unicode code points. ](https://tc39.es/ecma262/#:~:text=ecmascript%20source%20text%20is%20a%20sequence%20of%20unicode%20code%20points)
- HTML (❌)
    - [開始タグの最初の文字は、U+003C LESS-THAN SIGN 文字 (<) でなければならない。](https://www.w3.org/TR/2011/WD-html5-20110525/syntax.html#:~:text=the%20first%20character%20of%20a%20start%20tag%20must%20be%20a%20u%2B003c%20less-than%20sign%20character%20(%3C))
- CSS (✅)
    - https://stackoverflow.com/questions/19123336/can-i-safely-use-unicode-characters-e-g-accents-in-css-class-names-or-ids#:~:text=from%20the%20css%20specification
- WebComponent (?)
    - まだ明確に定まっていない？
- React (✅)
    - 最終的にJSに変換される
    - コンポーネント名は残らない
- MySQL (✅)
    - [参考](https://dev.mysql.com/doc/refman/8.0/ja/identifiers.html#:~:text=%E5%BC%95%E7%94%A8%E7%AC%A6%E3%81%A6%E3%82%99%E5%9B%B2%E3%81%BE%E3%82%8C%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84%E8%AD%98%E5%88%A5%E5%AD%90%E3%81%A6%E3%82%99%E8%A8%B1%E5%8F%AF%E3%81%95%E3%82%8C%E3%82%8B%E6%96%87%E5%AD%97%E3%80%82)
- DynamoDB (▲)
    - テーブル名、Index名だけ下記のルールに従う
    - [名前付けルール](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#:~:text=%E3%83%87%E3%83%BC%E3%82%BF%E5%9E%8B-,%E5%90%8D%E5%89%8D%E4%BB%98%E3%81%91%E3%83%AB%E3%83%BC%E3%83%AB,-DynamoDB%20%E3%81%AE%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB)
- Github (✅)
    - `git config --global core.quotePath false` で利用可能
    - [参考](https://stackoverflow.com/questions/34549040/git-not-displaying-unicode-file-names#:~:text=git%20config%20--global%20core.quotepath%20false)
- OS (✅)
    - (今時マルチバイトのファイル名が使えないOSがあるのか？)

このように多くの環境では問題なく利用できるようです。
HTMLそのものには日本語タグ名を利用することはできませんが、Reactを介しての利用は可能です。
DynamoDBなど、どうしてもalphanumericな文字列が要求される環境もありますので、`腐敗防止層` などで吸収する必要がありそうです。

## 想定される意見

- 打ちづらい
    - その通りだと思います。ただ、コードは**書きやすさより、読みやすさが重要**という認識をすり合わせることができれば運用は難しくないと思います。
- 外国人エンジニアとのコラボレーションがしづらい
    - コラボレーションするメンバーを含めチーム全体で、認知負荷を最小限に止めるに方針を決めると良いと思います。
    - 現状日本人のみでチーム組成されている場合は、将来的に外国人エンジニアと協業する可能性がどのくらいあるでしょうか？また、そもそも現状の英語はネイティブが読める英語になっているでしょうか？(ローマ字とかは論外ですが。)。
        - (先述の例でchatgptがうまく翻訳をしてくれているので、もしかすると正しい日本語で書いてから機械翻訳などを噛ませた方が精度が高まるかもしれません、、)
- プロダクションコードが汚れる
    - フロントエンドに関しては`バンドル + Minify(Uglify)`が基本なので、本番コードが汚染される心配はないと思われます。
- なんかバグるんじゃ？
    - 利用技術の下調べは前提になりそうですね、、
- 英語力がおちる
    - 業務時間では価値のあるコードを生み出すことに注力するべきです。ただ、エンジニアに英語力が要求される場面は海外の書籍・ブログ記事を読んだり、フレームワークなどのドキュメントやその他一次情報を参照する時が多いと思うので特段問題はないと思います。
- 英語を勉強するべき
    - 自分がテックリードだったとしてチーム英語力が完成するのはいつになるでしょうか？それまでのコードの品質はどう担保するのでしょうか？そして、チームは成果をいつまでに出す必要があるでしょうか？
- なんかきもい
    - めっちゃ分かりますw当たり前を疑うような話なので、気持ち悪さはどうしてもあります。コードの価値を焦点にフラットに方針を検討できればと思います。

## 提案

### チームメンバーの読解速度を確認してみる

前提になるのはチームの英語力になります。そこで、チームで読解スピードを計測してみるのはいかがでしょうか？
こちら `https://www.sokunousokudoku.net/measuresan/` のようなサイトで2, 3数分程度で実施することができます。
ただし、エンジニアは英語ができないといけないという暗黙のバイアスは強く感じるところなので、心理的安全性を保ち正直に実施と結果の申告してもらえるような風土作りは案外難しいかもしれません。

### 漸進的に導入する

既存のプロダクトにいきなり日本語を混ぜていくのは非常に抵抗を感じる部分があると思います。そこで、セグメントを切りながら日本語を漸進的に導入していくのはどうでしょうか？
最初はドメイン知識が凝縮している`ドメインモデル`周辺から日本語を導入していくことで、先述のメリットを効率よく実現でき、ドメイン知識をよりわかりやすく緻密に表現することができる様になります。ドメインモデルでの日本語活用に成功したら、次は`DomainService`や`ApplicationService`に実装する`UseCase`などを日本語にすると良いと思います。その後は、コンポーネント名、DAO、DTOなどセグメントを切って実践していくのが良いと思います。

### まずはプライベートプロダクトで試す

個人的な話ですが、多肉植物の栽培にはまっており、灌水や植え替えを管理するWebアプリケーションを`React + Firebase`で開発しているのですが、ここで日本語変数名を利用しています。これまでも、いくつかプライベートプロダクトを開発してきましたが、日本語でプログラムされていることで少し時間が開いても読み直しが圧倒的に楽であることを実感しています。また、`灌水`、`科・属・種`、`施肥`、`耐寒性`と行った園芸特有の用語をいちいち英語で考えるよりも何も考えずにコードに起こすことができます。FireStoreでも日本語のコレクション名を利用していますが、今のところ問題は出ていません。唯一の欠点は、やはり変換が終わらないとエディタのサジェストが利用できないので、書き心地の点はアルファベットを利用した方が良いです。ただ、メリットの方が上回ることを実感しています。

## まとめ

個人的な見解をまとめた記事なので、読んで不快感を感じた方も多くいると察しますが、当たり前のことでも日々疑いながら改善のサイクルを回していくことでエンジニアとしてのアウトプットをより高めていきたいと考えています。
私自身も現在働いている会社でのPJでは普通に英語でコーディングしています。しかし、国内向けのSaaSプロダクトのため専門用語の取り扱いには日頃から課題を感じていました。
過去日本語でコーディングすることが明らかにアンチパターンだった時代がありますが、時代は繰り替えします。
例えば、Javaの厳しい型制約への課題から動的言語が流行りましたが、プロダクトが大規模になるに連れて再びTSやGOなどのように人間のために型を利用できる言語が再び注目されました。
日本語プログラミングに関しても環境が整えば再考されるタイミングが出てくるのではないかと思っています。

まとめると私が考える、日本語でプログラムを書くメリットは以下の通りです。

1. `認知コスト`が下がる ( => コードの`ドキュメントとしての価値`が上がる)
1. `ドメイン駆動設計`をより上手く実践できる　（ => 複雑なロジックや`ドメイン知識`のコードへの落とし込み作業が楽になる）

末筆ながら、長い記事を読んでいただいた方はありがとうございましたmm