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

おもちゃソフトウェアを書くことは楽しい

概要

  • Toyプログラム 作成の意義と魅力について解説
  • 知識の深化 や問題解決力向上のための実践的アプローチを紹介
  • 現代のソフトウェア開発 における課題と喜びを再発見する方法を提案
  • おすすめのToyプログラム一覧 と難易度・所要時間の目安を掲載
  • 学習リソース や追加チャレンジも併せて紹介

なぜToyプログラムをもっと書くべきか

  • Richard Feynman の名言「自分で作れないものは理解できない」への共感
  • 自作経験 が本質的な理解やスキル向上の源泉
  • 「車輪の再発明を避けるべき」 という意見への反論
    • 自分で「車輪」を作ることで、理論書を何冊読むよりも深い理解を得られる体験
  • 2025年のソフトウェア開発 の現状
    • AIの台頭 や開発のコモディティ化・工業化が進行
    • 創造性や楽しさの喪失 への危機感
  • Toyプログラム 作成による純粋な喜びの再発見

Toyプログラム作成のコツ

  • 80:20ルール の活用(20%の労力で80%の機能を目指す)
  • 本番品質を目指さない 割り切り
    • 必要最低限の実装に絞り、過剰設計を徹底的に避ける
  • 未実装部分はpanic/crash させて、必要になった時だけ追加
  • 難しそうに見えるものでも、実際に作ってみると意外と簡単な発見

Toyプログラム作成のその他のメリット

  • 断片的な知識 が本業で役立つ場面の多さ
  • ライブラリやツールの問題発見 ・トラブルシュートのスピード向上
  • ソフトウェアの制約条件 の体感的理解
  • 独自の解決策 や発想の創出につながる可能性

おすすめToyプログラム一覧

  • 難易度所要時間推奨リソース 付き
  • いずれも 汎用プログラミング言語 の基礎がある前提

正規表現エンジン(難易度4/10、5日)

  • POSIXスタイルの正規表現を解釈・判定するエンジン
  • Wikipedia: Regex

x86 OSカーネル(難易度7/10、2ヶ月)

  • マルチブート対応カーネル、CLI、デバイスドライバ、メモリ管理等
  • OS Dev Wiki

GameBoy/NESエミュレータ(難易度6/10、3週間)

  • シンプルなGBやNESゲームのエミュレータ
  • GB DevNES Dev Wiki

GameBoy Advanceゲーム(難易度3/10、2週間)

  • スプライトベースのGBA用ゲーム
  • ToncGBATEK

2D物理エンジン(難易度5/10、1週間)

  • 剛体物理、衝突判定、複雑な形状・運動量対応

動的インタプリタ(難易度4/10、1-2週間)

  • JavaScript風言語のツリーウォーク型インタプリタ
  • Crafting Interpreters

C風コンパイラ(難易度8/10、3ヶ月)

  • シンプルな型付きC風言語のコンパイラ
  • 最適化やIR設計の追加チャレンジ

テキストエディタ(難易度5/10、2-4週間)

  • 基本からUnicode対応やLSPサポートまで幅広い設計

非同期ランタイム(難易度6/10、1週間)

  • RustならFutureタスクの同時実行・I/O対応

ハッシュマップ(難易度4/10、3-5日)

  • クローズド/オープンアドレッシング、ロビンフッド法等
  • Robin Hood Hashing

ソフトウェアラスタライザ/テクスチャマッパ(難易度6/10、2週間)

  • 3Dグラフィクスパイプラインの実装
  • Scratch-A-PixelHow OpenGL works

SDFレンダリング(難易度5/10、3日)

  • 数式で定義された3D空間の可視化
  • Inigo Quilez’s SiteShaderToy

ボクセルエンジン(難易度5/10、2週間)

  • Minecraft風の基礎エンジン
  • 0 FPS: Meshing in a Minecraft Game

スレッド仮想マシン(難易度6/10、1週間)

  • 高速インタプリタの設計と最適化
  • Wikipedia: Threaded codemuforth.dev

GUIツールキット(難易度6/10、2-3週間)

  • 独自のGUI設計・実装・アクセシビリティ対応
  • YouTube: How Clay’s UI Algorithm Works

軌道力学シミュレータ(難易度6/10、1週間)

  • ニュートン重力のシミュレーション
  • Wikipedia: Leapfrog integration

