世界を動かす技術を、日本語で。

「愚かな」コードを書いてみよう

概要

  • 「バカな」コードを書くことの大切さ についての体験談
  • 音楽家志望からプログラマーへの転身 の経緯
  • 失敗や試行錯誤を通じた成長 の重要性
  • 新しい技術やツールに挑戦する楽しさ
  • 自分自身にもっと寛容になるべきだというメッセージ

「バカな」コードを書こう

  • 2010年に学校を卒業、音楽家を目指していた経緯
  • 母親の勧めでTAFE(オーストラリアの職業訓練校)に入学、コンピュータとゲームが好きだったためコンピュータ系コースを選択
  • プログラミング未経験 だったが、VB.NETの教科書を使って独学
  • 苦労しながらも理解できるようになり、プログラミングに夢中
  • ゲーム開発のディプロマや学士課程で多くの「バカな」コードを書いた経験
  • ゲームジャムや趣味、大学、キャリア初期での試行錯誤
  • こうした経験がスキル向上や学びにつながった実感

新しい技術に挑戦する姿勢

  • 最近はJavaScript/TypeScriptやNodeJS、Denoなどのランタイムを学習
  • James SnellのNode Streams APIの講演をきっかけに、まずは簡単なストックティッカーを作成
  • 「なぜ最初は躊躇したのか」と自問自答
  • インスピレーション用の小さなアプリを作る際も同じ迷いを感じたが、Denoのバイナリコンパイルを試したくて結局作成
  • 完成したことで大きな満足感、新しい技術を使うことへのワクワク感

自分に寛容になろう

  • 長年の経験から自分のコードに厳しくなりすぎていたことに気づく
  • 「バカな」コードを書くことを恐れる必要はないという自己認識
  • 自分のためのコードは、綺麗でなくても良いという許容
  • 新しいランタイムや言語にどんどん挑戦し、壊して学ぶ姿勢の重要性
  • 学び続けるマインドセットがキャリアや趣味の楽しみに直結するという実感

読者へのメッセージ

  • 自分自身への寛容さを持ち、「バカな」コードを書くことを恐れないことの推奨
  • コードに「バカ」も「賢い」もない、ただのコードであるという認識
  • 自分の好奇心を大切にし、挑戦と学びを楽しむことのすすめ

Hackerたちの意見

写真の授業での量と質のグループを思い出すなぁ。やってみることで、いろいろ学べるんだよね。遊びに行こう!

量には独自の質がある。

その結論には大体同意するけど、ちょっと naive すぎるかも。量のグループはメトリックを「ハック」する簡単な方法があるんだ。何でも写真を撮りまくるだけでいいから。カメラをセットして、昼夜問わず自動で写真を撮らせることもできる。正直言って、動かない壁の前でやってない限り、良い写真が撮れる確率は高いと思う。サンプルが十分あれば、ほんの小さな確率でも期待される結果になるからね。でも、本当の魔法の成分は説明にあると思う。>「グループは自分たちの作品の質を気にしなかったので、照明や構図などを試す時間を持っていた。」この文を読むと、「量のグループは成績に自信を持っていたから、プレッシャーなしで創造的になれた」ってことだと思う。でも、もし実験を変更して、学生を曲線で評価し、撮った写真の数に比例させたら、結果は違ってくるかもしれない。誰かが「ただ写真を撮りまくってるだけだ」って伝えるだけで、成績が不安定に感じるかもしれない。この状況では、質のグループよりも探索や実験の能力がさらに少なくなると思う。でも、メッセージは正しいと思うし、創造的な仕事や主に頭を使う仕事(コーディングを含む)ではこの戦略が正しいと思う。プロセスが創造性に依存するほど、このタイプの探索や自由に多くの時間を割く必要がある。研究のような仕事では、これが構造の基礎になるべきで、評価基準はほとんど取り除いて、基本的にアドホックな性質を受け入れるべきだと思う。コーディングのようなことでは、もっとミックスが必要で、その適切なミックスは実際の目的に大きく依存すると思う。だから、何がその目的なのかを考える上で、この区別が重要だと思った。

2010年に学校を卒業したとき(もうずいぶん前だね)、ミュージシャンになりたいと思ったんだ。パンクバンドが現場で学ぶなら、俺もできるだろうって。だけど、母さんは何かをする必要があるって言ってた。面白い偶然だよね。俺もロックスターになりたかったし、少なくとも成功したミュージシャンになりたかった。母さんもそれを止めたんだ。彼女の主張は、「学校で学べないなら、楽しいことを学ぶために学校に行きなさい、例えば数学とか。それからロックスターになれるかもよ。プログラマーにもなれるし、プログラミングはもう学んでたから。」ってことで、数学専攻で大学に行って、最終的には物理学の学位を取得した。今も音楽をやってるけど、フルタイムではなく、日中の仕事で自分を支えられる安心感がある。

