Friday, December 18, 2015

Implementing Egg in PHP

I recently implemented an interpreter for the toy language Egg as described in Marijn Haverbeke's Eloquent JavaScript.

It was an interesting exercise for two reasons.

Firstly, I implemented it in PHP rather than JavaScript.

I did this not because I'm more comfortable in PHP than I am in JS (I'm at least equally comfortable), but because I wanted to make it difficult for me to get lazy and copy and paste parts of the JS implementation.

This turned out to be a great move because it forced me to flex PHP muscles that I haven't ever really used. For instance, I've used anonymous functions before, but the fact that PHP closures don't automatically capture variables from its parent scope meant I needed to come up with a couple of creative solutions for something that just comes along "for free" in JS.

Secondly, I implemented the entire thing using TDD.

This was, by far, the most difficult part of the exercise. Haverbeke's code is clean and succinct and after reading it I had a clear idea of what I wanted to implement. However, I forced myself to stick to the Red-Green-Refactor cycle and built the system in the smallest (reasonable) increments in functionality I could think of.

This was frustrating in parts. As this was the first time I've used TDD properly to drive the design of something bigger than a code kata or coderetreat exercise. I've used unit testing pretty extensively in some large projects, but never to explicitly drive the design, this is new for me.
Having seen Haverbeke's implementation I knew exactly where I wanted to go, but forcing myself to drive the design and implementation using TDD (and being as methodical as I was able to be) meant that I couldn't skip over a bunch of steps and simply write a PHP version of Haverbeke's code. I had to go the long way around, and I'm glad I did as it meant I learnt a lot about both the testing framework I was using (PHPSpec) as well as testing in general.
The upshot of sticking to TDD all the way through, though, was that once I'd finished the project and actually looked at the resulting code, I was pleasantly surprised to see just how clean it was. Far cleaner, I'd wager, than if I'd just bombed into writing an implementation straight. I'm also pretty sure that approaching it the way I did meant that troubleshooting was a breeze. I can imagine that if I hadn't written my tests upfront (and in the way I did) I'd have spent a bunch of time tracking down logic errors.