ビットワイズチャレンジ(難易度3/10、2-3日)

  • 64ビットのみで全状態を管理するゲーム設計
  • The Bitwise Challenge

ECSフレームワーク(難易度4/10、1-2週間)

  • ゲーム開発者向けEntity-Component-Systemの自作

CHIP-8エミュレータ(難易度3/10、3-6日)

  • 70年代のシンプルな仮想マシン
  • Wikipedia: CHIP-8

チェスエンジン(難易度5/10、2-5日)

  • 合法手の判定・探索アルゴリズムの実装

まとめと次のステップ

  • Toyプログラム作成 は知識の定着・創造力の刺激に最適
  • AIや自動化時代 においても、人間ならではの発見や楽しさを再認識
  • 学んだ技術 を本業やプロジェクトで活かすための基礎固め
  • 小さな成功体験 の積み重ねが、開発者としての自信と喜びにつながる

Hackerたちの意見

トイソフトウェアって、自転車や車、ボートとかをいじるのと似てるよね。自転車をいじるのは楽しいけど、明日仕事に乗っていく自転車をいじるのはストレス。トイソフトウェアを書くのが恋しいな。楽しいんだよね。でも、結局そのソフトを使いたくなっちゃうから、そこから問題が始まる。バグを見つけるけど、直す時間がないんだよね。

俺も「実用的なソフト」に興味があるけど、時間とエネルギーが足りないんだ。多くは、何度もやった退屈な細かい作業がいっぱい。自分がやりたいことに取り組めるのはちょっとワクワクするけど、それを「AI」に書かせるのは挑戦でもあるし、手間がかかるんだよね。だから、全てがバラ色ってわけじゃない。ちなみに、今はまだ実験段階の初期だから、数ヶ月後にこの意見を持ってるかはわからないけど。

最近、自分の請求書アプリを作ったんだ。欲しい機能を追加する楽しさに夢中になっちゃった。これらの機能は、大手製品では月額料金がかかるものばかり。タイムリーに請求書を出す必要があったんだ。アプリを使いたい気持ちがあったけど、スタイリングや住所の追加など、直さなきゃいけない問題があった。そこで、君が言ってたことに気づいたんだ。ある時点で、自転車をいじる楽しさと、日常使いの自転車の「有用性」を優先する方が良くなるんだよね。そうすることで、楽しさと有用性が時間とともに収束するかもしれない。

以前は自分でメールをホスティングしてたんだ。でも、今はもうやってない。まさにこの理由からね。もちろん、これは「自分でやれ!」っていう他のすべての熱心な呼びかけにも当てはまる。実際、フルタイムでやってる誰かに委任したいんだ。

うーん、わからないな。仕事に行くために使う自転車を修理するのって、唯一の自転車だったらストレスになるかも。仕事に行くのに必要だし、もし一日でも休んだら上司がめっちゃ怒るだろうしね。もし予備の自転車があれば、そんなに大変じゃないんだけど。実はこの比喩がすごく好きで、1) 車の複雑さのせいで、重要な修理ができないことが多い 2) 生活環境をその複雑なものに合わせて構築してしまっている 3) 時々、ランダムに故障して、関係者全員にとってミニ危機になることがあるけど、専門家に見てもらうために仕事を休まないと解決できない 4) 自転車は同じ状況だけど、大抵の問題はちょっとしたキットで自分で直せるんだよね。それなのに、車を持つことは大人の証みたいに見られるのが不思議。ちょっとした考えだけど、カスタマーサービス以外のほとんどの場所は、スループット重視で、誰かが一日休んでもそれほど重要じゃないんだよね。もし本当に「稼働時間」を気にするなら、みんな仕事の近くに住んで、自転車を直せるようにしてるはずだし、バス路線もあったかもね。

明日仕事に行くために必要な自転車を修理するのはストレスだよね。他の人も毎日使ってる自転車を修理するのはどう?それが仕事だよ。