幸運なことに、成功しなきゃいけないプレッシャーなしでミュージシャンを目指すことができるよ。この道を進んでいけば、いつか自分自身で成功を宣言できる日が来る。

学校でロボティクスを専攻しなかったことを本当に後悔してる。プログラミングがしたかったから、コンピュータ工学を勉強したけど、授業ではあまり吸収できなかったな。でも、学校が持ってたロボティクスの設備や指導を受けることはもうできないだろうし。もちろん、何かを試すのに遅すぎることはないけど、比較的小規模なクラスでの構造化された高等教育にはかなわないと思う(ロボティクス専攻はたしか24人くらいだったかな?)。

面白い偶然だね。俺もロックスターになりたかったし、少なくとも成功したミュージシャンになりたかった。 今も音楽はやってるけど、フルタイムじゃなくて、日中の仕事で自分を支えながらやってる。人によっては「夢を追いかけなきゃ後悔するよ」って言うけど、これは自分の選択を後悔してる人が言うことだよね。他の人は「夢を仕事にしちゃダメ、そうすると特別じゃなくなるから」って言うけど、これは夢を追うことが何を意味するかを誤解してる人が言ってる。俺はこう思う。幸せは追いかける夢や選んだ職業にはない。毎日自分が何をするか、どう見るか、そしてそれを持つことを許すかの選択にあるんだ。毎日を構成するものは重要じゃない。でも、これは俺の考え。

自分のコードの多くは最初はバカみたいだけど、徐々に洗練されていくことを願ってる。

まずやってみて、それから正しくやって、最後にもっと良くする。

確かにそうだね。最初は「バカな」コードを書いて momentum を作るべきだと思う。早くコードを書き始めれば、早く自分のアイデアを形にできるし、解決しようとしている問題のメンタルモデルの欠陥を見つけられる。昔は先を考えたり、計画を立てたりして「設計」しようとしてたけど、ただ「何かを紙に書く」ことが頭の中の多くの仮定を修正するって気づいたんだ。ある同僚が「何かを動かす」ことを勧めてくれて、そこから反復するやり方に完全に変わった。最初のバージョンが「バカ」でも、ハックっぽくてもね!

これは大体正しいと思うけど、メンタルモデルを持つことと反復することの必要性も強調したい。プログラマーがモデルを考えずにプログラミングを始めて、ただコードを重ねて問題を解決しようとするのはよくあることだと思う。最初の「動く」実装で満足して、反復しないプログラマーも多い。最近は、プログラムについて考えることが少なすぎる気がする。コードを書く前に、少しでも紙にマッピングすることが大事だと思う。

事前にハード要件を知っておくことは、正しいものを作るために重要だよね。「一時的な」ものが本番環境に乗っかって、ずっと残っているのは怖い。もちろん、緩やかな結合や明確なインターフェースがこれを助けるけど、簡単な例として「シングルプレイヤーバージョンを作るだけ」っていうのは、野菜を食べるよりも悪いことがあるかもしれない。マルチプレイヤーを後から追加するのは難しいから、最初からそのつもりで作る方がいい。

「スタートするために“バカな”コードを書いた方がいいと思うよ。 momentumを得るためにね。最初のイテレーションに依存しすぎると、プロジェクトやスタートアップ全体が技術的負債に溺れちゃうかも。だから、飛び込むのは次の条件があるときだけだよ:A) それが一回限りのもので、すぐに結果が欲しいとかデモ用とか B) 捨てやすくて、誰もそれを出荷しようとしたり、メンテナンスさせようとしない場合。とはいえ、あまりにも摩擦が多くて分析麻痺になって、何も出荷できないのも良くないね。」

俺は両方やることが多いよ。時間はかかるけど、全体的なアーキテクチャが良くなる。最初に機能的なものをゼロから書いて、要件や制約を理解するんだ。それが有機的に成長して、アーキテクチャは悪くなる。製品をよりよく理解したら、まずはより良いアーキテクチャについて深く考えてから、基本的にゼロから書き直す。複雑な製品では、何度もイテレーションが必要になることもある。

だから、コードを書かない「ソフトウェアアーキテクト」は好きじゃないんだ。自分が設計したコードすら書かない人は特に。

いつもアーキテクチャを考えておくべきだよ。でも、今のアプリケーションの規模や複雑さに合ったものであるべきだね。5年後の姿を想像するんじゃなくて。進化させていくのはいいけど、常に持っておくことが大事。

「まずは存在させろ。後で良くすればいい」っていうフレーズが、周りの界隈でちょっとしたマントラになってるよね。

