クソコード批判とクソコード批判批判はなぜ燃えるのか

Short Answer:批判は人格否定だからです。

Long Answer:

知的活動の成果物とアイデンティティ

文脈 note.mu

要約すると、「自分の書いたコードと自分のアイデンティティは不可分であり、コードを否定されるのはアイデンティティを否定されることに等しい」という話と、「研究への批判は人格に対する批判を意図してはいないので、それらを混同するべきではない」という話であり、一般化すると「知的活動の成果とアイデンティティを同一視するのは妥当であるか」という問題になると思う。話が面倒になるので、本当に人格攻撃がしたくて批判しているケースはここでは考えない(現実の批判は、両者が様々な割合で混ざっているものだと思う)。

この問題に対する答えは、おそらく立場によって異なる。成果物を出す側、すなわちこの文脈で批判を受ける側としては、成果物とアイデンティティは多かれ少なかれ同一視することが普通ではないかと思う。成果物とは自己顕示欲を満たすものであり、それまでに培ってきた思索の質を反映するものであり、人生の少なくない時間を費やした努力の成果である。しかも現代社会では、試験や評定といった形で思考の質を評価することが一般に行われており、この尺度において多くの人に受け入れられることが高い社会的立場、つまりアイデンティティに直結すると言って良い。このような状況で、思考の果てに生み出した成果物を否定されることは、直接的にせよ間接的にせよ、思考の質を否定されていることと同じであり、ひいてはアイデンティティを脅かすものである、という解釈は十分に納得できる。

一方で、批判する側はこの文脈からは容易に離れていられる。既に何らかの成果物がある場合、そこに思いつく限りの具体例やパターンを当てはめてみることにより、理想的な形からの逸脱は比較的容易に発見できる。ことプログラミングや研究に関しては、前提条件に形式的な操作を施すことで論理的に導かれる帰結が重視される傾向にあるため、一つの不整合は成果物の価値を毀損するのに十分な影響がある。そういった不整合を発見した場合であっても、批判側は成果物の表現する論理に形式的な操作を行い、その結果を報告しただけであるから、成果物の背後にアイデンティティが密着しているという事実は用いておらず、議論に用いていないのだから無関係だと主張したくなるのも、批判側の視点としてはあながち的外れではない。もちろん、提示した反例が実は誤っているというケースはありえるし、反例の瑕疵を指摘された場合には彼我が逆転して一転アイデンティティの危機となる可能性もある。しかし、批判は常に後出しになるため、批判側は自信がなければ黙っていることができるから、よっぽどの理由がない場合は安全圏からものを言うことができる。

かくして、批判側は成果物そのものの価値を、それを生み出した人格とは切り離して評価していると考える一方で、受け手は成果物を貫通してアイデンティティを攻撃されているように感じるという構造ができる。批判という行為の性質上、この非対称性を変えるのは難しいから、解決策としては互いの意識を調整するというあたりが落とし所になる。つまり、批判側はそれがどのような種類の批判であっても、本質的には受け手にとって人格攻撃の性質をもつという点を理解し考慮すべきだし、受け手は批判の全てが人格へと向かっている訳ではないことを理解し、意識的に成果物とアイデンティティの距離を置くべきである。どちらの比重が大きくなるかは、知的活動の種類によると思う。例に挙げたプログラミングや研究であれば、瑕疵のない論理を組み上げることが重要であるため、受け手は自分のアイデンティティたる成果物の一部を放棄し、瑕疵を取り除く勇気をもつようにしたほうが有益だろう。逆にアイデンティティの表現そのものが目的である、絵画や音楽といった芸術作品を批判する場合には、表面的な指摘からは想像できないほどに相手の深部を傷つける可能性があることに留意したい。

このバランスを見誤ったとき、批判は燃える。微妙なコードを強く批判すると、相手は傷つく。傷ついた人は批判されたことを批判する。批判側は有利な立場とは言え、それは批判の内容についてであり、批判するという行為そのものについては大抵ノーガードだから、やはり傷つく。互いに殴ったらあとはもう戦争しかない。特にTwitterなんかやってるような人は脳を止めて脊髄反射で会話してるので、見たいものしか見ないし書きたいものしか書かないし行間は読まない。後には焼けただれた荒野だけが残る。

元のNoteでも紹介されていた、ポール・グレアムアイデンティティは控え目に」は、成果物とアイデンティティが分離していることを期待されるケースにおいて、この問題への効果的な対処法になっている。批判がアイデンティティに刺さる痛みが嫌なら、当たり判定を小さくすればいい。でも芸術家はこの手法使えないと思うんだけど、どうしてるんだろう。 blog.livedoor.jp

