PHP - The Wrong Way とは何だったのか

これは PHP Advent Calendar 2017 - Qiita の12日目の記事です。

わたくし先月、PHP - The Wrong Way を日本語に翻訳しました。

www.phpthewrongway.com

衝撃の扉絵はご覧いただけましたでしょうか。

f:id:tanakahisateru:20171211151812p:plain

これは2017年の Symfony Live London で Laravel を笑い者にしている様子 を描いた風刺画です。

うそですけどね。

でもどうですか、そういう絵だといえばそう見えませんか? ロンドンでの事件は Laravel と Symfony の間にある摩擦ですが、それと相似な関係は、ユーザーコミュニティ全体と Laravel のようなものとの間にこそ、より深刻な状態で横たわっているのではないでしょうか。このロンドンのブーメランは、自分の翻訳進捗にずいぶん影響しました。

実を言うと自分は、あまり多くの人に PHP - The Wrong Way の翻訳を読んでもらいたいとは思っていません。この種の不幸な摩擦のサンプルとして、文脈を超えた配慮をする力と器のある人に届き、考えかたのきっかけにしてもらいたかったのです。

そりゃもう、誰にでも読んでもらいたい文書としては、こんなものよりはるかに PHP: The Right Way のほうが有益です。過剰に見えるにしても、少なくとも Right Way には技術的には嘘は書かれていません。

ということは? ええ、そのとおり、Wrong Way は技術情報として、著者の妄想にしかない嘘の事実が書かれているのです。いえ、むしろその大半が事実にもとづかない、無知ゆえの言い訳のようなもので出来上がっています。

英文でこのドキュメントを最初に読んだ時点で思ったのは、日本で言ういわゆるポエムのスタイルに近いということでした。まだコモディティ化していないパラダイムに関して、部分理解 (曲解?) から想像を膨らませたオレオレ理論を語りはじめるアレです。(どこかのサイトではアカウントごと抹殺されるほどの大罪とされていますね)

とはいえ、多言語に翻訳されて GitHub でメンテされているんだし、そのためにドメイン名まで取ったんだから、何かひとつぐらい得るものがあるにちがいない、というのが翻訳のそもそもの動機でした。それで、何が得られたかって? ええ、ある意味、期待以上のものが得られましたよ。それは何かというのはちょっと後にして、まずはきっちり批判しなければなりません。

このウェブサイトは、PHP プログラミングに関する現実的な見解を示すために作られました。流行りのトレンド、理論、学問的な教示ではなく、経験と実践の帰着を書き記した視点です。

そうですか、それでその「経験と実践」は具体的には誰の? 何の? データはどこから?

繰り返し登場する「現実の」「現場では」といった言い回しですが、いくら読み進めても、十分といえる事例は出てきません。脳内べき論ばかりが繰り返されます。また、どのトレンドと学術理論がどのように間違っているか、いっこうに証明されません。たとえばここ。

今日のプログラマの多くは、健全なプログラミングの基本原則を完全に無視し

モダンな人たちのどの方法論が、基本原則の何を、どのように無視しているのか、なぜその無視が問題なのか、まったくわかりません。いきなり無条件に「流行っているものは間違っているはずだ (大衆は陰謀に騙されている)」みたいな導入です。これじゃカルトですね。

技術トレンドのほうには、少なくともそれを支える人がいて、共通の問題意識のバックボーンがあります。学術論文というのは、客観的な推論と実証データをともなう「科学的」なスタイルが必要です。いずれも、「誰が」「何を」説明しているのか明らかになっています。

理性的な議論の土俵において、これがもっとも目につく不正です。しかも著者は匿名です。いくら心からの主張でも、一度でも嘘をつくと全体が信用されなくなります。もし本当に議論に集中できるようにと匿名にしていたのだとしても、これでは逆効果です。口から出まかせを言っているから名前も名乗れないのだろうと言われても仕方ありません。

もし「これは私のエッセイですが、きっと皆さん薄々思っていることと重なるでしょう」みたいな話であれば、信用を失うことはなかったんでしょうけど。

(... え、おまえも「うそですけどね」って最初に書たじゃん? ああ、これは所詮エッセイですから)

RedditPHP コミュニティを長く見ているという、Jon LeMaitre さんからの返信は、主にそういった内容のことが繰り返されています。「だから誰の話だよ」って。

medium.com

These people seem to work tirelessly at getting other people to follow their way of doing things.

