100 Days of Codeをやってみた
ツイッターで100 Days Of Codeというチャレンジがたまに流れていて、面白そうだったのでやってみた。今年も終わりに近づいているので今更ながら振り返ってみる。
100 Days Of Code概要
ルールは簡単:
途中で風邪をひいて寝込んだりいわゆるライフイベントが発生したりして合計で5日ほど空いてしまったが、8月14日にはじめて11月26日に終わった。
積ん読していた本をある程度消費したい、という欲求もあり、100日間基本的に本に載っているコードや演習問題、オンラインのチュートリアルなどをやって過ごした。自前のプロジェクトを立ち上げたりしなかったのですこし寂しい気もする。近いうちに自作言語に手を出したい。
やったこと(というか読んだ本)
Essentials of Programming Languages 第1章〜第7章
Paradigms of Artificial Intelligence 第1章〜第4章
Structure and Interpretation of Computer Programs 第2章
500 Lines or Less - Python Bytecode Interpreter章
Types and Programming Languages OCamlでの実装章
Implementing Programming Languages 第2章
Kaleidoscope LLVM Tutorial
MinCaml compiler
Essentials of Programming Languages
この本がここ1年ほど一番読みたいと思っていた本だった。ものすごく簡単な言語からはじめて、Racketでインタプリタをいろいろ実装していくという本。
などといったプログラミング言語の基礎概念の多くを実際に自分の手で作っていくのはすごく面白かったし勉強になった。とりあえずRacketで実装していって、その後OCamlで書き直してみたりしたのもよかった。(とくに代数的データ型の便利さを実感できた点で)
まだ章はいくつか残っているので今後もまた戻ってきたい。
Paradigms of Artificial Intelligence
こちらはちょっと手をつけた程度。Common Lispに没入するに至らず、不完全燃焼気味。絶対に読みたい本の一つなので2019年に持ち越し。
Structure and Interpretation of Computer Programs
カマイルカさん(@lagenorhynque)とOpt Technologiesの皆様のご好意で読書会にオンライン参加させてもらっていた。ここ二ヶ月ほど事情があって参加できず悲しい。近いうちにまた是非参加したい。
Schemeで問題を解いていって解けた人からコードをSlackにあげていくというなかなか楽しい会。Lispに興味がある人はガンガン参加するといいと思う。進むペースはすこしゆったりめか。
500 Lines or Less
The Architecture of Open Source Applicationsというシリーズがある。いろんなオープンソースのプログラムの設計思想などをその開発者が解説するというなかなか素敵なもの。その中の500行以下のプログラムをピックアップした刊が500 Lines or Lessだ。
章のひとつがPythonで実装するPython Bytecode Interpreterの解説で、これを追いながら写経していった。スタックマシンの実装の理解やバイトコードに対する慣れなど、得るものは多かったと思う。正直書かれていたコードはそこまで好きなスタイルではなかったが・・・
Types and Programming Languages
何回か流し読みしたことはあるのと最初の方はるじゃんどるさん(@Lugendre)の読書会でやったことはあるのだが、正直ちゃんと納得できるレベルで読めたとは言えない状態だった。
以前読んだ時はそもそもプログラミング言語についての前提知識が不十分だったように思う。Essentials of Programming LanguagesやConcepts, Techniques, and Models of Computer Programmingなどといった「プログラミング言語関連のトピックを俯瞰的に提示する本」を読んだ上で挑戦するのがちょうどいいのではないか。
今回もそこまで真面目に読んだ感じではなく、実装について触れている章を写経するのがメインだった。近いうちにまたちゃんと読み込みたい。
Implementing Programming Languages
C++のサブセット的な言語をJava Bytecodeやマシン語にコンパイルする話が主体になる本。パーサに関する演習問題などを(本が推奨するパーサジェネレータではなく)OCamllexとMenhirで実装していった。
Kaleidoscope LLVM Tutorial
Kaleidoscopeという小さな言語をLLVMにコンパイルするチュートリアル。C++とOCamlのものがあり、当然OCamlを選んだ、のだが。古いチュートリアルでLLVMがどんどん発展している技術ということもあり、サンプルコードの多くが動かない。というかOCamlではLLVMのJITコンパイラにアクセスするのがすごく大変そう(チュートリアルが書かれた頃に存在したAPIがごっそりDeprecatedになっていた)。
けっこう機能面でも思い切って削った(主に前述のJIT)コンパイラを実装。はじめてOCamlコードのデバッグやライブラリコードを必死に読むという経験をしたので、結果オーライか。
MinCaml compiler
東北大学の住井先生のMinCamlというOCamlサブセットをSPARC命令セットにコンパイルするOCamlプログラムを写経。
http://esumii.github.io/min-caml/paper.pdf
K正規化、α変換、β簡約などの関数型言語らしいコンパイラ最適化に触れつつそれなりの分量のOCamlコードを理解しながら写経していくというのは大変勉強になった。残念だったのはそもそも私がSPARCの命令セットを全く知らないので、最後の方の工程があまり理解できていない点・・・ 実はMinCamlのさらに限定的なサブセットからはじめて、少しずつ言語機能を追加していく感じでMinCamlコンパイラまで戻っていく、というような過程もやってみたいと思ってはじめたのだが前述の問題で失速してしまった。アセンブリ力が高まったら再度挑戦してみたい。
総括
というわけで、興味の赴くままにいろいろと触っていったらだんだん言語処理系沼にはまり込んでいった感がある。使う言語としては最初はLisp系やPythonだったのだが、後半はほぼOCaml。セマンティクス的にはかなり自分にとってしっくりくる言語だった(でもmodular implicitsはほしい・・・)のでこれからも積極的に使っていきたい。
100 Days of Codeという試みはなかなか面白かった。毎日なるべくちょこっとでも本を読んではPCに向かってコードを書く、さらには書いたコードはなるべくgithubにあげる、という習慣は、無駄に草を生やしているだけのように見えてこれでなかなか蓄積になっている、気がする。なんだかんだいって100日終わった後も継続的に趣味コード書いてはあげてるし。
コードはそれなりの量を書き散らかしたがプロダクト開発ではなく自分の知識獲得のためのものばかりだった。予想どうりだったとは言え今見返すとちょっと極端だったように思う。2019年は趣味でもすこしプロダクト的なものも書いていきたい。どこかのタイミングでまた100 days of codeやるかも。