Learning functional programming the hard way - by implementing an interpreter from scratch.