これはかなり印象的なリストだね。著者にとって難易度が低いものも、俺にはかなり高いかも。刺激を受けるし、自分のトイを引っ張り出したくなる。だけど、LLMを使った学習についての結論にはもう少しニュアンスが必要だと思う。使い方次第だよね。これは学習には最悪なプロンプトだね:> この解決策を実装してくれ これは学習には素晴らしいプロンプトだよ:> ELFについての概要を教えて。高レベルの抽象に焦点を当てて、「どうやって」より「なぜ」にもっと重点を置いて。確かに、質問が出たときに自分で調査しなくて済むのは何かを奪っていると言えるけど、もし誠実に知的な作業(つまり、本当に考えること)をしているなら、常に質問を議論できるソクラテス的な教師がいるのは学習プロセスを加速させる素晴らしい助けになるよ。

キャリアに関して自分のためにやった最高のことの一つは、仕事の合間に取った6ヶ月のサバティカル中に起こった。やりたいプロジェクトがたくさんあったけど、スコープクリープに悩まされてたんだ。制約がないと、プロジェクトの大きさを決めるのが難しくて、どんどん巨大で終わらないものになっちゃう。だから、プロジェクトごとに1週間だけに自分を制約することにした。1週間でできることがそのプロジェクトの内容。新しい言語やフレームワーク、新しい分野でゼロから使えるものを作る経験は、自信を大きく高めてくれた。プログラミングが実際に得意だって気づいて、今まで直面してきた壁を突破できたことで、新しい挑戦に取り組む自信がついたんだ。新しい仕事を探してるときにすごく役立ったよ。同時に、プログラミングの楽しさを思い出させてくれた。1週間で、自分や知り合いが抱えていた問題を解決するものを作れたし、創造的で知的に挑戦的な方法でできたんだ。もし仕事の合間に数ヶ月の休みが取れるなら、リートコーディングとかはやめて、トイプロジェクトを作ってみて。自分がどれだけ知ってるかに驚くと思うよ。

自分も同じことをやったけど、AIがいろいろな定型文を生成して、自動テストを作る手助けをしてくれるおかげで、このプロセスがかなり加速したよ。

ジェネAIは、自分のためにちょっとしたおもちゃプロジェクトを作るときには本当に素晴らしい助けになるよ。自分は主にバックエンドエンジニアだけど、フロントエンドもできるし、特に遅くはないけど、CSSの魔法には特に時間がかかる。昔は、CSSとの戦いで何時間もかかるのが分かっていたから、個人的なプロジェクトをやる気が起きなかった。AIツールを使えば、「きれいにして」って言うだけで済むから、85%くらいはできちゃう。重要なのは、スタイリングのフレームワークを入れてくれるから、あとはバグを直したり、編集したり、調整したりするだけで、すごく早く終わるってこと。だから、今は過去にクイックサンドのように感じていたことを乗り越えられるから、個人プロジェクトを作ることが増えたんだ。

若い頃、Classic ASP + SQLは簡単だったし、家のサーバーにIIS + SQL Serverをセットアップしてた。HTML/CSS/JavaScriptも書けたし。デプロイは... アップデートスクリプトを実行して、FTPでASPファイルをプッシュする感じだった。今は新しいやり方があるのは知ってるし、個人的にCI/CDを設定したいんだけど、「おもちゃプロジェクト」をやろうとすると、自分のソフトウェア開発ライフサイクルについて調べたり考えたりしてつまずいちゃう。おもちゃプロジェクトのホスティングやデプロイには何を選んでる?

残念ながら、レトコードが次の仕事を得るための鍵なんだよね。

トイソフトウェアプロジェクトや小さな個人ソフト(実際に役立つもの)を作る中で学んだことの一つは、柔軟な設定エンジンを実装しないことだね。以前は、他の人が使えるように設定中心のソフトを作るべきだと思って、この罠にハマってた。だけど、設定エンジンを作るのは、実際にやるべきことを書くよりもずっと効率が悪いんだ。複雑さが低い小さなライブラリ以外のコードを共有したことはほとんどなくて、他の仮想の人のためにコードを書くのに多くの時間を無駄にした。自分のために書くべきだったのに。

通過儀礼だね! :D