「クソ」コードという言葉

以上の議論は成果物とアイデンティティの関係に着目していたが、「クソコード批判」という文脈に固有(ただし、他の文脈への転用は容易)の問題として、「クソコード」という言葉の意味にも議論の余地がある。インターネット上や現実でのこの言葉の使われ方から考えると、「クソ」の部分の解釈には相当の幅があるように感じられる。この幅の一端では、「クソ」という言葉は完膚なきまでの否定であり、根本的に発想を変えなければ修正不可能であるような、大きい瑕疵を意味している。他方の端では、「クソ」は単なる二値分類のラベルであり、無謬ではないという程度の意味しかもっていない。このような広い解釈をもつ言葉を、特にコンセンサスもなく使った場合、大混乱をきたすことは火を見るよりも明らかであるし、更に人格否定の性質を多少なりとも内包しているのだから、収拾がつかなくなるのはほとんど当たり前とも言える。

自分はかなり軽い意味で「クソコード」という言葉を使う方だが、主な理由としては、瑕疵のあるコードを表現する語呂のいい言葉が他に存在しないという点が大きい。また、書いたコードとアイデンティティの分離度合いが大きく、少しでもまずいコードは書き直すことに抵抗がなかったり、そもそも自分の思いついたコードが最善であると絶対の自信をもって確信していることが少なく、改善の余地があるのにこの場で思いつけないのは自身の不徳のなすところであるという意識があるため、ほとんどのコードは多かれ少なかれ妥協を含む、完全ではないものだと思っている。加えて、プログラミングコンテスト等を通じて、点数や順位という比べやすい形で負けを意識することが普通だったため、「クソ」のような単語がもつネガティブなニュアンスについても、通常の人が感じるものより弱いのではないかと思う。

こういった意識で「クソコード」という言葉を使う人間が、「クソ」を重く捉える人と話せば、一瞬で齟齬が生じる。そして傷ついた人が経験を共有すると、軽く捉える人は「クソ」の部分を無視して、批判そのものを批判しているように解釈する。すると重く捉える人は反論を繰り返し……という負の連鎖が発生しているのではないかと思う。一般論として、Twitterのような文字数が制限されている上に脊髄反射で文章を書くようなプラットフォームでは、言葉の解釈が食い違っていることに気づくこと自体難しいし、気づいたとしても認識を擦り合わせるのは大変な労力を要する。でもTwitterでそんなめんどくさいことしたくないじゃん?かくしてTwitterは荒れ、批判は批判を呼び、炎はどんどん燃え盛り、人の精神を焼き切っていく。

十数行の変更で改善できる程度の、小さい瑕疵のあるコードをうまく言い表す言葉ってないんですかね。

結局どうすればいいの

  • 批判は人格攻撃なので、相手の精神状態をちゃんと見て調節したほうがいい。
  • 批判されても人格と切り離せるようにしておくとよい。人格攻撃したくてしてそうな奴からは得るものがないので逃げたほうがいい。
  • 「クソコード」よりカジュアルな言葉がほしい。
  • Twitterはクソ。

Spider-Man: Far From Home

Spider-Man: Far From Home

Tony Stark亡き後のヒーローとは何なのか?という話。TonyはPeterに入れ込んでいたみたいだけど、Tonyの技術者・経営者としての成功のような、自信を支えるバックグラウンドを持っていないPeterに押し付けるのは酷だよなあと思う。そのPeterも正体バレ+Beck殺しの濡れ衣を着せられてしまい、追い詰められていきそうで不穏な感じ。かつてのTony StarkもStark Industriesの兵器の流出問題で同じような立場に立たされていたけど、Tonyを支えた才能はPeterにはない。しかしPeterには支えてくれる仲間がいる……。これシンフォギアXVでは??やはりアイアンマンはシンフォギア(確信)

ホログラムを使って現実を上書きする戦闘もよかった。ニンジャスレイヤーのメンタリスト戦を彷彿とさせる、何を信じればいいのかどんどん分からなくなっていくトランス感が気持ちいい。こういうメタ系の演出は一般受けしないので普通の映画ではやんない印象があるけど、そもそも一見さんを容赦なく切り捨てているMCUだからできるのかなと思った。

ICFPC2019感想&反省

ICFPC2019が終わってもう一週間も経ってしまった。忘れないうちに感想と反省を書いておく。

