Many of us call the opening keynote of WWDC by Steve Jobs the Stevenote. Well I’m dubbing the closing keynote of MountainWest RubyConf the Jimnote in honor of Jim Weirich. But… maybe I’m too late. It was sort of like watching a Mike Tyson fight (back when he was his prime and KOing people in 90 seconds.)
Jim gets up, tells us that this is the most important thing that programmers should know and brings up three slides:
and sits down.
OK – here he comes and more fired up than ever.
A brief tutorial on LISP.
syntax: s-expressions (s-exps), atoms, lists
nil is the same as empty list
functions: car == head, cdr == tail (trivia: car is address register, cdr is decrement register), cons, eq, atom
special forms: cond, lambda
LISP is turing complete with just this small set of rules.
Now we go into a discussion of how Jim solved the problem of showing the same graphics between an 8-bit memory-mapped 8080-based computer and a 16-bit vector-based PDP11. The answer: FORTH.
FORTH “words” (like Ruby methods) were very short and FORTH itself used reverse polish notation (RPN.) Jim learned about factoring properly this way. To port FORTH all Jim needed to do was write some primitive words (aka graphics drivers.) Note that Jim says that Nintendo console games were written in FORTH.
UDFs – now we’re looking at unducted fans engines which has spinning blades which would pull in air into the engine but did not succeed.
But… designing these engines was an interesting gig. It did involved multiple threads that access shared data. Which is a huge headache. Perhaps a way to help with this would be to avoid system locks but this worked out to one chance in a million of failure. Which seems like good chances, but it failed roughly once a day (since it executed roughly 1.5 million times a day). The point is that writing threaded applications is hard especially when accessing shared modifiable data.
Which brings us to Erlang…
There’s four types: Atoms, Variables, Tuples, and Lists. Hmm I think I see how this starts to form a Moebius strip.
You can’t change a variable once its assigned, which is actually pattern matching. I would call this immutable data. I use immutable data when passing objects between threads in my Cocoa apps.
Then we go into a client/server example in Erlang and it starts to remind me of Cocoa’s Distributed Objects.
In Ruby you send messages to objects and in Erlang you send messages to processes.
Erlang in comparison is simple, powerful and spawns processes quickly. Ockham might have approved.
“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.” – Tony Hoare
We live in a (programming/business/consumer?) society that values complexity. In the Ruby world, we’ve come up with Camping, Merb, and Rubinius.
So in summary: Simplify.
- Small core.
- Simple rules.
- Powerful abstractions.
Follow-up question: Where do you draw the line between simplicity and metaprogramming? Answer: If it solves a problem you’re having, go ahead and metaprogram – as long as its a significant amount (more than one line or so.)