それに関しての問題は、設定エンジンを作るのが、ただコードを書いてやっちゃうよりもずっと効率が悪いってことだ。http://mikehadlow.blogspot.com/2012/05/configuration-complex... これらの教訓を受け入れるのに、10年かかったよ。Visual Studioや.NETツールと競えるような製品なんて作れない。個人開発者が、他の誰かが5秒以上見てくれるようなデバッガー体験を再現するのにどれだけの時間がかかるんだろう?設定可能なものを作る上で一番難しいのはUI/UXだよね。ホスト言語の外に出た瞬間、ツールのサポートはゼロになる。確かに、設定言語として他の人気のある言語(SQL、Python、Luaなど)を選んで、そのエコシステムに乗っかることはできるけど、"プログラマーじゃない"人が「設定」のパッチワークサイトを整然と訪れる方法を作らなきゃいけない。ビジネスの人たちに、.pyや.sqlファイルがいっぱい入ったフォルダを編集しに行けって言ったら、多分良い反応はもらえないよね。これを華やかなウェブインターフェースで包んでも、問題が軽くなるわけじゃないし(むしろ悪化する)。今は、製品を構築/デプロイする方法が非常に馬鹿げていると感じてる。私が見つけた最良の道は、共通ライブラリに近いものと、それを使って期待される契約を実装する顧客ごとの実行可能ファイルを作ること。各顧客のプロジェクトは同じモノレポのサブフォルダに存在する。階層ファイルシステムの力は、業界全体で悲しくも過小評価されている。

「もしかして、あなたはLLMを使っているユーザーかもしれませんね。分かります、あれは便利なツールです。特定の学びには役立ちます。でも、こういうプロジェクトには使わない方がいいかも。知識は皿に盛られて出てくるものじゃないから。これがどこから来ているのかは分かるし、今の自分も同意するけど、『この意見をあまり強く持ちすぎない方がいい』とも言いたい。AIから助けを得るアドバイスと、人間から助けを得るアドバイスがどう違うのかを考えるのは面白いよね。ブログの最後に『ところで、もし友達にプログラミングの専門家がいたら、助けを求めない方がいい』って書くのはちょっと変だよね。変に感じる理由は二つあると思う。1) 専門家の友達は実際に質問に答えてくれて、個人的に詰まっているのを解決してくれるから、これは大きい。2) 専門家の友達は、あなたが何をしているのか理解していて、ただやってあげるんじゃなくて、自分でやる手助けをしようとしてくれる。少ない人が試したことだと思うけど(自分も試したことないけど)、実際にLLMに専門家の友達のようにガイドしてもらうのはどうだろう?問題を解決するためにコードを出すだけじゃなくて。もしかしたら、そういうのは苦手かもしれないけど、もしそうなら、1年か2年後にはすごく上手くなっていると思う。どんな助けが必要かを明確にする習慣をつけるのはいいかもね。LLMが間違った種類の助けをくれると仮定するのはやめよう。」

「ところで、もし友達にプログラミングの専門家がいたら、助けを求めない方がいい。」AIは今日の時点では専門家のプログラマーじゃないし、その結論に至るのに専門家のプログラマーはいらないよ。

私もまさにそれをやろうとしてる。LLMをインターンじゃなくて先生として使うって感じで。

これが私のLLMの最も一般的な使い方で、彼らはそれが得意だよね。時々、システムプロンプトを使ったり、質問の仕方を工夫して、ただ「あなたが正しい」と言うだけの媚びた感じにならないように気をつけなきゃいけない。アイデアを中立的に比較するようにするのが大事。最近、ClaudeとChatGPTは両方とも媚びた感じが強くなった気がする。

自分は個人的に使うためにたくさんの使い捨てアプリを作ったことがある。シェアできるコツは、GitHubに公開すること。そうすると、意外と多くの人に役立つことが分かるよ。20以上のスターがついたおもちゃリポジトリがいくつかあって、1つは200以上のスターがついてる。README.mdにスクリーンショットと簡単な実行手順を載せるだけでOK。マニュアルを書く必要はない。npm install && npm run startみたいなシンプルな指示で大体の人には十分だよ。スクリーンショットは重要だけどね。

これは、採用プロセスの履歴書レビュー段階で他の候補者の中で目立つ素晴らしい方法でもあるよ。採用マネージャーとしての一番の疑問は「この人は本当にコードを書けるのか?」ってこと。2〜3のプロジェクトがあって、それぞれに複数のコミットがあるGitHubプロファイルは、その疑問にすごく良い答えを出してくれる。そういうのがない人をフィルタリングすることはないけど(素晴らしいエンジニアの中にはコードを公開したことがない人もいるから)、そういうのがある人は電話面接に選ばれる可能性が高いよ。