リポジトリは生きてるサーバのパスワード等が入っているのでまだ公開しません。後処理をする前に中国旅行に来てしまったため……。

あ、チームは1kg cheeseです。Register直前までチームメンバーが好き勝手なチーム名を提案していてまとまらなかったが、yuustiがドミノ・ピザの1キロチーズピザを頼もうとか言い出したため、なし崩し的にこのチーム名になった。

コンテストの感想

問題文中でLambda LifterとPanterに言及しており、しかも3回アップデートが来るというそれらの回を踏襲したような形式から、また微妙な回かと思って戦々恐々としていたが、フタを開けてみればかなり良い問題だった。問題自体は適度な大きさの探索でとっつきやすく、プログラムを提出する必要がないのは安心感があるし、タイブレークとしてリアルタイム性のあるマイニング問題が出たのも新鮮味があった。

一方で、前半に要素を詰め込みすぎな感じはした。特に24時間ノンストップでLightningを終わらせて疲れ切った直後に、4時間でマイニング対応してねというのはなかなか辛い。体力を消耗して余裕がなくなる前に対処できるよう、最初からマイニングのようなリアルタイム性を要するシステムが来ると分かっていると良かった。

役割分担

今年はy3eadgbeが一身上の都合で抜けて、新しくkenkooooが入った。役割は以前とほぼ同じで、AI班がkawatea, yuusti, mkut、インフラがosa_k, amylase, kenkooooという分担になった。

  • ○役割分担、人数の割当て共に適切だった。
  • ✘インフラ班は人数が多かったものの、互いに互いのコードをちゃんと把握しておらず、ownerが寝ているときにトラブルが発生すると結構どうしようもなかった。特に今回はリアルタイム性が重要だったため、即時トラブル対処ができないと点数に直結してしまうので厳しかった。
    • 全員バラバラの言語かつモジュールでシステムを作っていたのが遠因となりシステムが把握しづらくなっていたので、全部入りの1モジュール構成にすれば見通しが良かったかもしれない。
    • MySQLにアクセスする部分はPythonを使っていたが、誰もPythonMySQLドライバの挙動をよく分かっておらず、異常に大量のコネクションを張ろうとして、サーバ側のコネクション制限に引っかかりまくって辛かった。
  • ✘インフラがいつ壊れるか戦々恐々としていると結構脳に負荷がかかるので、暇な時にAIを実装してみるといった遊びができなくて悲しい。
    • 自分は左手法で隙間を舐めていく動きがいいんじゃないかとずっと主張していたので実装したかったけど、余裕がなくて結局諦めてしまった。
    • 壊れにくく、かつ他人にメンテを投げやすい設計ができると負荷が軽減できるのでは?

解答ファイルの管理

前回まではソルバの出力をwrapperがポータルサイトREST APIを叩いてアップロードする形式だったが、今回は所定のディレクトリに置かれたファイルをIndexerが定期的に確認する方式にした。

  • ○前回までと同様、Flask製のポータルサイトMySQL Connection Error等で落ちまくっていたため、HTTP経由で生成した解答を登録する方式だとほぼ間違いなく死んでいた。
  • ○インフラが整わないうちに生成された解答をとりあえずコピーしておき、後で採点するというムーブができた。
  • ✘ファイルはコピーされたがIndexerにまだ検出されていない状態の解答が見えないため、AI班に待ちが発生してしまった
  • ✘解答のVerifyもIndexerにやらせてしまったため、バッチ実行の後などで解答が大量に生成された後はIndexerが遅くなった。
    • 新しいファイルを拾ってキューに入れるプロセスと、実際に採点と登録をするプロセスを分ければマルチプロセスできそう。
    • ソルバを実行するためのwrapperに採点まで組み込む構成も考えたが、verifierがおかしいことが後でわかった時のbackfillや、複数のマシンをセットアップした時にいちいちHeadless Chromeをセットアップしないといけなくて面倒くさいなどの、非本質的な部分でrejectしてしまった。ただ、AI作成者が自分のマシンでwrapperを走らせていたことも考えると、一概にダメとは言えなそう。

ソルバの管理

