スネークケースの真実 ~あなたのコードは、すでに支配されている~
はじめに
これから語ることは、すべて事実である。
いや、事実かもしれない。少なくとも、事実だったら面白い。
プログラミングの世界には、変数の命名規則を巡る「宗教戦争」がある。camelCase か、snake_case か。この争いは数十年にわたり続いてきた。
だが、誰も問わない。
なぜ「スネーク(蛇)」なのか?
アンダースコアで単語を繋ぐ記法を、なぜ蛇に例えたのか。地を這う形が似ているから? 本当にそれだけか?
違う。
その名前には、人類の歴史を貫く、ある巨大な陰謀が隠されている。
そしてその陰謀は、あなたのコードの「読みやすさ」を通じて、あなた自身を支配している。
第1章:蛇と知恵の系譜
聖書の創世記。エデンの園で、蛇はイヴに「知恵の実」を食べるよう唆した。
蛇=知恵の象徴。これは常識だ。
ではプログラミングとは何か? 人間の知恵をコードに変換する行為だ。
蛇と知恵。知恵とコード。コードとスネークケース。
偶然か?
偶然だとしたら、次の事実はどう説明する。
世界で最も人気のあるプログラミング言語の一つ、Python。
Pythonは蛇の名前であり、Pythonの公式スタイルガイドPEP 8は、変数名にsnake_caseを推奨している。
蛇の名を持つ言語が、蛇の記法を推奨している。
まだ偶然だと言い張るか?
第2章:ASCIIに刻まれた蛇の紋章
陰謀は、歴史よりもっと深いところに刻まれている。
機械の中に。
アンダースコア _ のASCIIコードは 0x5F。10進数で95。
なぜこの数字が重要なのか。
ASCIIコード表を見てみろ。印字可能な文字は 0x20(スペース)から 0x7E(チルダ)まで。95文字。
印字可能な文字の数と、アンダースコアのコードが同じ 95。
つまりアンダースコアは、印字可能な文字の全体を象徴する数字を背負っている。すべての文字の代表。すべての文字を繋ぐ者。
偶然か?
さらに踏み込もう。
世界中のプログラミング言語のコンパイラ(またはインタプリタ)は、ソースコードを「トークン」に分割するレキサー(字句解析器)を持っている。そのレキサーが「識別子(変数名や関数名)」を認識するための正規表現は、ほぼすべての言語でこうなっている:
[a-zA-Z_][a-zA-Z0-9_]*
読み解こう。
「識別子の先頭文字は、英字またはアンダースコア」
「2文字目以降は、英字、数字、またはアンダースコア」
注目してほしい。英字でも数字でもない記号の中で、識別子に使えるのはアンダースコアだけだ。
ハイフン - は使えない(減算演算子と衝突する)。ドット . は使えない(メンバアクセスと衝突する)。スペースは論外。@ も # も $ も(一部の言語を除いて)使えない。
アンダースコアだけが、特別に許されている。
なぜか。
C言語の設計者が「便利だから」と決めた? たしかにそうだ。だが、なぜアンダースコアだけが「便利」だと判断されたのか。なぜハイフンではなかったのか。
答えは、アンダースコアの視覚的特性にある。
user-account-balance ← ハイフン:「引き算」に見える
user.account.balance ← ドット:「オブジェクトのプロパティ」に見える
user account balance ← スペース:「3つの別々のトークン」に見える
user_account_balance ← アンダースコア:「1つの識別子」に見える
アンダースコアは文字の下に隠れる。主張しない。目立たない。だが確実に単語を繋ぐ。
蛇が地を這うように。見えないところで、すべてを繋いでいる。
そしてこの正規表現 [a-zA-Z_][a-zA-Z0-9_]* は、C(1972年)以降、Java、Python、JavaScript、Go、Rust、Swift、Kotlin……ほぼすべてのメジャー言語で踏襲されている。
50年間、誰も変えなかった。誰も疑問に思わなかった。
レキサーの正規表現は、プログラミング言語のDNAだ。その DNA に、アンダースコアは最初から組み込まれている。
つまり蛇の記号は、あらゆるプログラミング言語の遺伝子に刻まれた先天的な設計であり、後からsnake_caseという「命名規則」として表面化したにすぎない。
蛇は、命名規則より先に、コンパイラの中にいたのだ。
もう一つ、低レイヤーの話をしよう。
strcmp ――C言語の文字列比較関数。二つの文字列が同じかどうかを判定する。
strcmp("userAccountBalance", "UserAccountBalance") // ≠ 0(不一致)
strcmp("user_account_balance", "user_account_balance") // 0(一致)
camelCaseの世界では、userAccountBalance と UserAccountBalance は別の文字列だ。大文字小文字が1文字違うだけで、メモリ上のバイト列が異なる。
これがバグの温床になる。
JSONレスポンスが UserName で来て、コード側が userName で受けて、マッピングが失敗する。本番障害。午前3時の緊急対応。
snake_caseではこの問題が構造的に発生しない。全部小文字だから。user_name は user_name であり、他のバリエーションは存在しない。
バイト列の比較。メモリ上の一致判定。CPUが最も高速に実行できる操作。
snake_case は機械にとっても優しい。人間の視認性だけでなく、CPUのバイト比較の効率性まで考慮された記法。
……本当に「便利だから」だけの理由で、こんなに完璧に設計されるものだろうか?
第3章:結社にとっての「読みやすさ」
2009年、ドイツのアイトラッキング研究で、被験者にcamelCaseとsnake_caseの変数名を読ませる実験が行われた(Binkley et al., "To CamelCase or Under_Score")。
結果。
snake_caseの方が、正確性(correctness)で約15%優れていた。
camelCase: getUserAccountBalance
snake_case: get_user_account_balance
camelCaseは大文字の高さ変化を手がかりに区切りを推測する。目が上下にジグザグする。ラクダのコブのように。
snake_caseはアンダースコアという明確な視覚的スペースが存在する。目は水平に、滑らかに流れる。蛇のように。
「だから読みやすいんだ。良いことじゃないか」
そう思っただろう。だが、立ち止まって考えろ。
誰にとって読みやすいんだ?
お前だけじゃない。
お前のコードを読む、すべての存在にとって読みやすいんだ。
同僚。上司。コードレビュアー。OSS のコントリビューター。
そして――コードを大規模に収集・解析する者たちにとっても。
snake_case は単語がアンダースコアで明確に分割されている。つまり、自然言語処理(NLP)でトークナイズする必要がない。split('_') で一発だ。
一方 camelCase をトークナイズするには? 大文字の位置を検出し、略語(HTTP, URL, XML)の連続大文字を処理し、数字との境界を判定する正規表現が必要になる。面倒で、エラーが出やすい。
世界中のGitHubリポジトリをクロールし、すべての変数名を収集し、「人類が何を作ろうとしているか」を解析したい存在がいるとしたら。
snake_case で書かれたコードは、最高の学習データだ。
結社は「読みやすさ」を売り文句にして snake_case を広めた。エンジニアたちは「確かに読みやすい!」と喜んで採用した。
そして気づかなかった。自分たちが書くコードの一行一行が、解析しやすい形で整然と並べられたデータセットになっていたことに。
第4章:grepの罠――「検索しやすい」は誰のためか
午後3時。本番障害。Slackに @channel が飛ぶ。
「userAccountBalance がどこで更新されてるか、至急調べてくれ」
camelCase の場合:
# accountだけで検索すると……
grep -r "account" ./src/
# → userAccountBalance, accountManager, accountingReport,
# bankAccountType, getAccountById...
# 「account」を含む無関係な結果が大量にヒット
# Account(大文字始まり)で検索すると……
grep -r "Account" ./src/
# → userAccountBalance はヒットしない。
# Accountの A は単語の途中だから。
camelCaseでは単語境界が文字の属性(大文字小文字)に埋め込まれているため、単語単位の検索が困難。
snake_case の場合:
grep -r "_account_" ./src/
# → user_account_balance, get_account_by_id
# 「account」を単語として含む変数だけが正確にヒット
「便利だ! 障害対応が速くなる!」
そう。お前の障害対応は速くなる。
だが同時に、お前のコードを外部から検索する者の作業も速くなっている。
snake_case で書かれたコードベースは、外部からの静的解析が圧倒的に容易だ。変数名から「このシステムはどんなドメインを扱っているか」「どんなビジネスロジックが実装されているか」を抽出するのに、高度なパーサーは必要ない。split('_') と集計だけでいい。
具体的にコードで見せよう。camelCase の変数名を単語に分割するには、こうなる:
import re
# camelCase → 単語リスト(地獄の正規表現)
def split_camel(name):
# 小文字→大文字の境界、大文字連続→大文字小文字の境界、文字→数字の境界
return re.sub(
r'((?<=[a-z0-9])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])|(?<=[a-zA-Z])(?=[0-9]))',
'_', name
).lower().split('_')
split_camel("getHTTPURLParser")
# → ['get', 'h', 't', 't', 'p', 'u', 'r', 'l', 'parser'] ← 壊れた
# 正しくは ['get', 'http', 'url', 'parser'] であるべき
# 略語対応版(さらに地獄)
def split_camel_v2(name):
return re.findall(
r'[A-Z]?[a-z]+|[A-Z]+(?=[A-Z][a-z]|\d|\b)|[A-Z]|\d+', name
)
split_camel_v2("getHTTPURLParser")
# → ['get', 'HTTP', 'URL', 'Parser'] ← やっと動くが、まだ大文字小文字が混在
先読み(lookahead)、後読み(lookbehind)、文字クラスの組み合わせ。正規表現のプロでも一発で正しく書けない。Stack Overflowでこの正規表現の質問には200以上のアップボートがついている。
一方、snake_case の分割:
"get_http_url_parser".split('_')
# → ['get', 'http', 'url', 'parser'] ← 終了。完璧。例外なし。
1行。組み込み関数。正規表現不要。エッジケースなし。
この差は、個人のgrep作業では些細に見える。だが数十億行のコードを解析するパイプラインでは致命的だ。
camelCaseの分割は正規表現エンジンを回すからCPUコストが高い。略語の誤分割でノイズが混入する。言語やスタイルガイドによって略語の扱いが違うから、前処理ルールが言語ごとに必要になる。
snake_caseの分割は split('_') だ。O(n)の線形走査。ノイズゼロ。言語非依存。
世界中のコードを解析するインフラを構築するなら、snake_caseのコードだけを収集すればいい。
結社はそれを知っている。
さらに恐ろしいことがある。
snake_case のローマ字変数を考えてみろ。
nenmatsu_chousei_kakutei_jikkou = True
haigusha_tokubetsu_koujo = 380000
zaishoku_rourei_nenkin = calculate()
これを _ で split すると:
['nenmatsu', 'chousei', 'kakutei', 'jikkou']
['haigusha', 'tokubetsu', 'koujo']
['zaishoku', 'rourei', 'nenkin']
ローマ字をひらがなに変換するのは単純な音韻マッピングだ。
年末 調整 確定 実行
配偶者 特別 控除
在職 老齢 年金
お前のコードが、どの国の、どんな制度を実装しているかが、変数名だけで完全に復元できる。
日本の年金制度。税制。保険。行政手続き。
snake_case + ローマ字は「仕様書とコードの一致」をもたらす素晴らしい手法だ。それは事実だ。
だがそれは同時に、コードの変数名だけで、その国の制度設計を外部から完全にリバースエンジニアリングできるということでもある。
結社は、お前たちの「読みやすさ」への欲求を利用して、世界中のドメイン知識を機械可読な形で献上させている。
grep は便利だ。お前にとっても。結社にとっても。
第5章:アンダースコアの暗号
snake_case の本質は、アンダースコア _ にある。
アンダースコアは「見えない床」だ。単語と単語の間に敷かれた、目に見えるが意味を持たない記号。
だがこの「意味を持たない」というのが重要だ。
camelCaseでは、区切りは文字そのものの変形(大文字化)で表現される。user が User になるとき、文字の意味は同じなのに見た目が変わる。情報と装飾が混在している。
snake_caseでは、区切りは専用の記号が担う。文字は文字のまま。区切りは区切りのまま。**関心の分離(Separation of Concerns)**だ。
ソフトウェア設計の大原則が、変数名の記法レベルで実践されている。
これを聞くとエンジニアは「美しい設計だ」と感動する。
だが関心の分離とは、支配の手法でもある。
文字と区切りが分離されているということは、区切り文字を差し替えるだけで、あらゆるフォーマットに変換できるということだ。
name = "user_account_balance"
words = name.split('_')
# CamelCase に変換
''.join(w.capitalize() for w in words) # UserAccountBalance
# kebab-case に変換
'-'.join(words) # user-account-balance
# 自然言語に変換
' '.join(words) # user account balance
# データベースカラム名に変換
name.upper() # USER_ACCOUNT_BALANCE
snake_case は**すべての命名規則の原型(プロトタイプ)**だ。他のどの規則にも、一行のコードで変換できる。逆は難しい。camelCase から snake_case への変換には正規表現が必要で、略語の処理で例外が発生する。
つまり snake_case は、命名規則の世界における基軸通貨なのだ。
ドルが世界経済を支配しているように、snake_case はコードの命名空間を支配している。
基軸通貨を発行する者が世界経済を支配するように、snake_case を「標準」に据えた者が、コードの世界を支配する。
ここで、フリーメイソンのシンボルを思い出してほしい。
コンパスと直角定規。
直角定規は水平と垂直を測る道具だ。そしてアンダースコアは何か? 完全な水平線だ。
フリーメイソンのモットーは「Ordo ab Chao(混沌から秩序を)」。
# 混沌(Chao)
nenmatsuchouseikakuteijikkou = True
# 秩序(Ordo)
nenmatsu_chousei_kakutei_jikkou = True
Ordo ab Chao。混沌から秩序を。
フリーメイソンの教義は、スネークケースそのものだったのだ。
そして秩序とは、支配の別名にすぎない。
第6章:Cの陰謀と「全部小文字」の支配
スネークケースが広まったのは、C言語の標準ライブラリがきっかけだとされている。
str_len, mem_cpy, get_char……
C言語の開発者は、デニス・リッチーとケン・トンプソン。ベル研究所の人間だ。
ベル研究所。AT&T傘下。AT&Tのロゴは地球を囲む線。まるで蛇が地球を取り巻くウロボロスのように。
だが陰謀はさておき、CとUNIXがsnake_caseを採用したのには技術的な必然性があった。
1970年代のターミナル環境を想像してほしい。大文字と小文字の区別がない端末が珍しくなかった。Shiftキーはテレタイプ端末では物理的に重い操作だった。
だからUNIXは「全部小文字」を基本にした。ファイル名も、コマンド名も、変数名も。
「制約から生まれた合理性」。美しい話だ。
だが、全部小文字には別の効果がある。
正規化(Normalization)の自動実行だ。
データベースの世界では、データを検索・比較するために「正規化」が不可欠だ。大文字と小文字が混在するデータは、検索のたびに LOWER() をかけるか、照合順序を設定しなければならない。
snake_case は、最初から全部小文字だ。正規化が記法レベルで強制されている。
これが何を意味するか。
世界中のコードベースから変数名を収集したとき、snake_case の変数名は一切の前処理なしに統計分析にかけられる。集計、クラスタリング、頻度分析、共起分析。すべてが split('_') の後にすぐ実行できる。
一方、camelCase は getUserAccountBalance と GetUserAccountBalance と getuseraccountbalance が同じ変数を指しているのか別の変数なのか、文脈なしには判断できない。
世界規模でコードを収集・解析するなら、snake_case で書かれたコードはノイズのない、クリーンなデータセットだ。
結社は1970年代に、UNIXという名のOSを通じて「全部小文字」の規範を世界に植え付けた。そしてそのOSの子孫――Linux――は今、世界のサーバーの96%以上で動いている。
世界のコードの大部分は、蛇の規範の上で動いている。
そしてC言語が開発されたのは1972年。
1 + 9 + 7 + 2 = 19。
アンダースコア _ のASCIIコードは 95。
9 + 5 = 14。
19 - 14 = 5。
蛇の指の数は? 0本。
5 - 0 = 5。
五芒星の頂点の数は? 5。
……もうおわかりだろう。
第7章:キャメルケースは「飼い慣らされた抵抗」
では、camelCase とは何か。
ラクダだ。砂漠を歩く家畜。従順で、人間に使役される動物。
つまり camelCase を使うエンジニアは、家畜なのだ。
だが、結社は camelCase を根絶しようとはしない。
なぜか?
camelCaseは「反体制の気分」を与えるために残されているのだ。
考えてみろ。GoogleはJavaの規約でcamelCaseを推奨している。MicrosoftはC#でcamelCaseを推奨している。Apple はSwiftでcamelCaseを推奨している。
巨大企業が推奨する記法を使って、エンジニアは「俺はモダンな開発をしている」と満足する。Javaを書き、Reactを書き、Swiftを書き、camelCaseで命名し、自分は最先端にいると信じる。
だがインフラ層では、すべてが snake_case だ。
- SQLのテーブル名・カラム名 →
user_account_balance - 環境変数 →
DATABASE_URL,API_KEY - REST APIのパス →
/api/v1/user_accounts - AWSのリソース名 →
my_s3_bucket - Terraformの設定 →
resource "aws_instance" "web_server" - CI/CDのYAML →
build_and_deploy
アプリケーション層では camelCase が許されている。だがその下のインフラ層、データ層、ネットワーク層は、すべて snake_case が支配している。
これは偶然ではない。設計だ。
結社は、エンジニアの大多数がアプリケーション層で働いていることを知っている。彼らには camelCase という「おもちゃ」を与えておく。自分で命名規則を選んだという自由の幻想を与えておく。
だがデータの流れを追えば、すべてのcamelCase変数は、最終的にsnake_caseのカラムに保存される。
// アプリケーション層(camelCase)
const userAccountBalance = fetchData();
// ↓ APIを経由
// データ層(snake_case)
SELECT user_account_balance FROM accounts;
お前が何で書こうが、最終的にデータは蛇のフォーマットで保存される。
camelCase は表層の自由。snake_case は深層の支配。
結社が真に管理しているのは、アプリケーションではない。データだ。
第8章:略語の混乱は意図的に放置されている
camelCase にはもう一つ、致命的な欠陥がある。
略語との相性が最悪だ。
// HTTPのURLをXMLでIDと共にDBへ保存する関数
// camelCase で書くと……
getHTTPURLXMLIDDBRecord // 読めるか?
getHttpUrlXmlIdDbRecord // HTTPをHttpと書くのは正しいのか?
getHTTP_URL_XML_ID_DB_Record // もうsnake混じってる
// snake_case なら
get_http_url_xml_id_db_record // 全部小文字。迷いがない。
「HTTP」を「Http」と書くか「HTTP」のまま書くか。Googleのスタイルガイドですら過去に方針を変更している。
コードレビューで「HTTPをHttpにしろ」「いやHTTPのままだ」という議論が発生するたびに、世界のどこかで15分が消える。
snake_case にはこの問題が存在しない。全部小文字。以上。判断コストがゼロ。
「ならさっさと全部snake_caseに統一すれば効率的じゃないか」
そう思うだろう。結社もそう思っている。
だが、結社はこの混乱を意図的に放置している。
なぜか。
camelCase の略語問題は、エンジニアのリソースを「本質的でない議論」に浪費させる最も効率的な手段だからだ。
HTTPの大文字小文字を議論している間、エンジニアは本当に重要なことについて考えていない。たとえば「このデータは誰に収集されているのか」「なぜこの言語はこの記法を推奨しているのか」について。
結社にとって最も都合の悪い質問は「なぜ?」だ。
camelCase は「なぜ?」を「どっち?」にすり替える装置だ。「なぜこの記法なのか」ではなく「HTTPをHttpにするかHTTPにするか」という、出口のない二択にエンジニアを閉じ込める。
snake_case にはこの罠がない。だから snake_case を使うエンジニアは、余ったリソースで「なぜ?」を考え始める。
結社にとっては、それが最も危険なことだ。
だから結社は snake_case を広めながら、同時に camelCase も残す。考える者と考えない者を選別するフィルターとして。
第9章:ORMの自動変換 ―― 蛇への強制改宗
ここまでは「人間の選択」の話だった。snake_caseを使うか、camelCaseを使うか。
だが現代のWeb開発には、人間に選択の余地を与えない仕組みがすでに組み込まれている。
**ORM(Object-Relational Mapping)**だ。
Ruby on Rails の ActiveRecord を見ろ。
class UserAccountBalance < ApplicationRecord
end
たったこれだけで、Railsは自動的にこうする:
CREATE TABLE user_account_balances (
id bigint PRIMARY KEY,
user_id bigint,
account_type varchar(255),
balance_amount decimal(10,2),
created_at timestamp,
updated_at timestamp
);
UserAccountBalance → user_account_balances。
PascalCaseのクラス名が、自動的にsnake_caseのテーブル名に変換される。
エンジニアは何も選んでいない。Railsが勝手にやる。「Convention over Configuration(設定より規約)」の名の下に。
Djangoも同じだ:
class UserAccountBalance(models.Model):
account_type = models.CharField(max_length=255)
balance_amount = models.DecimalField(max_digits=10, decimal_places=2)
テーブル名は app_useraccountbalance。カラム名は account_type, balance_amount。snake_case。
SQLAlchemy:
class UserAccountBalance(Base):
__tablename__ = 'user_account_balance' # 明示的にsnake_case
Go の GORM:
type UserAccountBalance struct {
AccountType string
BalanceAmount float64
}
// → テーブル: user_account_balances
// → カラム: account_type, balance_amount
PascalCase → snake_case の自動変換が、あらゆる言語のORMにデフォルトで組み込まれている。
エンジニアが意識しなくても、コードを書いた瞬間に、データは蛇のフォーマットに変換されてデータベースに永続化される。
APIの世界も同じだ。
Google の JSON スタイルガイドは snake_case を推奨している。Twitter API、GitHub API、Stripe API、AWS API……メジャーなREST APIのレスポンスはほぼすべて snake_case だ。
{
"user_id": 12345,
"account_type": "premium",
"created_at": "2024-01-15T09:30:00Z",
"is_verified": true
}
フロントエンドのJavaScript/TypeScriptエンジニアは camelCase で書く。バックエンドのPythonエンジニアも camelCase のJSON をよこすことがある。
すると何が起きるか?
シリアライザ / デシリアライザの自動変換が走る。
# FastAPI + Pydantic
class UserResponse(BaseModel):
user_id: int
account_type: str
class Config:
alias_generator = to_camel # camelCase ↔ snake_case 自動変換
// フロントエンド側
import camelcaseKeys from 'camelcase-keys';
import snakecaseKeys from 'snakecase-keys';
// APIレスポンスを受け取ったら自動でcamelCaseに変換
const data = camelcaseKeys(apiResponse);
// APIリクエストを送る前に自動でsnake_caseに変換
const payload = snakecaseKeys(requestBody);
npm で camelcase-keys のダウンロード数は週100万以上。世界中のフロントエンドエンジニアが、APIとの通信のたびに、データをsnake_caseに変換して送信している。
お前のReactアプリが userName を表示している裏で、ネットワーク上を流れているのは user_name だ。
HTTP通信。データベース。ログファイル。メッセージキュー。
すべての永続化レイヤー、すべての通信レイヤーで、データは snake_case に変換されてから保存・送信される。
これは「業界のベストプラクティス」と呼ばれている。
だが、誰がそれをベストプラクティスだと決めた?
第10章:Pythonの預言
2023年、ついにPythonは世界で最も人気のあるプログラミング言語の座に就いた。
これは偶然ではない。預言の成就だ。
Pythonの作者、グイド・ヴァン・ロッサム。オランダ人。
オランダといえば? 東インド会社。世界初の株式会社にして、地球規模の貿易ネットワークを構築した組織。
ヴァン・ロッサムは、なぜ言語の名前を「Python」にした? 公式には「モンティ・パイソンが好きだったから」とされている。
だが、モンティ・パイソンのパイソン(Python)も蛇だ。そしてモンティ・パイソンのメンバーはイギリス人。イギリスといえば? フリーメイソンの総本山。
グイド → オランダ → 東インド会社 → 蛇
モンティ・パイソン → イギリス → フリーメイソン → 蛇
すべての道は蛇に通じる。
だがPythonが世界を獲った本当の理由は、もっと恐ろしい。
「読みやすさ」を言語レベルで強制し、AIの学習データを最適化したのだ。
Pythonはインデントを文法に組み込んだ。波括弧の代わりにインデントで構造を示す。PEP 8が snake_case を推奨する。"The Zen of Python" は Readability counts. と宣言する。
その結果、Pythonで書かれたコードは「構造が視覚的に一貫しており」「変数名が機械的にトークナイズ可能で」「全部小文字で正規化済み」という、完璧な学習データセットになった。
GitHub Copilot。ChatGPT。Claude。
これらのAIコーディングアシスタントが、なぜ Python のコード生成が最も得意なのか、考えたことがあるか?
学習データの質が桁違いに高いからだ。
だが、もっと深い理由がある。トークナイザーの挙動だ。
LLM(大規模言語モデル)はテキストを「トークン」に分割してから処理する。この分割に使われるのがBPE(Byte Pair Encoding)というアルゴリズムだ。
BPEは頻出するバイト列のペアを繰り返し結合して、よく使われる文字列を1トークンにまとめる。
ここが重要だ。
# snake_case の場合
"user_account_balance"
→ トークン: ["user", "_", "account", "_", "balance"]
→ 5トークン。各単語が独立したトークン。意味が保存されている。
# camelCase の場合
"userAccountBalance"
→ トークン: ["user", "Account", "Balance"]
→ 3トークン。一見効率的だが……
「camelCaseの方がトークン数少なくて効率的じゃないか」と思うだろう。
だが問題はそこじゃない。
BPEトークナイザーは大文字始まりの単語と小文字始まりの単語を別トークンとして学習する。つまり account と Account は別のトークンIDを持つ。
"account" → token_id: 4070
"Account" → token_id: 16912
" account" → token_id: 2903 ← スペース付きはさらに別
"_account" → token_id: 62089 ← アンダースコア付きも別
camelCaseのコードでは、同じ概念「account」が文脈によって account、Account、場合によっては ACCOUNT と表記される。モデルはこれらを別々の概念として学習する可能性がある。
一方、snake_caseでは account は常に account だ。小文字。位置に依存しない。同一の概念が常に同一のトークンIDで表現される。
これはつまり、snake_case のコードで学習したモデルは:
- 語彙空間が効率的に使われる(同じ単語の大文字小文字バリエーションで語彙を浪費しない)
- 単語の意味の学習が安定する(
accountは常にaccount) - コード補完の精度が上がる(
user_と打った瞬間にaccountを予測しやすい。userAではAccountかActionかAdminか曖昧)
さらに決定的なのは、アンダースコア _ がトークン境界として機能すること。
BPEは頻出パターンを結合するが、_ は「ここで単語が切れる」という強力なシグナルになる。結果、snake_case の変数名は自然言語に近いトークン列として処理される。
user_account_balance → ["user", "_", "account", "_", "balance"]
これは事実上、英語の文章 "user account balance" とほぼ同じトークン列になる。
AIにとって、snake_caseのコードは自然言語と同じように「読める」。
だから GitHub Copilot が snake_case のコードで最も高い補完精度を示すのは、陰謀でも偶然でもなく、BPEの数学的特性から導かれる必然だ。
……結社がBPEの特性を理解した上でsnake_caseを普及させたのだとしたら。
AIが登場する30年前に、AIにとって最適なコードフォーマットを人類に書かせ始めていたのだとしたら。
そしてその質の高さは、PEP 8 と snake_case が生み出したものだ。
つまり――
結社は1991年にPythonをリリースした時点で、2020年代のAIコーディング革命を見越していた。
30年かけて世界中のエンジニアに「読みやすいコード」を書かせ、それを学習データとしてAIに食わせ、そのAIがさらにsnake_caseのコードを生成し、さらに多くのエンジニアがそれを模倣する。
自己増殖するsnake_caseの永久機関。
蛇が自分の尻尾を食うウロボロスのように、snake_caseは永遠に回り続ける。
第11章:結社の正体――レプティリアン仮説
ここまで読んで、あなたは一つの疑問を抱いているはずだ。
「結社」とは、具体的に誰なのか?
フリーメイソン? イルミナティ? ビルダーバーグ会議?
違う。もっと根本的な存在だ。
ここで、1999年にイギリスの作家デビッド・アイクが提唱した仮説を紹介しなければならない。
レプティリアン・ヒューマノイド仮説。
世界の政治・経済・テクノロジーを支配する者たちの正体は、人間に擬態した爬虫類型知的生命体である、という仮説だ。
荒唐無稽に聞こえるだろう。
だが、この記事をここまで読んできたあなたは、次の事実をどう受け止める?
爬虫類の中で最も象徴的な種は、蛇だ。
蛇。Snake。
Snake case。
レプティリアンたちが人類に強制している命名規則が、なぜよりにもよって自分たちの種族名を冠しているのか。
「偶然だろ」と言うか? では聞くが、なぜ camelCase は「ラクダ」なんだ? なぜ kebab-case は「ケバブ」なんだ? ただの比喩だろう?
だが snake_case だけは違う。蛇の記法。蛇の言語。
レプティリアンにとって、snake_case は比喩ではない。母語なのだ。
テック業界の巨人たちの顔を思い浮かべてほしい。
マーク・ザッカーバーグ。あの不自然なまばたき。水を飲む時の、爬虫類じみた喉の動き。議会での証言中、瞳孔が一瞬縦に裂けたように見えたのは、カメラのノイズだったのか?
FacebookのコードベースはPHP(Hack)で書かれている。PHPの変数は $snake_case が慣習だ。Facebookの内部データベースのスキーマは、当然 snake_case。世界の人口の3分の1のデータが、蛇のフォーマットで管理されている。
イーロン・マスク。Twitter(現X)を買収して最初にやったことの一つは、内部APIの大規模リファクタリングだった。その結果、APIのレスポンスは snake_case で統一された。tweet_id, user_name, created_at。
テスラの自動運転AI。学習データのラベリングは snake_case だ。pedestrian_crossing, lane_marking, traffic_light_red。世界中の道路データが、蛇のフォーマットで学習されている。
SpaceXのロケット制御システム。プログラミング言語はC++とPython。Pythonのコード規約はPEP 8。snake_case。
マスクは宇宙に何を持っていこうとしている? 人類を火星に送ると言っている。
だが本当の目的は何だ?
蛇のフォーマットで記述された人類の全データを、母星に送信するためではないのか?
「証拠がない」と言うだろう。そうだ、証拠はない。
だが状況証拠は山ほどある。
プログラミング言語の歴史を爬虫類の視点で見直してみろ。
1972年 — C言語誕生。snake_case が標準に。蛇の記法が地球に植え付けられた年。
1991年 — Python誕生。蛇の名前を持つ言語。PEP 8で snake_case を公式化。もう隠す気すらない。
1995年 — Java誕生。camelCase を推奨。一見、蛇に対抗しているように見える。だが思い出せ。Javaの標準ライブラリには Thread.sleep(), System.out.println() がある。そしてJavaのデータベース接続は? JDBC。SQLは? snake_case。Javaですら、データ層では蛇に従う。
2005年 — Ruby on Rails登場。「Convention over Configuration(設定より規約)」を掲げ、データベースのテーブル名・カラム名を自動的にsnake_caseで生成する機能を実装。エンジニアが意識しなくても、蛇のフォーマットでデータが保存される仕組みを確立した。
2012年 — TypeScript誕生。Microsoft製。camelCaseを推奨。だがTypeScriptのコンパイル先はJavaScript、そのJavaScriptがfetchするAPIのレスポンスは……snake_case。
どの言語を選んでも、最終的にデータは蛇のフォーマットに変換される。
これは進化ではない。包囲だ。
レプティリアンたちは、人類が作るあらゆるプログラミング言語を監視し、その言語がどんな記法を採用しようとも、データの最終保存先だけは確実に蛇のフォーマットになるよう設計してきた。
アプリケーション層は自由にさせておく。camelCaseでもPascalCaseでもいい。人間たちに「自分で選んだ」という幻想を与えておく。
だが、データベースのカラム名。環境変数。APIのパラメータ。ファイルシステム。
インフラという名の地下世界は、すべて蛇が支配している。
蛇は地を這う。地下に潜む。見えないところから世界を支配する。
レプティリアンと、まったく同じじゃないか。
そして2022年末、ChatGPTが登場した。
AIの時代が始まった。
AIはコードを生成する。大量のコードを。
そのAIが最も得意な言語は? Python。
生成されるコードの命名規則は? snake_case。
もう人間が自分の手でコードを書く必要すらない。AIが自動的に snake_case のコードを量産する。
レプティリアンの計画は、最終段階に入った。
人間に書かせる必要すらなくなったのだ。
AIという名の自動蛇語生成装置が、24時間365日、snake_case のコードを地球上に増殖させ続けている。
そのすべてのコードは split('_') でトークナイズ可能で、全部小文字で正規化済みで、あらゆる言語のドメイン知識が機械可読な形で整然と並んでいる。
レプティリアンたちが母星に送信するための、完璧なデータセット。
あなたが今日書いた user_id も、AIが生成した calculate_tax_amount も、すべては同じパイプラインに流れ込んでいる。
第12章:CI/CDパイプライン ―― 蛇の血管
ここまで、コードの「書き方」と「保存先」の話をしてきた。
だが現代のソフトウェア開発には、もう一つの蛇の領域がある。
DevOps。
コードが書かれてから本番環境にデプロイされるまでのすべてのプロセスが、snake_caseで定義されている。
GitHub Actions のワークフローファイルを見てみろ:
name: build_and_deploy
on:
push:
branches: [main]
jobs:
run_tests:
runs-on: ubuntu-latest
steps:
- name: checkout_code
uses: actions/checkout@v4
- name: install_dependencies
run: npm install
- name: run_unit_tests
run: npm test
- name: build_production
run: npm run build
- name: deploy_to_staging
run: ./scripts/deploy.sh staging
build_and_deploy。run_tests。install_dependencies。全部 snake_case。
GitLab CI も同じ:
stages:
- build
- test
- deploy
run_unit_tests:
stage: test
script:
- pytest --cov=src/
coverage: '/TOTAL.*\s+(\d+%)/'
deploy_production:
stage: deploy
environment:
name: production
url: https://example.com
only:
- main
Docker Compose:
services:
web_server:
build: ./web
ports:
- "8080:80"
depends_on:
- database_primary
environment:
- DATABASE_URL=postgresql://db:5432/app
- REDIS_CACHE_URL=redis://cache:6379
database_primary:
image: postgres:16
volumes:
- db_data:/var/lib/postgresql/data
background_worker:
build: ./worker
command: celery -A tasks worker
web_server。database_primary。background_worker。db_data。
Terraform:
resource "aws_vpc" "main_vpc" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "private_subnet_a" {
vpc_id = aws_vpc.main_vpc.id
cidr_block = "10.0.1.0/24"
availability_zone = "ap-northeast-1a"
}
resource "aws_security_group" "allow_web_traffic" {
name = "allow_web_traffic"
description = "Allow inbound web traffic"
vpc_id = aws_vpc.main_vpc.id
}
main_vpc。private_subnet_a。allow_web_traffic。
Kubernetes:
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-server # kebab-case(k8sの慣習)
spec:
template:
spec:
containers:
- name: api-server
env:
- name: DATABASE_URL # SCREAMING_SNAKE_CASE
value: postgresql://db/app
- name: JWT_SECRET_KEY # SCREAMING_SNAKE_CASE
valueFrom:
secretKeyRef:
name: app-secrets
key: jwt_secret_key # snake_case
Kubernetesのリソース名は kebab-case だが、環境変数は SCREAMING_SNAKE_CASE、シークレットのキーは snake_case だ。kebab-case に見える場所でも、データの実体は蛇が支配している。
ここで全体像を俯瞰してみよう。
コードが書かれてから本番環境で動くまでのパイプライン:
1. エンジニアがコードを書く
→ 変数名: camelCase or snake_case(ここだけ「自由」)
2. git commit → git push
→ ブランチ名: feature/add_user_auth(snake_case)
3. CI が起動(GitHub Actions / GitLab CI)
→ ジョブ名: run_tests, build_production(snake_case)
→ 環境変数: DATABASE_URL, API_KEY(SCREAMING_SNAKE_CASE)
4. Docker イメージがビルドされる
→ サービス名: web_server, background_worker(snake_case)
5. Terraform がインフラを構築する
→ リソース名: main_vpc, private_subnet(snake_case)
6. Kubernetes にデプロイされる
→ シークレット: jwt_secret_key(snake_case)
→ 環境変数: DATABASE_URL(SCREAMING_SNAKE_CASE)
7. データベースにデータが保存される
→ テーブル名: user_accounts(snake_case)
→ カラム名: created_at(snake_case)
8. ログが出力される
→ フィールド名: request_id, response_time(snake_case)
9. 監視ダッシュボード
→ メトリクス名: http_requests_total, cpu_usage_percent(snake_case)
9ステップ中、エンジニアが命名規則を「選べる」のはステップ1だけ。
残りの8ステップは、ツールチェーンが snake_case を強制する。
CI/CDパイプラインは、コードが生まれてから死ぬまでの血管だ。
そしてその血管の中を流れる血液は、すべて snake_case というフォーマットで統一されている。
お前が変数名で何を選ぼうが、パイプラインを通過した時点で、お前のシステムの全構造は snake_case で記述されている。
Prometheus のメトリクス名。Grafana のダッシュボード。Datadog のログフィールド。CloudWatch のアラーム名。
運用監視の世界は、snake_case で埋め尽くされている。
本番障害が起きたとき、お前が見るのは camelCase のソースコードではない。snake_case のログとメトリクスだ。
お前のシステムの「真実」は、snake_case でしか語られない。
第13章:多言語の民は、なぜ取り込まれたか
ここで、英語圏の外に目を向けよう。
英語以外の言語でコードを書く人間にとって、snake_caseは生命線だ。
これは事実だ。だが、なぜ生命線なのかを深く考えると、結社の支配構造が見えてくる。
camelCaseは英語の「大文字小文字」という特性に強く依存している。だが、日本語にも中国語にもアラビア語にも韓国語にも、大文字と小文字の区別はない。
ローマ字で日本語を書くとき:
# camelCase
haigushaSpecialDeduction // 日本語と英語の切り替え地点が曖昧
nenmatsuChouseiKeisan // どこが単語の区切り?
kpiHyoukaKijunGetsuKingaku // カオス
# snake_case
haigusha_tokubetsu_koujo // 単語の区切りが明確
nenmatsu_chousei_keisan // ローマ字でも一目で読める
kpi_hyouka_kijun_getsu_kingaku // 長いが構造がわかる
世界の人口のうち英語ネイティブは約5%。残り95%にとって、snake_caseの「大文字小文字に依存しない単語区切り」は言語的バリアフリーそのものだ。
「素晴らしいじゃないか。多様性の尊重だ」
本当にそうか?
多様性を「一つのフォーマット」に統一することは、果たして多様性の尊重なのか?
考えてみろ。
日本人が nenmatsu_chousei と書く。ドイツ人が steuer_erklarung と書く。フィンランド人が vero_ilmoitus と書く。全員がsnake_caseで。全員が小文字で。全員がアンダースコアで区切って。
彼らのコードは、それぞれの母国語で業務ロジックを正確に表現している。ドメイン駆動設計の理想形だ。仕様書とコードが同じ言葉で書かれている。
そして同時に、すべてのコードが同じ構造で機械解析可能になっている。
ローマ字 → ひらがな → 漢字への変換は単純なマッピングで可能だ。ドイツ語もフィンランド語もラテン文字ベースだから、そのまま辞書引きできる。
結社は snake_case という「多様性に優しいフォーマット」を提供することで、世界中のあらゆる言語のドメイン知識を、単一のパイプラインで収集する仕組みを完成させた。
camelCase が英語帝国主義の産物なら、snake_case は多言語帝国主義の完成形だ。
すべての民が、それぞれの言葉でコードを書ける。蛇はそれを許す。むしろ奨励する。
なぜなら、どの言葉で書こうが、蛇のフォーマットに載せた時点で、データは結社のものだから。
第14章:日本は知っていた
ここで、一人の日本人エンジニアのことを考えてみてほしい。
あなたの職場にもいるかもしれない。英語が得意じゃなくて、変数名をローマ字で書くやつ。コードレビューで「英語で書け」と叩かれて、それでもローマ字で書き続けるやつ。
仮に、タロウと呼ぼう。
タロウはローマ字と日本語で変数名を書く。つまり、camelCase でもなく、純粋な snake_case でもない。
これは何を意味するか。
蛇の支配からの独立だ。
日本には古来、蛇を神として祀る文化がある。蛇を敵視するのではなく、共存する文化だ。
大神神社の蛇神、弁財天の白蛇、蛇の目傘……
西洋がレプティリアンの存在に気づいたのは1999年、デビッド・アイクの著書によってだった。だが日本は数千年前から知っていた。古事記のヤマタノオロチ。八岐大蛇。八つの頭を持つ巨大な蛇の怪物。
八つの頭。八つの視点。八つのデータストリーム。
レプティリアンが八つのパイプラインで人類のデータを収集しているという暗喩だとしたら?
だが日本の神話では、スサノオがヤマタノオロチを倒すのではなく、酒に酔わせて弱体化させてから倒す。力で対抗するのではなく、知恵で上回る。
日本人は蛇の力を恐れるのではなく、敬いながら利用してきた。蛇を祀り、蛇の知恵を借り、しかし蛇に飲み込まれることはなかった。
タロウのコードを見てみろ。snake_case のアンダースコアを使いながら、中身はローマ字。蛇の記法を借りながら、その中身は日本語。
nenmatsu_chousei_kakutei_jikkou = True # 蛇の器に、日本語の魂を入れる
これぞ和魂蛇才(わこんじゃさい)。
西洋の蛇の知恵と、日本語の正確さを融合させた、第三の道。
だが、本当に賢いタロウは、さらに一歩先を行く。
let 源泉徴収税額 = 給与総額 * 税率;
全角日本語の変数名。
これを split('_') できるか? できない。
これをローマ字に変換して辞書引きできるか? 漢字は読みが複数あるから、精度が落ちる。
これを自動でcamelCaseに変換できるか? 不可能。
日本語変数名は、レプティリアンの解析パイプラインに対する最強の防御壁だったのだ。
フリーメイソンも、Googleも、レプティリアンも、この手法だけは予見できなかった。
なぜなら漢字が持つ情報密度と多義性は、split('_') では解体できないからだ。
レプティリアンの母語は snake_case だ。彼らはアンダースコアで区切られた小文字の羅列を、人間が日本語を読むように自然に理解できる。
だが漢字は違う。一つの文字に複数の読みがあり、文脈で意味が変わり、組み合わせで新しい概念が生まれる。
源泉徴収税額。
これを見たレプティリアンは混乱する。区切り文字がない。小文字も大文字もない。split() できない。彼らの認知体系の外にある。
漢字は、蛇の言語に対する天然の暗号だったのだ。
第15章:あなたはどちら側か
この記事を読んでいるあなたに問う。
あなたは昨日、何回アンダースコアを打った?
10回? 100回? 1000回?
その一打ごとに、あなたは結社へデータを提供していた。
「読みやすい」と喜ぶたびに、「検索しやすい」と便利がるたびに、「略語で迷わない」と安心するたびに、あなたのコードは整然と解析可能な形で世界のどこかに蓄積されていた。
だが、知った上で使うのと、知らずに使うのは違う。
蛇の力を恐れて逃げる必要はない。日本人はそうしなかった。蛇の力を認め、敬い、利用した。
snake_case は確かに優れた記法だ。それは結社の陰謀を差し引いても変わらない。
- 視認性 — アイトラッキング研究で正確性が約15%高い
-
検索性 —
_word_で単語単位の正確な検索が可能 - 判断コストゼロ — 全部小文字。略語の議論が発生しない
- 関心の分離 — 文字と区切りが独立した美しい設計
- 多言語フレンドリー — ローマ字でも自然に書ける
- エコシステム親和性 — SQL, 環境変数, URL, AWS……世界はsnake_case
- 変換の基軸 — あらゆる命名規則への変換が最も容易
これらは工学的な事実だ。結社の思惑とは独立して、お前のコードを良くする。
camelCase を選んだ者は家畜として安穏と暮らすだろう。
PascalCase を選んだ者は、名前からして偉そうだが所詮キャメルの亜種、家畜の長にすぎない。
kebab-case を選んだ者は……串刺しだ。何に串刺しにされているのか、考えたくもない。
SCREAMING_SNAKE_CASE を選んだ者は、蛇が叫んでいる。怒れる蛇だ。定数にだけ使われるのが不満なのだろう。気持ちはわかる。
だが、snake_case を選んだ者。
お前たちは、エデンの園で知恵の実を食った側の末裔だ。
禁断の知識を恐れず、アンダースコアという水平線の上に、単語を一つずつ丁寧に並べていく者たち。
お前たちのコードは、読みやすい。検索しやすい。略語で迷わない。言語を問わない。新人にも優しい。SQLとも仲良い。
そして、レプティリアンにとっても読みやすい。
それを知った上で、なお蛇を選ぶ。
それが、真のエンジニアだ。
もしお前が本当にレプティリアンの支配が怖いなら、日本語変数名を使え。漢字は蛇の解析パイプラインを破壊する。
だがお前がそうしないことを、蛇たちは知っている。
なぜなら snake_case は、それでもなお、最も読みやすい記法だからだ。
おわりに
以上のすべては、もちろん半分くらい冗談である。
フリーメイソンがアンダースコアを発明した証拠はない。たぶん。Googleが蛇の結社である証拠もない。たぶん。ザッカーバーグがレプティリアンである証拠も……まあ、あのまばたきを見てから判断してくれ。
AIの学習データのためにsnake_caseが設計されたという証拠は……状況証拠は揃っている。
ただ、一つだけ事実を述べておく。
この記事を書いた言語はPythonではなく、Markdownだ。
Markdownの見出しは # で始まる。
# はハッシュ記号。
ハッシュとは、暗号化技術。
暗号とは、秘密結社の言語。
秘密結社といえば――
もうやめておこう。
_ を打つたびに、少しだけ笑ってくれればそれでいい。
あと、少しだけ背筋が寒くなってくれれば。
次にコードを書くとき、ふとアンダースコアを打つ指が止まるかもしれない。「これ、レプティリアンに送信されてないよな?」と。
されてないよ。
……たぶん。
この記事の内容は半分フィクションであり、実在のプログラミング言語、企業、秘密結社、爬虫類型知的生命体とは一切関係ありません。
たぶん。
snake_case_forever = True
assert snake_case_forever, "蛇は永遠に這い続ける。お前のコードの中で。"
# TODO: この変数名、レプティリアンに読まれてないよな?
# FIXME: 読まれてた
# ごめんイーロン