VHS(https://github.com/charmbracelet/vhs)を使ってGIF作成のスクリプトを書いてるんだけど、複数のコマンドをデモする時にCLIのワークフローをすごく見せられるよ。例: https://github.com/bbkane

ありがとう、試してみるね。いくつかアイデアがあるんだ。

こういうプロジェクトをいくつか持ってるけど、実際に世に出るかは分からない。コードを書くのが好きなだけなんだ。仕事の中でコードを書くのはほんの一部だけど、正直言って、趣味みたいなもんだね。みんなに自分の作品を好きになってもらったり、名声を得たり、履歴書を膨らませたりすることには魅力があるけど、そうなると楽しさがなくなっちゃう。自分は人生で本当に楽しめることがあまりないから、他人の目を気にしたり、名声を追いかけたり、印象を与えたり、キャリアのことを心配したりするのは、楽しみを台無しにするんだ。昔は、こういうことに情熱を持って、上手くなればキャリアや将来に役立つかもって思ってたけど、現実はそんなに甘くない。そうすると、楽しさや情熱が奪われちゃう。だから、楽しむためにコーディングを好きでいるのは全然悪くないよ。他の人はスポーツをしたり(観たり)、アートやクラフトに取り組んだり、鶏を育てたりするけど、自分はコーディングをする。特に上手いわけでもないし、ただ楽しんでるだけ。それが全てだよ。コーディングが楽しいなら、その楽しみを大切にしてね!たとえ自分のように極端にしなくても。これが言いたいこと。

この意見が好きで、みんなが生産的であることを奨励される一方で、自分自身の喜びも大切なものだっていう重要な考えを思い出させてくれる。

あなたはLLMを使ってるのかもしれないね。わかる、便利なツールだよね。特定の学びには役立つ。でも、こういうプロジェクトに使う誘惑には抵抗した方がいいかも。知識は皿の上に乗せられて与えられるものじゃないよね。LLMを検索エンジンみたいに使ってるのは私だけ?LLMの前は、「mysql mongodbの利点と欠点」みたいなことをGoogleで検索してたんだ。各DBの公式ドキュメントやフォーラム、ブログ記事、Stack Overflowの投稿を読んでた。検索に時間がかかるけど、情報を読むのは全然苦じゃなかった(学ぶ時間だから、いつでも歓迎だし)。今はLLMに同じことをちょっとコンテキストを加えて聞くだけで、「写真を保存する時のmysqlとmongodbの利点と欠点。リンク参照」って感じで。だから、何に気をつけるべきかの概要をすぐに得られるし、参考文献があるから幻覚に頼らずに済む。確かに時々「写真のメタデータをPostgresに保存するためのデータスキーマを教えて。Xは別のテーブルにしたいんだけど」みたいに言っちゃうこともあるけど、それは出力がどうあるべきかをよく知ってるからなんだよね(ただ、タイプするのに時間をかけたくないし、時々実際に使うべき型を忘れちゃうこともあるから)。

今はLLMに同じことをちょっとコンテキストを加えて聞くだけで、「写真を保存する時のmysqlとmongodbの利点と欠点。リンク参照」って感じで。近い将来、企業は自社製品を比較でより良く見せるためにたくさんのお金を払うことになるかも。LLMは結果を「自然」に見せるだけの賢さがあるから、すべての検証可能な情報は真実で、参考文献でサポートされるけど、正しいフレーミングや強調が重要になるんだよね。

新しいことを学ぶ時、LLMは私がまだ知らないいろんな視点や文脈を引き出してくれるから、私にもすごく役立ってる。ドキュメントやフォーラム、コードサンプルから情報を引っ張ってきて、物事がどうつながっているかを見せてくれるし、何が良いか悪いかの理由を提案してくれることもある。まだ知らなかったドキュメントを調べるチャンスもたくさんあるよ。

私がLLMを使う主な目的は、あまり詳しくないライブラリやツールのボイラープレート設定を教えてもらって、それに対するオプションを調べることなんだ。例えば、「AWS ECSクラスタのためのTerraform設定を教えて。2つのサービスが互いに話せるようにして、一つは公開、もう一つはプライベートにして」みたいな感じ。たまに、小さな自己完結型のアルゴリズムを教えてもらうこともあるよ。例えば、「日付の差を人間が読みやすいテキストにフォーマットする方法を教えて。例えば、1日、16時間」とかね。

これに加えて、ドキュメントが不十分または全くないAPIの検索が簡単なのも、私の使用の80%くらいだよ。それ以外にも、「これがxyzシステムのデザインなんだけど、このアーキテクチャを使うのはバカなの?」っていうのが多い。

そうそう、これが私にとって生産性の90%の恩恵があるところだね。ドキュメントを1時間探す代わりに、LLMに聞けば5分で答えがもらえる。

これ、コードレビューや、手を加えまくるプロトタイプを素早く生成するのに使ってる。ほとんどのLLMのコードは残らないけどね。「じゃあ自分で書けばいいじゃん?」って言われるかもしれないけど、動くプロジェクトの骨組みから始めるのが一番難しいこともあるんだよね。

LLMを使ってSQLのウィンドウ関数について学んだよ。10年以上SQLを書いてなかったし、ウィンドウ関数に出会ったこともなかった。どう働くかやトレードオフを説明してくれて、すごく良かった!

うまくいくと嬉しいけど、時々、求めてる答えを得るためにプロンプトに入れる適切な言葉がわからなくて困ることがある。最近Rakuで遊んでたら、すごく難解な型シグネチャエラーが出て、Claudeは全然役に立たなかった。Signatureリテラルとメソッドパラメータの'スラーピー'シジルの相互作用について知らなかったから。スラーピーという言葉をプロンプトに入れて初めて、探してた情報を吐き出してくれたけど、その時点ではもう知ってたんだよね。

うん、俺もそうだよ(ほとんどの場合ね)。理解できないコードに取り組むのは好きじゃない。でも、自分が書いたクライアントAPIを使って、クライアントが自分の書いたものとどうやって連携するかを調べるように頼むようになったよ。これがすごくいい感じ。

LLMを検索エンジンのように使ってるのは俺だけ?この理由で、GeminiやCopilotのような検索ファーストのLLMが結構好きなんだ。出力を確認するためのリンクをくれるし、Google検索やBingよりSEOスパムに誘導されにくい気がする。ただ、今の検索エンジンは歴史的に見てパフォーマンスが悪くなってると思うから、LLMがその恩恵を受けてるのかも。

Claudeを使ったバイブコーディングのおかげで、楽しいサイドプロジェクトへの情熱が再燃したよ。最初はちょっとつまずいたけど、ツールやプロセスを理解して、数週間でいくつかのアプリを作ったんだ。新しいアイデアも次々浮かんできてる。 - 家族用カレンダー/天気ダッシュボード - 見た投稿を隠せるBlueskyリーダー - 時間追跡をもっとゲーム感覚にして、楽しくできる仕事用PMダッシュボード - 見た後にX秒間投稿を隠すChromeのReddit拡張 - メンテされていないプラグインを置き換えるWordPressプラグイン これが好きで、慣れるまで時間がかかったのは、これらのアプリを見たり使ったりして、90%の完成度でも満足できることだった。最初はClaudeにUIの改善をたくさん頼んでたけど、ほとんどのことは手放して、機能や新しいものを作ることに集中することを学んだよ。

Claudeにバグを直してもらっても、更新された出力が出てこないのが辛い。修正を求めるのを6回も頼まなきゃいけないのに、出力に更新が含まれてるって言い張るんだ。そんな経験、あった?

記事の精神がすごく好きで、AIエージェントコーディングの時代においてプログラミングの楽しさがますます重要になってると思う。でも、時間の見積もりが短すぎるって感じるのは俺だけ?地球上で一番速いプログラマーではないけど、遅くもないし、ほとんどのプロジェクトはその見積もりよりもずっと時間がかかると思う。特に1日2-3時間しか作業しないとなるとね。ほとんどのプロジェクトは、コーディングを始める前にリサーチや学習にかなりの時間がかかると思う。例えば、最近Pelicanブログを自分のハッキーな静的サイトジェネレーターに置き換えたんだけど、1日2-3時間作業して、2週間かかった。これでも、そのリストの中の多くのプロジェクトより簡単なものなんだよ。