前回と同様、Gitリポジトリのmasterで指定されたパスにあるコードを make && ./run.sh する素朴な実装にした。

  • ○ソルバの更新がすぐに反映できた。
  • ○サーバ上で実行する限りにおいて、必ず最新の補助スクリプトを使うことを強制できた(2017年はブランチで分けたが、古い補助スクリプトが使われて問題を起こすケースがあった)。
  • ✘ソルバにバグが混入すると、その後もずっとバグり続けるのが厳しい。オフライン実行型のタスクなら普通は大きな問題にはならないが、今回はLambda Coinのマイニングというオンラインに近いタスクがあったため、バグったソルバのせいで解答に失敗することがあった。最終的に10万LMC程度損していると思われる。
    • ソルバをパッケージ化してfreezeし、可能な範囲で正しさが保証されているソルバを動かせるようにするべきだった(ディレクトリを切ることで擬似的にfreezeしてもらっていたが、間違ってバグっているコードで上書きする事故があった)。

マイニング

Lightning終了時点まで完全にオフラインの問題だと思っていたところに突然ぶっこまれたので、あまり複雑なシステムを実装する気力がなく、最終的にはその時点で有力だったソルバと、kawateaが作ったマップ生成プログラムを直列に実行してsubmitするスクリプトを書いた。

  • ○初回のマイニングが開始した時点ではとりあえず動いた。
  • ✘ずっと動かしていたら、問題サイズがある程度大きくなったところでソルバの実行に長時間かかるようになり、数回解答に失敗した。
    • 最終的に、マイニングのソルバも通常のシステムとマージして、強いCPUを使いつつ複数のソルバを並列で回せるようにした。もっと早くやっておくべきだった。

リポジトリ構成

単一のGitリポジトリにみんなでコミットする構成。特にブランチ分けやレビューなどしなかったので、無限にマージコンフリクトが起きて面倒だった。git pushのときに勝手にfetchしてrebaseするオプションとかありそうだけど……。

AWS OrganizationsとIAMユーザの設定

去年のICFPCの時に、AWS Organizationsを使って自分のメインアカウントの支払い情報を使いつつ、計算資源は完全に独立させる(メインアカウントを他の人に触ってほしくないため)という設定をした……ということがICFPC2018の感想に書いてあるんだけど、どうやって設定したのかが全く書き残されていなくて困った。

osak.hatenablog.jp

で、過去の自分ができたんだったら今の自分にできないことはないだろうと思ってボタンをポチポチしたらできたので、今後のために書き残しておく。

Organizationの下にアカウントを作る