It’s unclear who “these people” are as the author never actually provides names or even examples of these propagations. It’s a nebulous complaint as abstract as the very abstractions lamented by the author further into the article.

この人は Laravel のユーザーみたいですね。他の指摘内容をざっとかいつまんでみます:

  • 自作ライブラリのセットでも、いつもそれ使うって決めてるならすでにフレームワークじゃん
  • Djang / Rails の成り立ちについては完全に理解が間違ってるよ
  • 無駄に層を積んで複雑にしてるとかそれ strtotime() 見ても同じこと言える?
  • 普通の案件ならスケールしないのはフレームワークのせいじゃなくて人材の(ゲフンゲフン
  • PHPは関数型をサポートしていますってどこが? リフレクティブってそんなパラダイム知らないけど?
  • OOP が好きだ嫌いだで Composer のクラスローダー使わない手はないでしょ、PSR-0/4 は嫌でライブラリは使ってもいいとかいまどきナンセンスにもほどが...
  • セキュアプログラミングのやつだけは読む価値ある

Wrong Way とは逆の意味で (当たり前すぎて) 翻訳が辛いので、だれかお願いします。たぶんこの返信のほうがよっぽど、一般的には価値のある文書なので。

たしかに、Wrong Way は見出しのレベルではいいこと書いてそうに見えちゃうので、知識がない人が見れば「そうかPHPはそんなことになってるのか、人知れず真実を見抜いているとは立派な」ってふうになるじゃないですか。そんでダメな人ほど「ほらやっぱり所詮はPHPの連中は、いくら有名だって言ってもろくなもんじゃない。オブジェクト指向フレームワークも標準規約も無視していいじゃん。真面目にやってなくてよかった」って、ますますダメなほうへ行くでしょ。

よく考えてください、知識がある人が技を極めたあと体制側の欺瞞を知って戻ってきてダークヒーローになったとかなら、こんな稚拙な間違いだらけになるはずないじゃないですか。経験豊かな人が PHP に教訓を授けてくれた? いやいや、他の言語文化で多くの経験をしているならなおさら、PHP で起きていることを多角的に理解できないとおかしいでしょ。これ PHP の初歩しか実務経験がなくて、何か仕事で嫌なことがあったんだなとプロファイリングしたほうが辻褄が合います。

だいたい日本のエンジニア、外人が書いたってだけで信用しすぎなんですよ。ちょっとぐらい「これはやばいwww」「ポエム乙w」「放射脳の臭いがする」的なはてブが付くと思ってたら、

はてなブックマーク - PHP - The Wrong Way f:id:tanakahisateru:20171211173554p:plain

そして星ですかそうですか... むしろ理解を示しちゃいかん派の代表選手として、これ日本語で紹介させていただいたつもりなのですよ、こちらとしては、えぇ。

Wrong Way : Always trust foreigners than your neighbors.

自分からはさらに 2 点指摘させてください。(もっとあるけど書ききれないので)

ひとつめ。

すべての汎用 PHP フレームワークはクソ!

誰も必要としていないのは、万能なフレームワークです。みんながみんな一般的な問題を抱えているわけではなく、みな非常に特殊な問題を抱え解決しようと試みています。

– ラスマス・ラードフ

ちょっとまてコラ !

この引用をフレームワークプロダクトを否定するのに使うのは、あまりにもラスマスに失礼じゃないか? え?!

これは、PHP Frameworks Day 2013 の公演で質疑応答の回答の抜粋で、まさにその質問と回答が YouTube で公開されています。

www.youtube.com

回答いきなり "They all sucks" で会場大爆笑です。すばらしいつかみネタでした。そして、次のように続いています。

"So, while all these sucks, everyone needs a framework, while everyone doesn't need a general purpose framework. Nobody has the general problem..."

見比べると、間にあった一節がチョッキンされていますね。「ま、ぜんぶクソだけどさ、みんな何かフレームワークは必要としている、でも、なんでも万能フレームワークじゃない」だいぶ意味が違いますね。だいたい、PHP Frameworks Day に来てフレームワーク全否定するとか、どんだけ空気読めんのかって話になっちゃいますよ、ありえいないでしょ。

ラスマスが言いたかったのは、そりゃ畑違いの人からしたら、目的の異なるフレームワークは役に立たないしクソって言われるのわかるよ、つまり PHP には汎用で万能なフレームワークなんてニーズは実はなくて、みんなそれぞれいろんなレイヤーで PHP を使っている、だからフレームワークは多様だし、たとえ誰かがアレはクソだこっちのほうが優れていると言っていたとしても、問題を共有する人たちにとっては、他人にはわからない大事な価値観があって、PHP はその多様性を支える言語なんだと、そういうことじゃないですか?

このスタンスは本当に素晴らしく、フレームワークの各コミュニティの関係に良い影響を与えただろうと思っています。同じようなことを日本の PHP カンファレンスでも言ってました。たしか「この会場に来られている皆さんはクレイジーなこととお思いかもしれませんが、PHP7 は WordPress のパフォーマンス向上を非常に重視しています」と。

これを、既成のフレームワークを否定して自作主義を後押しする文脈で引用するのは、もしわざとなら、PHPer の風上にも置けやしねぇってもんですよ、ほんとに。他も、ちょっと引用のニュアンス違うんじゃないかと思う箇所もあったけど、とにかくこれが飛び抜けてひどいですね。

あと、「誰が何を言っているかは問題ではない」と後から FAQ で言うのなら、有名人の引用を挟むのはチートですよね。違うでしょ。誰が何を言ったかは、その発言の背景が非常に重要です。そこもっかい考えて、ラスマス動画を拝みましょう。

ふたつめ。

そして以前のプログラマーフレームワーク A またはフレームワーク B を使っていたら人日が節約できたのにと、泣き言を言いだします。

これはプロのプログラマーのメンタリティではありません。こんなこと誰もしません。

は?

プレーン PHP で書かれたコードを2年以上かけてどうにかフレームワーク化した件で、メンバーがどれだけ前の外注に呪いの言葉を吐いたかって話、しようか?

確かに、恐ろしいコード、おそらくはじめから設計されていなかったコード、またはクライアントが書き直しを選択したくなくて何度も自己成長しているであろうコード、といったものは存在し、コードが悪すぎてもうあなたには手に負えないとしても、どんなフレームワークもこのような状況を防いでくれはしません。これはよくあるプログラムの自然な成長プロセスです。とにかく、どんな種類のフレームワークも結局は断片化してしまいます。

恐ろしいスパゲッティコードが存在することは確かですが、誰も恐ろしいスパゲッティコードを意図的に作りはしません。場合によっては経験不足の結果かもしれませんし、クライアントのせいで開発の途中で何度か仕様を変更したというのはしょっちゅうですが、その両方のいずれの場合でも、フレームワークを使用したところで結果はスパゲッティコードになります。また、どれだけオブジェクト指向パラダイムが使用されても、結果はやはりスパゲッティコードになります。

プログラマとして、私たちがみな回避しようとするこのような状況ですが、これは普通のことで、これは プログラミングの芸術 で、これは プログラマであること が意味するもののひとつなのです!

読みにくいわ!

いやこれ、翻訳力なくて申し訳ないんですが、原文でもこんな雰囲気で... 誤読させようとしてるのかなって感じです。ようするに「他人のコードを恐れること」の章は、ソフトウェア・エンジニアリングの全面否定です。

  • 率直に言ってやばいコード
  • 設計なしでスタートする開発
  • 顧客がリライト工数を嫌がって秘伝のタレ化
  • 初心者に書かせてスパゲッティ化
  • 顧客が途中で仕様変更を連発

これが「よくあるプログラムの自然な成長プロセス」であり、「回避しようとする状況」ではなく「普通のこと」で、「プログラマーとはつまりこういう意味の職業」だそうです。ありがとうございました素晴らしい社畜っぷりですね。

フレームワークオブジェクト指向では救済できないって...? いや、そういう問題に対して、もっとも救済の手を差し伸べてくれているのがこいつらですけど。現代ソフトウェアが複雑さを破綻させずに済んでいるのは、その歴史にオブジェクト指向があったおかげです。複雑さに根性は無効、という当たり前の人道的なエンジニアリングマインドは、オブジェクト指向とともに育ったと自分は認識していますが。

ていうか...

率直に言ってやばいコード → オブジェクト群をフォルダで区切り、別リポジトリにするなどして相互に不可侵に。で、片方に溜まった負債は早くリファクタリングで返済しましょう。今だと、やばいコードには PHPStan を CI 回すのが効きます。PhpStorm の黄色はコミット通しちゃだめです。

設計なしでスタートする開発 → 書く前に設計しないとかありえないので早く逃げて。設計というのはドキュメントを書くことじゃなくて、作ろうとしているものが何であるかという概念を決めること、どのように実現するかの仮説検証のことですよ。材木を買ってきてなんとなく釘を打っているうちに犬小屋っぽくなってきたから犬を入れようみたいなものを開発と呼ぶなら、幼稚園児にレゴで遊ばせておけばいいのです。小学生でも夏休みの工作はまず計画からやるでしょう。

顧客がリライト工数を嫌がって秘伝のタレ化 → タレの消費期限を見積もって、それ以上の契約では事故っても無保証かつ新規と同じ見積もり基準で請求します、を通す。借金してでもデッドラインまでに工数捻出したほうが有利と顧客にわからせる。こうしないと、病気になると知っていながら厳しいことは教えない医者と同じで、言う事言って聞かない相手は (目先の損に見えても、あなたに実力があるなら長い目で見て得だから) 切っていくぐらいがちょうどいいです。

初心者に書かせてスパゲッティ化 → スパゲッティになるほど広いスコープを初心者に任せるの、完全にマネジメントのミスだし経験者の指導ミスですね。まずは、誰の目にも十分と思えるエキスパートを雇い、初心者の技能を一定水準まで引き上げましょう。

顧客が途中で仕様変更を連発 → スパゲッティ化するレベルの変更要求が起きた時点で、これまでの分をフリーズして再見積。見積工数と検証の手間もリセット。当たり前。逆に、問題なくイテレーション回せる範囲の変更で品質が下がるようでは、そもそも部分部分への責務分配の設計に問題があります。骨格を変えるならビル工事は中止、だからって内装を変更したら傾くビルは欠陥建築。

やれやれ... これが「経験と実践」の正体なのかと。ウォーターフォールさえない原始時代ですかね。なんら改善しようという模索なしに、受け入れろですか。受け入れるつらみを後に残さないようにではなく、将来の世代にも不幸の連鎖を続けさせろと。それどこの泥舟大企業のサラリーマンの話ですかね。(泥舟でも大企業ならマシなほうか。零細の大企業病は目も当てられないですよ)

そういう現実がある、はしょうがない、けど、何もしないのがプロだとかそういう言説は、だったら黙ってろこっちのやる気削ぐなとしか。議論する気がないのはどっちですかっていうね。

知識的なことはいくらか間違うかもしれないから目をつぶっても、ここで根本的なメンタリティに問題がある証拠がある以上、もうだめです。アウト。

Wrong Way: PHP - Wrong Way itself

我慢ならないのでひとこと言わせてもらいますよ。

まずは素直に学んでください。オブジェクト指向のセオリー の中でも、パッケージ原則に登場する「単方向依存」という概念は特に重要です。既成のフレームワークによる制約レベルを下げたいなら、依存の向きに最大限の注意を払ってください。何も考えていないとすぐに依存方向が双方向になって結合が密になります。呼ぶ側と呼ばれる側の間に、依存関係反転原則が成り立つ箇所がないかを見つけなければなりません。デザインパターンと言えるかどうかわかりませんが、抽象度の高いライブラリが共通して持っている様式は、とても参考になります。依存の向きの設計には高い能力が求められるわりに、費用対効果の高い仕事とは見られません。なので、プロジェクト規模が大きくなれば、惰性で書き足し開発せずに、機能と層を分け、できるだけ制約の強い既成のフレームワークに一方的に依存できる箇所を抜き出してください。価値の高いプログラムを書くために、プログラムを書かない選択をするのです。

オブジェクト指向デザインパターンフレームワークも、考えずに使うものではなく、むしろ、考える材料として常にストックしておいてください。もし、ドメインモデルが貧血になろうと今回はトランザクションスクリプトが適している、という答えが出たのなら、それはそれでかまいません。それが本当の意味での "Not Always" ということです。見向きもしない、見なくていいから学びもしない、というのは "Always Not" です。

「あらゆる箇所をオブジェクト指向で設計する必要はない」と「すべての領域でオブジェクト指向が役に立たない」を区別できない種類の人は、かわいそうですが、そもそもプログラミング仕事の適性がないと言わざるをえません。どうせ人間はそういうレトリックを区別できないからごまかせると考えている確信犯もナメすぎててダメです。

はー

さてそろそろ皆さん、Wrong Way を読んで笑ったり引いたりできるようになってきたでしょうか。じゃあもう一歩だけ、私の話に付き合ってもらいますよ。

いまみなさんは、ロンドンで Laravel を笑った Symfony ユーザーと同じポジションにいます。笑えば笑うほど、彼らは頑なに殻にこもるのです。なぜなら、正しいかどうかではなく、ある方法で「やった! 自分にもできた」「初めて違和感ない感じだった」という原体験を得た者は、その技術ブランドに強くアイデンティティを持って行かれます。手続き型でうまくやれる人ほど、関数型を理解するのが困難といった現象と同じです。これは不思議なことに、技術の優劣とは関係がありません。

Symfony から言わせれば、app() を通じて気軽にシングルトンにアクセスできるのは邪道の極みです。本来なくても成り立つインターフェースが、Laravel を構成するものとしてひとつのパッケージに収まっていて分離できないのも、スジがいいとは言えません。よりカジュアルで浅いように見せかけながら、パフォーマンスは Symfony よりもかなり落ちています。原理原則に忠実という意味ではよほど Symfony のほうがシンプルで整然としているのに、あれで Beautiful とかいう看板を掲げて、なんやねん言うたもん勝ちかと不愉快になるのもわかります。

おっと Laravel のひと、ここで技術的な言い訳をしたら Wrong Way と同じですよ。まずは素直に、なるほどそれはごもっとも、精進します。と返しましょう。それから、けれどどちらがより多くの人に価値を届けられたかでいえば、けして悪い仕事はしてないと思うんですよ。まあ、フランス人はアメリカを不愉快と思うのはわかりますよ、それはしょうがないよね。どうですか。

(ちなみに誰が言ったかという文脈はとても大事で、Yii ユーザーの自分は「こっちの方が先にロケット飛ばしたのにアメリカちくしょう」と、フランスよりよっぽどこじらせてるロシア側なんで)

そう来れば、こんどは良い意味での笑いが取れるんじゃないですか。この器がラスマスの "They all sucks" だったと思うんですね。ちくしょうバカにしやがって、ってムキになると、技術の優劣が自意識に直結しててカッとなるやつで、負けを認めてるのと同じです。フレームワーク使ってなかったとか異常者だなんて誰も言ってないのに、そういう種類のコンプレックスを抱えてしまいまうやつですよ。

そういう目で、Wrong Way の一派に対して何ができるか、どのようにアドバイスできるか、互いの価値を対等にシェアし合えるか、もっと真剣に考えないといけないように思います。

自分の偏見で申し訳ないのですが、PHP のコミュニティって、ここが平均だろうという線を引くと、その線から大きく外れた 2 つのクラスタが形成される感じがあります。たんに有能/無能という話ではなくて、たとえば、「爆発的ヒットの自社サービスで働く人たち」と「多重下請けの底辺でスーパー火消しやる人たち」だとか、それこそ「ユースケースむちゃくちゃ多い複合システムでセキュアコーディングを矯正してくれるフレームワークが重要」と「フレームワークを使ってシングルサイトを密結合で速くローンチできないと競争力を失う」の対立、だとか。

対立するクラスタは、互いに相手クラスタの底辺を見て「あいつらはバカだ」と言って自分を慰めるんですね。もしかしたら、本当に実務的な理由で Laravel を選んだ人が、用もないのに Symfony が偉いとイキって使う初心者を見てトホホと思うかもしれません。わけもわからずオールインワンなフレームワークに振り回される初心者を見て、Zend 1 の頃から必要最小限のライブラリを入れ替えては代謝してきたシステムのベテランは、今はライブラリ豊富にあるからちょっと落ち着いて自分で組んでみる練習をしてからでも遅くないぞ、と感じているかもしれません。そんな関係なんだから、そもそも絶対的な優劣も、あいつらは神秘主義者だと相手を否定する動機もないんですよね。(PHPPHP を揶揄する人の使う言語の関係も、ずっとそうだったでしょ?)

だいたい、歯ブラシ (=PHP) の使い方でケンカするなんて、おまえら夫婦かよってことですわ。たまには相手の気持ちに先回りして、何かサプライズプレゼントでも買ってやりませんか。

あ、そういえばだいぶ Pinoco をほったらかしにしてたっけ...

フレームワークによる制約とオブジェクト指向の学習コストに対処するには、できないできないと怒ったりわめいたりするんじゃなくて、たとえば、オブジェクト指向を駆使してオブジェクト指向の要らないフレームワークを作ってやるというアプローチもありますよね。

Right Way: As a programmer, create, share and act before rant.

以上、期待以上のものを見つけてしまったというポエムでした。ここ、はてなブログ! イエー!