I'm not going to be putting the code up anywhere - the project wasn't anything more than a project a Saturday and Sunday night after the rest of the family had gone to bed. I would recommend that anyone who is interested in programming languages writes an interpreter at some stage, though.
Writing an interpreter does two things.
Firstly, it demystifies programming languages. It shows us how an interpreter is a program just like any other.
Secondly, even though an interpreter (or compiler, or assembler, or whatever you're writing) is just a program, you'll be blown away by the power of the ideas embodied in that program.

As a final note, it's been a good few years since I experienced that unique thrill that comes from having a program you've written do something cool. It was most definitely one of those moments when my interpreter could take this

do(define(pow, fun(base, exp,
if(==(exp, 0),
1,
*(base, pow(base, -(exp, 1)))))),
print(pow(2, 10)))

and do this




Saturday, December 5, 2015

Guidance, binary, and responsibility.

When I was in Std. 6 (Grade 8) I had the worst "learning" experience of my life.
It was in what was called "guidance", ostensibly a class meant to furnish us with the skills we needed for life outside of school.

On that particular day we were discussing careers. This was around 1993 and computers/IT/whatever was still seen as being a particularly smart career move (although this was still before the feeding frenzy of the dotcom boom, so I don't think it was as hot a choice as it was later taken to be).
A fair number of us loved computer games, and some of us -- myself included -- thought it would be cool to grow up and make our own. That is, to be programmers.
At some stage someone (it could have even been me) mentioned becoming a programmer as a possibility.

The teacher then asked "who of you know what binary code is?", some of us put up our hands.

Then he asked "do any of you know how it works?" and I kept my hand up.

He then offered me a piece of chalk and asked if I wouldn't come to the board and write up something simple in binary, maybe something like the number 5, I can't remember exactly which problem he posed. I do remember, though, that I worked it out when I got home.

I went up to the board, and froze.

Now, there are a couple of ways a teacher could respond to this. I've taught classes before, and have been lucky enough to have seen brilliant teachers in action (my philosophy supervisor in his second year class on Epistemology was, perhaps, the greatest example of how to teach I've ever seen -- managing to turn even questions that seem entirely hopeless into opportunities for learning).

The correct response to a frozen student is to engage them, draw out what they actually know. Ask leading questions, encourage them to come to the right conclusions.

What my teacher did was use it as an opportunity to humiliate me and the rest of my class.

After a few moments of standing before the board frozen he sent me back to my desk and said something along the lines of "not everyone is cut out for being a programmer, those of you in this class interested in computers can certainly find work in computers, fixing them, replacing hard-drives and such, but not necessarily as programmers".

You see, my class was made up of guys who had been kept back the previous year, who weren't doing particularly well academically, or who had (like me) transferred from other schools. Leftovers, basically. And the attitude towards us was, more or less, get them out of the school as quickly as possible (many of my class did, in fact, leave our high school before graduating, opting for a skills based college education).

He had an opportunity to encourage us, and he used it as an opportunity to make us feel like shit about ourselves and our prospects.

I was 13. Think about that. What kind of grown man goes out of their way try to crush the dreams of a 13 year old?

If he had decided that, rather than using this as an opportunity to belittle me and had, rather, asked me what problem I was having with the binary conversion, the class may have turned out quite differently.

I had, in fact, by that time taught myself to program by reading the Q-Basic help manuals that came with MS-DOS 5. Reading the source of gorillas.bas and nibbles.bas.

As for binary (and remember, we had no internet in these days) I'd actually worked it out from reading about it in Wyndham's novel, Chocky. I'd never actually seen a lot of binary written out and couldn't remember if it was supposed to be written left to right or right to left. *edit: to be clear, the passage explaining binary in the novel is very clear, but I went out of my way to understand it -- I must have been around 8 at the time -- explaining it to anyone who would listen. It was a revelation to me*

Now, I don't think that teaching myself to program or learning binary from an SF novel (both before I was 11) is something that is particularly exceptional - I think that these are quite common experiences shared by many people, people who often become programmers.

 My experience in high school coloured my relationship to formal learning for a long time, and this kind of experience was repeated a number of times during my high school career.

I wish I could ask this teacher what he was thinking. Was he just having a bad day and so felt like lashing out at the "stupid class"? Did he realize that this episode may have actually discouraged learning in kids that could have, with even a little effort, a little guidance, flourished?

Wednesday, December 2, 2015

34 in review.

I've been inspired by Michael Fogus' year in review posts, and though that instead of doing it on the year, I'd do it on or around my birthday to try and get a sense of what I've managed to accomplish (if anything).

Favorite technical books discovered

The first two technical books that have impacted me this year have been related to high quality MOOCs. 

The first is Nisan and Schocken's "The Elements of Computing Systems" (and the associated MOOC on Coursera). This book, and the associated course, was one of the greatest learning experiences I've ever had in computing. Essentially they take you through "building" (viturally) a complete computing system from logic gates through to an operating system. Part 1 takes you through about half of the book, through to building an assembler. I'll be taking Part 2 next year when it's released. 
The MOOC is a really powerful supplement to the book. I can't recommend it highly enough.

The second is the monumental "Concepts, techniques, and models of computer programming" by Van-Roy and Haridi. This was linked to the EdX courses by Van-Roy where he covers about 50% of the text (and, as such, I've only read about half of the book). Still, what I have read has really changed my perspective on programming languages. As much as I dislike actually coding in Oz and the Mozart environment (the entire book is built around the language) I appreciate what it does. I've come away from the two-part series of courses having a much, much deeper appreciation of the ideas regarding (and my relative ignorance of) programming languages.

In terms of philosophy, my favourite read of the year was probably Peter Godfrey-Smith's "Philosophy of Biology".


Favorite fiction


Philip Roth's The Human Stain was, hands down, the best piece of fiction I read this year with Ishiguro's The Buried Giant a distant second. 

I read far too little fiction in the last year. I'll remedy that this year.


Philosophy


This year has been difficult in terms of my philosophical work. My actual work (see below) has been pretty busy, and so working on my thesis has been difficult. However, I managed to make a couple milestones. I wrote and defended my thesis proposal. I wrote up and presented a paper on representation and choice. Finally, the chapter I've been working on is sitting on around 20 000 words at the moment. Including the numerous rewrites I've done, I've written at least twice that (something more around 50-60K words) - so there is progress. 

Next year I'm pivoting to the evolutionary perspective on my work, this will in turn help me focus the sprawl that the first chapter currently is. 

I have read a lot of papers this year and although they're in the service of philosophy, very few of them were actually philosophy papers. We'll track this category a little closer next year.


Work/Programming/Hacking


This year I went out on my own again and co-founded a small consultancy. We're presently focused on professional PHP development and will be for the medium term. 
This has obviously taken up a lot of time. 

Still, I've managed to do a couple of cool things. I went to my first Code Retreat, an experience which was invaluable. I'll most definitely be attending again. 

I also built an InsectBot, which was a bunch of fun, as well as hacked around on my Arduino.

Further, I wrote and deployed my first Laravel app this year. I don't think I've had a better experience learning or working with a framework. Taylor Otwell is a champ.

Writing


I've had two publications this year. 

First, my story "A Darker Utility" appeared in New Contrast
Then, another one of my stories "Islands" appeared at The Kalahari Review

Both are what you might consider as "literary" fiction, and I'm quite proud of both pieces despite their flaws.

My story "After the Reception" also won first prize in the South African Writer's Circle SF competition, which was a nice surprise.

Plans for 35


I have a couple of things I want to achieve, in no particular order.

Firstly, I want to finish chapter 2 of my thesis. This'll get me past half way to my PhD. Totally doable.

Secondly, I'd really like to publish a philosophy paper. I'm working on a co-authored paper with my supervisor that is pretty well developed. So hopefully that'll happen soon.

Thirdly, I want to learn a new programming language. This year I learned Oz (barely) and relearned PHP. I'm thinking that I may want to give Clojure and Ruby a go. We'll see as the year progresses.

Fourthly, I want to write at least 60K words on my current WIP.

Finally, I really, really want to do more work contributing to FOSS.