まず、AWS Organizaitons (https://console.aws.amazon.com/organizations/home)を開く。画面はこんな感じ。

f:id:osa_k:20190527154858p:plain

"Add Account" と書いてあるボタンをクリックすると、Invite AccountかCreate Accountか聞かれる。ここではCreate Accountを選ぶことにする。すると新しいアカウントの名前とメールアドレスを聞かれるので、適当な名前と自分が管理している適当なアドレスを指定する。

これでアカウントは作成されるが、特にこの画面からログインできる訳ではないので、一旦ログアウトするか、Incognitoでもう1枚ブラウザを開いて、さっき指定したメールアドレスでログインする。パスワードを聞かれるが、当然そんなものは設定していないので "Forget Password" からパスワードをリセットする。そうすると新しく作ったアカウントで入れるようになる。

新規アカウントにアクセスできるユーザを作る

IAM (https://console.aws.amazon.com/iam/home)を開き、左のメニューからUsersを選ぶ。"Add User" と書いてあるボタンをクリックするとユーザが作成できる。Programmatic Accessを選ぶとAWS CLI経由のアクセスを許可でき、AWS Management Console Accessを選ぶとAWS Consoleへのアクセスを許可できる。

パーミッションは適宜設定する。この用途だとBilling以外の全てにアクセスできるアカウントが作成できると一番いいんだけど、今回は十分に信頼できる人しか触らないことが分かっているのでAdministratorAccessを付与した。PolicyのJSONを自分でいじればBillingのアクセスだけ落とすのもできると思う。

この方法で作成されたアカウントは、AWSアカウントにひも付いたConsole Sign-in Linkからログインする必要がある(たぶんAWSアカウントのIDをEmail代わりにログイン画面で入力してもいける)。このリンクを知る方法は複数あるっぽいが、とりあえずユーザの詳細ページからSecurity Credentialsタブを開くと見える。

f:id:osa_k:20190527160309p:plain

とりあえずここまで設定できれば、後は勘でなんとかなると思う。

Detective Pikachu

Detective Pikachuを見た。

ポケモンの描写は結構良かった。所々に入るオマージュがニヤッとする。プリンとか、ポケモン亜空間とか。しかし全体的にはあんまりまとまりが無いなと感じた。ピカチュウが折角くたびれたオッサンの声で喋っているのに、あんまりメチャクチャなことをしないので、その違和感をどうにも生かしきれてない気がする。Guardians of the GalaxyのRocketみたいな、妙にニヒルで言葉巧みに罵倒してくるようなキャラクターを想定していたのでちょっと肩透かしだった。

ストーリーも、なんかよく分からんうちに二転三転して、気づいたらラスボスのHowardが人類補完計画をしている感じ。序盤でTimがリザードンに殴りかかっていったシーンはポケスペ展開か?と思ったけど、その後は人 vs. ポケモンの構図がほとんどなくて、それも残念。

上映前に入るトレイラーの宣伝を見る限り、Detective Pikachu自体が子供向けにデザインされているっぽいので、Guardians of the Galaxyレベルのナンセンスやアグレッシブな展開を求めるのは酷なんだろうとは思うけど、トレイラーで想定していたのがそういう方向性だったので、期待を下回ってしまった感がある。

Avengers: Endgame

Avengers: Endgame

Captain Marvel以外一通り観たのでもう一度Avengers: Endgameを観てきた。なんも知らずに観た初回でも結構面白いと思っていたけど、シリーズを一通り観てから改めてEndgameを観ると全然違う。単に格好良く、もしくは面白く見せるための演出だと思っていたもののほとんどに実はちゃんと意味があり、どれを取っても過去との対比に感動がある。

魔術師勢はやはり強いなあと思った。特にThe Ancient OneとDoctor Strangeの、時間を超越して全てを見通している感じが好き。StrangeがTime StoneをThanosに差し出したと聞かされたThe Ancient Oneが、それには何か意味があるに違いないと理解してBannerに差し出す、絶対の信頼感が良い。そのStrangeもThanos戦でTonyになぜあらかじめ言っておかなかったのか問い詰められたとき、If I was told you, it would not happenという、全てを見通したかのような答えを返すのが最高に格好いい。Infinity WarでStrangeが見た勝利のビジョンはこれだったのか、と全てが腑に落ちるシーンだった。

2012年に飛んだCaptain Americaも良い。特にHydraからLokiの槍を取り返すシーン、エレベーターで囲まれるシチュエーション自体が明らかにCivil Warを意識していてどうなるかと思いきや、Hail Hydraの一言で信頼を得る流れは鮮やかだったし、20作使って張った伏線を満を持して回収するという、演出の技巧が光る。その後Captain同士で殴り合う時の "I can do this all day" "I know, i know" もセルフオマージュとパロディを重ねているうまいシーンだった。更に、Thanos戦でついにThorのミョルニールを手にすることになったのもアツい。初見時は単に武器を交換しただけだと思っていたけど、ふさわしい者しか手にできないというミョルニールの性質を知ってから観ると、Captainが本当に世界を背負うCaptainになったんだなあという感銘がある。

そしてTonyの死。I'm an Iron Manと言ってSnapする、ヒーローとして今まで積み重ねてきたもの全ての集大成。思えばこの映画はTonyにとって大切なものを全て再訪していく、Tonyのためのような映画だった。Potsと結婚して、娘ができて、Captainと仲直りして、過去で父親の想いを聞いて、Peterも取り戻して……。その果てが、自己犠牲のヒーローとしてのIron Manの最大の自己犠牲と、望み得る限り最大の勝利であるのが、いかにもTonyらしいなと思う。

伏線を活用する作品が好きだからという理由でシリーズを観始めて、ここEndgameに到達して、本当にその価値があったと感じた。個々の作品のクオリティは色々だったけど、その全てがEndgameに繋がり、またEndgameがその全てを参照していると思うと、全体で1つの作品だとしか言えないし、この体験をするためには全部を観る必要があったのは間違いない。

Ant-Man and the Wasp

Ant-Man and the Wasp

Ant-Manの2作目だけど、Infinity Warの頃から話が始まる。

Hank博士のラボで量子トンネルが出てきたので、ここで事故が起きてScottが巻き込まれてEndgameに繋がる感じなのかなと思っていたら、それ自体は平和に終わってしまった。エンドクレジット後の、Hank博士一家が灰になってしまうシーンは、そうなると分かっていてもきつい。こういうのを見るとThanos許せんなという気持ちになってくる(単純)。

1作目と比べると、小さくなるギミックを使ったダイナミックなアクションも、コミカルなシーンも少なくなっているのが残念だった。


Captain Marvelはまだネットで視聴できないみたいなので、ひとまず飛ばして今週末あたりにもう一度Endgameを見に行きたい。