動くプロトタイプがあれば、コードだけじゃなくて仕様やユーザーもテストできるからね。

だから、ソフトウェアエンジニアリングの職業が嫌いなんだ。出すために「バカなコード」を書いて、昇進して次の仕事に移って、未来のエンジニアがそのゴタゴタを片付けなきゃいけなくなる。だけど、経営陣や他の人たちは、未来のエンジニアがなんでそんなに苦労してるのか、技術的負債がなんでこんなに多いのか、そして大きな改善にはなぜ大規模な再作業やリファクタリングが必要なのか理解しないんだよね。だから、バカなコードを書いた人は昇進して良く見えるけど、その後のゴタゴタを処理する人は悪く見えちゃうんだ。

以前は先を考えたり、計画を立てたり、「アーキテクト」しようとしてたんだ。 何をするかによるよね。ネットワークプロトコルを作るなら、構築を始める前に慎重にアーキテクトするべきだし(他の人もそうするかもね)。問題は「これを間違えたら、どれくらい影響があるのか?」ってこと。コアサービスのAPIを間違えると大きな影響が出るけど、小さなモバイルアプリを書くのはそのアプリ自身にしか影響しない。でも、もし小さなアプリの反復を始める前にそのことを考えたら、もうアーキテクチャの決定をしてるってことだよね :-)。

この投稿には賛成も反対もあるけど、誤解してるかもしれない。最後の方でこう書いてある:「楽しんで書いて、あなたのためなら綺麗である必要はない。楽しんで、新しいランタイムや言語を試してみて。」これは、あなたのためでなくても綺麗である必要はないってこと。プロトタイピングの価値は常にあって、メンタルモデルを洗練させたり、仮定を検証したり、自分の考え(またはチームの)にギャップを見つけたりするために非常に具体的なんだ。残念ながら、今は完全に逆の方向に振れている気がする。計画や無限のチケットを書いて、実際にコードを書く前に何週間もそれを洗練するのは、ソフトウェアを作る上で逆効果だよね。計画モードにハマると、間違った仮定が育って、デザインに組み込まれていくから、埋没コストがどんどん増えていく。チームと一緒に基本的で共有されたメンタルモデルを持って、プロトタイピングを始めるだけでいい。LLMのおかげでこれが信じられないほど安くなった。でも、業界はまだ間違った方向に進んでいる。

俺の考えでは、特定のタイプのソフトウェアにはテストや計画、メンテナンスが不要だと思う。プロトタイプ(スタートアップ)は「正しく作る」贅沢はあまりないから、実際の目標は「市場に早く出すこと(そして市場を維持するために十分に動作させること)」だよね。ゲーム開発者は、だいたい作って出荷して終わり、プレイヤーはほとんどのバグを許容するし、すぐに次のキラキラしたものに移るから、すべてを修正する時間が来る前に進んでしまう。製品が市場で traction を得て、支払い顧客ができたら、その時に負荷(スケールアップ)やバグに対処するべきだと思う。どこかで読んだことがあるけど、スタートアップチームは解散させた方がいい、彼らは仕事を終えたから(次の素晴らしいアイデアに進む自由がある)、スケールアップチームに置き換えるべきだ。彼らが計画や設計、ソフトウェアの長期的なライフサイクルの準備をする。例えば、Facebookのアプローチはうまくいったと思う。彼らは市場をすぐにキャッチしたPHPプロトタイプを持っていたし、(俺の意見では)スケールアップチームに移行すべきだった。元のコードをファサードとして使い、何か新しいもの(当時はJava/C++が利用可能だったけど、今はGoを勧める)に置き換えることができたはずだ。

綺麗である必要はない EVEN IF あなたのためでなくても。 計画には「演劇」がたくさんあって、実際にコードを書く前に何週間も無限のチケットを書いて洗練するのは、ソフトウェアを作る上で逆効果だよね。 「高給の仕事」があって、プロトタイピングや問題のモデリングを始めて、反復的に完全なソリューションに改善していけるなら最高だと思う。改善の雪だるま式の進展や機能の完全性が「納品スピード」の加速として現れるのは否定しないし、コードを生み出す体験はすごく楽しい。好奇心に駆られた問題解決に深く入っていくのはとても楽しい活動だよね。でも、実際の世界では、上司が「いつこれを納品するの?」って聞いてくることが多い。俺は一度だけ、仕事で「やってるよ、終わったら終わるし、すごくクールになるよ」って言える特権を持ったことがある。計画やタスクの分解は、開発者にとっては保険みたいなもんだ。なぜなら、上司(直接のマネージャーまで)が「どれくらい進んでる?」って聞いてきたときに、「合意した計画に従って、N個のうちk(< N)個を終えたよ。ただ、この(k+1)番目のことでは、計画中にあのことが見つからなかったから、スコープクリープや外部依存、道の真ん中に牛がいる問題で詰まってる」って言えるから。そうなると、ある種の人は他の同僚に責任を押し付けて、自分を良く見せようとして昇進のチャンスを狙うんだ。みんなに「計画の演劇」に参加して、自分の「役割」を果たすことを強く勧めるよ。あるいは、可能なら自分のやりたいように何かを始めてみて。

