テキストエディタ
- テキストエディタは毎日使っているが、実際にどのように動作しているか知っているだろうか。まずは基本的な機能を実装するところから始める。
- テキスト文書をメモリ内でどう保存するかが最大の課題。配列の使用には性能上の問題があり、これを解決するためのさまざまなデータ構造を学ぶ必要がある。
- テキストカーソルの動作方式を学び、基本的なエディタを実装した後は、undo/redo や単語の自動折り返し機能の実装にも挑戦する。
2Dゲーム - スペースインベーダー
- シンプルなゲームであっても、特別なデータ構造やデザインパターンが必要になる。ゲームデザインやアートに集中するというより、ゲーム全体の実装に焦点を当てる。
- 画面描画、ゲームループ、ユーザー入力処理、動的オブジェクトの生成と管理、ゲームロジックの適用などを学ぶ。
- 基本的なゲームを実装した後は、タイトル画面メニューやゲームオーバー画面の追加、さまざまなコンピューターで同じ速度を維持すること、AI の適用などへ拡張できる。
コンパイラ - Tiny BASIC
- コンパイラの実装は、プログラミングに対する深い理解を必要とするプロジェクト。Tiny BASIC のようなシンプルな言語でコンパイラを書くところから始める。
- コードをトークン化する方法(lexical analysis)、パース(構造の確認とツリー生成)、意味解析、コード生成などの工程を学ぶ。
- 基本的なコンパイラを実装した後は、標準ライブラリの追加、最適化段階の追加、エラーメッセージの改善などへ拡張できる。
ミニOS
- OS の基本概念はさまざまな分野に応用できる。OS を実装することで、ハードウェアへの理解が深まる。
- ハードウェア依存の学習曲線はあるが、本やチュートリアルに従えばブート可能な OS を作ることができる。
スプレッドシート
- スプレッドシートアプリケーションは、テキストエディタとコンパイラの難しさを組み合わせたもの。セルの内容をメモリ内で表現する方法と、数式のためのプログラミング言語インタプリタの実装を学ぶ。
ビデオゲーム機エミュレータ
- エミュレータを書くことは、コンパイラ、OS、コンパイラ作成の難しさをひとつに組み合わせることに等しい。実際のゲームをエミュレータでプレイするのはやりがいのある経験。
- 実際のビデオゲーム機をエミュレートするとは、その CPU やその他のハードウェア構成要素のように動作する仮想マシンを書くことを意味する。
GN⁺の意見
- プログラミングの基礎を固めるうえで、テキストエディタやシンプルなゲームの実装は、実際に使っているソフトウェアの内部動作原理を理解するのに大いに役立つ。
- コンパイラや OS のような複雑なプロジェクトは、プログラミング言語とコンピューターアーキテクチャへの深い理解を要求し、これは高度なソフトウェアエンジニアリング技術を身につけるうえで不可欠である。
- こうしたプロジェクトは、プログラマーが新しい言語やフレームワークを学んだり、既存の知識を深めたりする際に、興味深く挑戦的な経験を提供する。
1件のコメント
Hacker Newsの意見
テキストエディタ、コンパイラ、オペレーティングシステム、レイトレーサーのようなプロジェクトに取り組むことはプログラミング能力の向上にはつながるが、ソフトウェアエンジニアリング能力を高めるものではない。実際、こうしたプロジェクトは「Not Invented Here(自前主義)」という破滅的な原則を内包しており、ソフトウェアエンジニアリングにおいては逆効果になりうる。
UI/ウェブ系のプロジェクトとしては、次のようなものを勧めている:
XMLHTTPRequestを包む HTTP ライブラリのラッパー(fetchは存在するが、HTTP リクエストをゼロからどう送ってどう読むのかを理解しておくと、CORS の問題やOPTIONSリクエストなどをデバッグするときに役立つ)ミニ OS に対する好意的な意見。アプリケーション開発者としては OS の機能(メモリ管理、ファイルシステムなど)に依存しており、こうしたものが裏側でどう動いているのか気になるはず。xv6 を使って余暇にさまざまなプロセススケジューリングアルゴリズムを学び、実装するのは非常に有益で楽しい経験になる。
ロボットや自動操縦機能付きドローン、プログラム可能な GNC パラメータを持つ宇宙船の飛行力学の高精度シミュレーションなど、物理的なものに触れたいという欲求について。"Fundamentals of Astrodynamics" という本を持っており、この休暇シーズンに活用したい。GNC(誘導、航法、制御)について良い情報を得たい。
個人の好みや状況によるが、アイデアを探しているなら良い出発点になりうる一覧。Sinclair ZX Spectrum を使って楽譜エディタやトラッカー、2D ゲーム(スペースインベーダー)などを作った。最初のコンピュータ(386)では、ハフマン圧縮器、B-Tree インデックス、OOP フォームジェネレータ、ダイヤルアップ用メールチェッカー、手書きパーサーなどを作った。
テキストエディタについての議論: テキスト文書をメモリ上でどう保持するかが最大の課題。最初は配列を使うのが自然に思えたが、文書の末尾以外にテキストを挿入すると性能が非常に悪い。しかし JavaScript の文字列を使い、2年以上エディタを使っていても性能問題はなかった。もちろん他にも多くの問題はあり、たとえば長い水平線のレンダリングは、単一行のレンダリングは安価だという前提で最適化していたため問題になった。
シンプルなおもちゃのレイトレーサーを試してみるのも良い考え。球体のあるビットマップグラフィックスで、拡散反射と鏡面反射を行うレイトレーサーを作るのは、プロジェクトを複雑にしすぎない限り、比較的スコープの限られたプロジェクトになりうる。
スペースインベーダーを書くのに「ファクトリーパターン」が必要だと思うなら、何かがおかしい。元のゲームでそのような設計概念が使われていたとは考えにくい。
データ構造として配列を使うテキストエディタについての意見。タイピング中は高速性が必要で、変更されるのは1行だけ。新しい行を入力するとき、Enter を押した後に配列を組み替えるための追加の遅延は、何百万行あっても目立たない。テキストエディタでより難しいのは、ユーザーが見ているものだけを確実にレンダリングすることだ。