Simply Scheme: SICP for the rest of us
If you're like me, you've probably read the first 150 pages of SICP (The Structure and Interpretation of Computer Programs) about three times. Personally, I find that it starts out extremely easy, but quickly becomes difficult. After a while I find that I am still reading, but not a whole lot is making sense to me. It's as though there is an underlying peice of knowledge that the authors assume I possess, which I don't.
I am of the school of "SICP should be read by all programmers". But I think my exact statement would be: "SICP should be read, and understood, by all programmers".
If we take a look on Amazon, we will see the strange mix of reviews SICP has received thus far (stars/reviews): 5/89, 4/8, 3/8, 2/3, 1/53
What?? So, I guess this implies that people either LOVE or HATE this book. If you go through the reviews in detail, you can see that a lot of the 1-star reviewers are upset with the text because it's simply too abstract and they do not leave with any confidence. I feel it is also worth mentioning that this text has received an elitist badge in our industry. If you read it, watch the lectures, and brainwash yourself into thinking you understood everything, you are now part of the genius club and can start quoting Paul Graham and Peter Norvig.
Enter Simply Scheme (Brain Harvey, Matthew Wright. 2nd ed, 1999, MIT press). A fundamental computer programming textbook for those of us who have trouble tackling SICP (and also for the people who, out of fear, pretend they could). According to the authors, SS was actually written as a pre-cursor to SICP. This textbook presents all the major concepts in a much more digestible way than SICP. This is good news!
As a word of warning, it's worth knowing that SS does use Scheme, but it teaches a slightly modified version of it. You will learn effective program design, but not the inner workings of Scheme itself. I already knew scheme when I started this book, and it annoyed me a little at the beginning, but I quickly got used to it.
The entire text is available free on the web. Take a look: http://www.eecs.berkeley.edu/~bh/ss-toc2.html.
I have also spent a lot of my freetime publishing my answers to all of the exercises at the end of each chapter. You can take a look at my solutions here: http://github.com/buntine/Simply-Scheme-Exercises (perhaps you can fork me and juxtapose your own solutions??). I hope this can help someone in their travels.
So, once you get through Simply Scheme, you may be much better suited to properly tackle SICP and finally become a master craftsman!
Travel update #1
I had planned to post these more often, but hey, I guess I've been busy with non-computery stuff for the first time in far too long.
At the moment I am in Thailand, in Krabi Town specifically, a small-ish city in the south. It's near Phuket (which I did not like, for the record).
I've been on the road for about a month now and have loved (nearly) every minute of it. The first few days were a little rough as it was at that point I truly realised I was alone in a very foreign place.
At this point, I've seen most of the country. There are still some spots in central Thailand that I'd like to check out, but that will have to happen another time. I think my favourite place so far has been Chiang Mai, the proverbial "capital of the North". It's an ancient city with a laid-back atmosphere. Tomorrow night I am catching the overnight train up to Bangkok, where I will spend a few more nights.
On the 29th of December, I am flying directly to Munich, Germany. From there I will try and see as much of Eastern Europe as possibly can in 20 days (without rushing too much, of course). My only guideline is that I will need to be in Amsterdam on the 18th of January. At this point I will be meeting my younger sister, Grace, with whom I will travel through some of Western Europe (The Netherlands, Belgium, France, Switzerland).
At this point, I am feeling glad that I decided to travel alone. This type of radical decision really helps you come out your shell. I've met a lot of really cool people from all over the world and experienced Thai culture in a way that a lot of package travellers would never get to see.
Until next time!
Time for an adventure (Angkor WHAT?!)
A few weeks ago, I booked a one-way ticket to Bangkok. I have a netbook, a backpack, malaria tablets, new shoes, and some books on LISP.
I am departing from Melbourne at 2:55pm on December 1st, 2009.
The plan (well, if I had one, this would be it) is to spend a few weeks in Thailand, and then transplant myself into Cambodia. After visiting all of the Wats (temples) and soaking in the atmosphere, I'll travel into Laos and lay back for a few weeks. I've heard there is a cool "river-tubing" activity near Vang Vieng, which sounds fun.
Next is the hustle-bustle of Vietnam! I've heard excellent things about this country, and really look forward to checking it out. My sister says she will fly over and meet me in Hanoi, which would be ultra badass!
After that, depending on my financial, physical and emotional state, I may well just keep going and catch a flight to somewhere in China. But who knows? By then I might be in Africa or South America...
I'll still be online regularly (where possible), so hopefully I can document some of my travels as I go. Wish me luck! :)
Running Linux processes as Daemons
Running an arbitrary process, such as a Python script, on your Linux box as a daemon is really quite simple if you have the right tools.
In my case, I had a simple Python socket server that needed to run permanently. Simply running it in the background (Ctrl-z) is no good as it would die the moment I logged off!
Enter daemon, a really handy tool for solving this exact problem.
Installation is easy. On Debian-based distros, you can just install it directly form aptitude. On CentOS, which uses yum, I had to install it from source. But I ran into no problems there.
Once installed, getting things running was easy:
$ daemon -r --name=myserver python /full/path/to/myserver.py
The "r" flag tells daemon to respawn itself if the service is killed. I've given it a name so I can refer to it later. And the rest of the line is the actual command I want to run.
To test if the process is still running, you can look in ps or pgrep, but the best way to do it is to simply ask daemon personally:
$ daemon -v --name=myserver --running
The "v" flag is for verbosity (of coarse). The "running" flag tell daemon that I want to know if the process specified by "name" is still running. The output you receive is simple to interpret, e.g: "myserver is running with PID: 23324".
To finally kill the process at some point in the future, you can issue the following command:
$ daemon -v --name=myserver --stop
And this one should be rather self-explanatory by now. :)
I've only grazed the surface here. Just check out the man page for an idea of how much more you can do with this. Good luck, muchachos!
Arguments for pair programming
A while ago I found myself in the position where I needed to convince my managers that Pair Programming was a worthwhile business investment. I was recommending the traditional approach, consisting of a "driver" and an "observer", who optionally switch roles at semi-constant intervals.
I was conscious enough to know that getting the actual benefits across clearly was important as the whole concept could easily be misconstrued to mean something along the lines of: "Hey! I want to sporadically wrap all of the production staff into neat little bundles of two".
Below are my no-bullshit reasons why, from my own experience, pair programming/designing/writing works well. Now, I should mention that your own mileage may vary. I've had occasions where peoples ego's (perhaps including my own) have got in the way -- but that's a whole different issue! Anyway:
- When working in two, people spend less time looking at forums, news and otherwise useless crap.
- Increases the Bus-Factor. That is, the number of people that need to be hit by buses before a substantial amount of domain knowledge is forever lost.
- If stuck on a problem, sometimes the best way to solve it is simply to ask someone to listen to you explain it (the answer becomes clear when you dictate the issue). This is a well-known phenomenon.
- When seeing each other work, staff can really gain an insight into how they spend their days and why they are an important asset.
- Staff can expand their skillset by observing each others experience and knowhow.
- Two minds are better than one when it comes to complex problem-solving.
- Bonding is always a plus.
Perhaps this list will help another cronie in convincing their managers of "pairings" effectiveness? Good luck.
A Ruby wrapper for the Discogs.com API
I recently noticed that Discogs.com, a huge discographies database, had released their API in the public domain. I think this is a really nice offering, especially considering effective use of the Ebay API can cost in excess of $50,000 per year...
Unfortunately, I couldn't really think of anything useful to do with the information. So instead I've spent the last few weeks writing a 100% Ruby wrapper for version 1.0 of the API. It abstracts all of the tedious work of handling requests/responses, parsing the XML, etc. This way, if someone else has a good idea (or I have one in the future), most of the work will already be done!
Anyway, enough of that. The specifics:
Support
The library currently supports everything in version 1.0 of the API as documented (sort of) on the Discogs website. Namely:
- Artists
- Releases
- Labels
- Searching (all of the above
Installation
I've setup the library as a gem so installation is as easy as:
$ gem sources -a http://gems.github.com $ sudo gem install buntine-discogs
Usage
Here is a small taste of what you can do:
require 'rubygems'
require 'discogs'
wrapper = Discogs::Wrapper.new("my_api_key")
artist = wrapper.get_artist("Master's Hammer")
release = wrapper.get_release("611973") # Supply an ID.
artist.name # => Master's Hammer
artist.releases[0].title # => Finished
artist.releases[1].year # => 1989
artist.releases[4].extraartists # => [ "Arakain", "Debustrol" ]
release.title # => "Ritual"
release.labels[0].name # => "Osmose Productions"
release.formats[0].descriptions[0] # => "LP"
release.styles # => [ "Black Metal", "Death Metal" ]
release.tracklist[1].title # => "Pad modly"Finding out more
I have setup the repository at github. Please let me know of any bugs/problems you find. I'm open to suggestions for improvement, also. Fork me!
On the wiki at github, I have setup a bunch of examples and some documentation for each resource.
Programming Bolverk; a simple example
Since Bolverk has gone live, I've had a few friends mention to me that "[It] sounds like a cool idea, but I have no idea where to start". Because of this, I've decided a small example of how one might go about programming her is in order.
I will demonstrate how to read in two binary numbers, determine their sum, and then print that value to the standard output.
0: Write the machine instructions
Below is an example of how you could write the solution (along with notes in parentheses).
2143 (LOAD register 1 with the decimal value 67) 220D (LOAD register 2 with the decimal value 13) 5123 (ADD register 1 and register 2 and store the result in register 3) 33A1 (STORE the contents of register 3 into the memory cell A1) D1A1 (PRINT the contents of memory cell A1 as a decimal number -- 80) C000 (HALT the program)
1. Load the instructions into main memory.
Click the "Write / Load Program" link and wait for the thickbox dialog to load up. Once ready, copy the following into the textarea:
2143 220D 5123 33A1 D1A1 C000
The "Starting cell" select can be left as is. Now click "Insert". You will notice that the program has been loaded into main memory. The populated cells will appear purple.
Note, you can manually change any single memory cell by double clicking it, changing the hexadecimal value, and then clicking out of the cell.
2. Initialise the program.
Click on the first cell of your program. You will notice the "Initialize Program" button will be enabled. Click it.
You will notice that the first two cells of your program code will be highlighted. This, as the legend shows, is the next instruction the machine will execute.
3. Run the program.
This is the easy part. You simply have to click the "Machine Cycle" button for each machine instruction in your program. At each instruction, you will see how the processor is being affected.
Try it! By the time the program ends, you should have the decimal number "80" printed to Standard Output.
Introducing Bolverk: 8-bit Microprocessor Emulator
Over the past few weeks, I have been developing a fun little application in an attempt to broaden my knowledge of the way a processor works at a low level.
What I've come up with is a Web-based, 8-bit Microprocessor Emulator with it's own Machine Language implementation. It contains 2kb of memory and is programmable in Hexadecimal.
I developed the "engine" first and then wrote a simple Web-wrapper for it using the Sinatra framework. Check it out here: http://bolverk.andrewbuntine.com. Or fork me on github!
I tried to keep the process enjoyable and did not worry myself too much with the finicky details that would undoubtedly plague engineers implementing a "real" machine. I questioned myself so many times that, after a while, I began to simply ignore my inner, logical self and simply kept hacking away. So even though writing a program to perform 8-bit floating point arithmatic in a machine language implemented using an interpreted and dynamic language is, quite obviously, far beyond ridiculous, I still reached my goal of... well, I don't know... total schizophrenia?
The true usefulness of such an application lies in it's effectiveness as an educational tool. Recently, I was watching some of the excellent Richard Buckland lectures from the UNSW Comp. Sci. course and I noticed that they were actually using something quite similar. The emulator they were using was only 4-bit and contained just 16 bytes of memory, but the concept was almost identical. What a confidence boost!!
Any feedback, bug reports, comments -- please send me an email!
My first Merb site
Just a quick note to my legions of loyal followers (hey, Mum), I've just finished my first website written using the Merb framework.
Development travelled along relatively well. I ran into a few issues early on with dependency hell and some bugs and/or missing functionality in a few gems. I blogged about a few of my hacks.
Here is my (partial) technology stack:
- ORM: DataMapper
- Tests: RSpec
- Views: HAML/SASS (which I won't be using again, even though it's very well written)
- Hosting: Dreamhost (using Phusion Passenger, which was easy to use with a config.ru file for Rack)
I still haven't worked out how to properly get Capistrano working with the Dreamhost setup, but shit happens...
Auf wiedersehen!
First post!
Welcome to my new blog. I look forward to writing about a whole bunch of uninteresting shit!
I am sure eventually I will get bored or lose motivation, but while it lasts, lets see what I can come up with.
Cheers,
Andy.