「... 実際にコードを書き始めるまで数週間かかる... こういう仕事をしている人がいるのが気になる。実際に見たことがないから。」

これを言うタイミングだと思うけど、「How Big Things Get Done」って本、Bent Flyvbjerg著。 「長期計画 vs. プロトタイピング開始」は偽の二項対立だよ。プロトタイピングは計画そのもの。言い換えれば、何週間もチケットを洗練するのが問題じゃない。問題は、プロトタイピングなしでこれをやると、実際にはチケットを洗練していない可能性が高いってこと。計画は、元に戻せないステップを踏むと止まるし、そのステップをできるだけ遅らせることには価値がある。そうすれば、プロジェクトが外部リスクにさらされることになるから。長期計画はこれが理由で価値があるんだ。ただ、長期計画を支持する人たちの中には、ただ時間をかけて計画に使わない人も多いけどね。

小さいし、バカだし、他にもたくさんの選択肢があったかもしれない。 ああ、この「バカな」コードね。これはただの練習だよ。俺たちの分野では、リハーサルや練習をするべきだと思わずに、プロジェクトを使ってそれをやろうとするのが気になる。実際の「バカな」コードは、エッジケースを無視したり、保証されていることに賭けたりするものだよ。

俺も同意だけど、最初は簡単に思えるけど、すぐに痛手になる無駄なバカさもあるよ(コードの量で測るとね)。思いつくのは、名前付けに関すること。プログラムをユーザーが見るドメインで考えると、データや関数、型をそのドメインに特化しすぎて名前付けや構造をしちゃうことがある。でも、計算や一般的なデータ操作はドメイン言語から分けた方がほとんどの場合良いよ。ドメイン特有のものをデータモデルに移すのに、ちょっとだけ時間をかけるだけで済む。ドメイン言語はフィールド名や型ではなく、値として考えるといい。そうすると、コードがすごく扱いやすくなる。もう一つのバカさは、ローカルステートにデフォルトすること。ステートを上に移動させるには少し計画が必要で、時にはリファクタリングも必要だし、全体のデータモデルを考慮しないと各部分を理解できない。でも、これをやると、絡み合った暗黙の調整がなくなるから、すごく効果的だよ。UI関連のことには特に当てはまる。これをすることを後悔したことはほとんどないけど、やらなかったことは何度も後悔してる。もう一つ無駄なバカさは、ロジックを広げること。説明が難しいけど、みんなが知ってるのは、if文(または他の分岐、フィルタリングなど)を使って、変数を不適切な場所に追加することの簡単さだよ。これをやらなきゃいけないと感じたら、データが十分にリッチか(ここで必要なことを表現できるか)と、一貫性があるかを再考してみて。

「データや関数、型をそのドメインに特化しすぎて名前付けや構造をしちゃうことがある。」昔、"Harry"にメールを送る必要があるPerlスクリプトを作ったことがあるんだ。(無実の人を守るために名前は変えてるよ)。Harryのメールアドレスを"$HARRY"という変数に保存したんだ。後で別の人(違う名前の)もメールを受け取りたいと言ってきた。問題ない、スカラーを配列に変えればいいだけ、"@HARRIES"に。自分ではすごく面白いと思ったけど、他の人はそう思わなかったみたい。

昨日、一日中Emacsの中からGithubにリポジトリを作成するライブラリに取り組んでた。3年ぶりに触ったんだ。ググってみたら、俺のシンプルなものよりずっと良い候補が見つかった。でも、自分のものを作る楽しみのために続けた。たくさん学んだし、すごく達成感を感じたよ。最後はちょっとごちゃごちゃしてたけど、整理し直さなきゃいけないけどね。自分のものを作ってる感じがする、たとえそれがモナリザのコピーを描いてるとしても。

これって短縮されたタイトルの一つ?元は「さあ、バカなコードを書いてみろ、挑戦してやる!」みたいな感じだったのかな?

「バカなコード」は、コンセプトやクイックプロトタイプをつなげるのには役立つと思う。でも、戦略的な決定には、よく調査されたドキュメント(PRDとかそれに類似したもの)が、反復の出発点として役立つし、取るアプローチはチームの文化に影響されるよね。