The iPad ain’t ending anything

February 1st, 2010

The haters are wrong, part one

I just finished an excellent blog post by my friend Blake Patterson. It’s about the iPad. Blake realized in the wee hours of Sunday morning that the iPad was actually Alan Kay’s Dynabook, emerging after 40 years in Steve Jobs’ turtleneck-clad arms. Seriously, it’s a great post. Go read it.

I think Blake may be right that the iPad is going to be a great device for developers and users. It’s a whole new playground for a set of mature, widely-known, yet still rapidly-developing technologies. It’s an incredible opportunity. People who are poopooing the thing, or suggesting it’s actually going to harm the computing world, are being unimaginative and pessimistic.

I find cynicism and pessimism applied to a lot of issues and events in the web development world. Maybe it’s the recession. Or this cold winter we’re having in the continental U.S. But the gloom and doom is dead wrong. And I feel compelled to explain why.

I’m not given, personally, to bouts of dizzy optimism. I’m not a bit light-headed at this moment. I think the future is looking awfully good for people who develop software for the Internet and people who use this software. And I want to pour some cold water on the clever people currently pouring cold water on the tech optimists. The Internet is not splintering, Apple is not going to end the golden age of the personal computer, the United States is not chronically short of talent, and our jobs are not all going overseas.

Read the rest of this entry »

Futures, promises, asynchonicity, and concurrency

January 28th, 2010

It’s a concurrent world, and, increasingly, it’s an asynchronous world too. Many things are going on at the same time, and it’s impossible to determine exactly when each is starting or ending. In other words, everything is fast and out of control.

As a software developer, both concurrency and asynchronicity are more important concepts than ever. But both are hard concepts, and they’re also hard to embrace in practice—the sequential model of programming is so ingrained in my head that both new structures for concurrency and asynchronicity in familiar languages and less familiar languages with built-in support for these concepts offer a steep learning curve. Fortunately, there’s been a lot of buzz, from separate origins, about two programming concepts that may, um, promise to deliver a brighter future to me and other befuddled developers.
Read the rest of this entry »

Excerpt from
“Notes on Postmodern Programming”

October 11th, 2009

I’ve wanted to cite this passage a few times now, but I can only find the essay in PDF form. So I’m just going to put the passage here, so I can point back to it in the future.

Geeks, if people regularly joke that they couldn’t understand what you do for a living, consider pointing them to this description of the process of writing a program to accomplish a specific task. There’s a lot of debate on Lambda the Ultimate about whether the authors are joking. For the record, I don’t think they are, but that doesn’t mean they aren’t intentionally being funny.

Read the rest of this entry »

Twitter, geocoding, and JavaScript in Baltimore

October 9th, 2009

I drove up to Baltimore’s Beehive coworking space last night to meet the folks in the Baltimore/DC Javascript Users group. We poked around the Twitter API and looked at both what you could get from the API via JSONP and what you could do with it.

Read the rest of this entry »

Lazy Enumerators in Ruby

September 30th, 2009

I gave a talk on Ruby’s Enumerators at the DC Ruby Users Group in August. I’ve posted my slides from the presentation, if you’re interested.  Basically, I discovered that enumerators make lazy evaluation easy to implement in Ruby, and applying lazy techniques with enumerators may yield more efficient and elegant code.

Read the rest of this entry »

A Ruby on Rails mystery, and the price of magic

June 22nd, 2009

I count myself lucky that I can earn a living programming with Ruby and in particular with the Ruby on Rails framework. But every tool, even the best, has a few surprises up its sleeve. Sometimes you get hung up on something quirky, but more often you’re having a problem with a feature—something that’s there by design. This is my story about one such problem I had with a Rails feature, how I diagnosed it, and what it means: metaprogramming is awesome, but it comes at a price, and in imperative languages, the price is side effects.

Read the rest of this entry »

Some gems from RubyNation 2009

June 15th, 2009

Nothing close to a complete review of all the quality talks I heard at RubyNation, the following is just a summary of cool things I learned about while attending.

For other resources, and some of my own snarky comments, take a look at the Twitter Channel for the event: #rubynation

TupleSpaces and Rinda

Luc Castera gave an excellent presentation about concurrency and distributed programming in Ruby. After basically saying that using Ruby’s built-in facilities for concurrency was a myth, he laid out several alternative approaches and applications. The most interesting was using Rinda to implement TupleSpaces in Ruby. Rinda can run as a service listening on a port, and it can manage a queue of messages to be processed by a TupleSpace, which is basically an associative value store, or a mini-environment. Other processes can monitor the contents of the spaces and pull data from them to run operations. This is the actor model: the spaces share nothing and communicate asynchronously with messages.

Take a look at Luc’s slides for all the info. Great talk. I’m going to look into Rinda as soon as I can.

Reek: A code complexity metric tool

Mentioned during Mark Cornick’s excellent talk on refactoring, reek is a tool to measure the perceived complexity of your Ruby code. Reek doesn’t like repetition, and it really hates long methods. It certainly doesn’t like my code: reek returned 41 warnings about my latest controller. More about reek on github.

Micronaut

From Relevance Labs comes a homegrown BDD framework that ended up embracing RSpec while promising to make your tests run faster. Use metadata to group and target your tests, and you may never have to wait for an hour for all your specs to run. According to Aaron Bedra, it’s also beautiful code to look at: a good example of metaprogramming in only 2 KLOC. And someday soon its tiny heart will beat inside RSpec proper. More on micronaut at Relevance’s blog.

Enumerators

How did I miss this? Already in Ruby 1.8, these constructs will be even more important in 1.9. They’re essentially lazy data implementations. Roughly:
>> r = [1,2,3,4].cycle
=> #<Enumerator #f00ba2>
>> r.take(5)
=> [1,2,3,4,1]

Directed Graph Data Stores

Holy Cow! I’ve only just learned the difference between Tokyo Cabinet (it’s a key-value store) and CouchDB (document-based data store). Ben Scofield, in his talk on categorizing comic books, explained these both but also brought up Directed Graphs, which I haven’t thought about since SICP. There don’t seem to be any highly-visible implementations of this storage method, although I believe that RDF models data as directed graphs. This is going on the top of my research list. Cool stuff.

A Wildcard: Reia

There was a lot of buzz about the new Reia programming language, but little concrete information. The estimable Hal Fulton gave a talk on the Ruby-like language for the Erlang VM, but even he didn’t seem to know much about it. Its creator user to run revactor, a Ruby framework that implemented the Actor model, and a language with Erlang’s spooky power and Ruby’s “curb appeal”, as Russ Olsen has it, would be superb. But it seems we’re a long way from being able to evaluate whether Reia will make a mark.

Lingo and Memes

Did anyone else hear the phrase “bikeshop it” several times during different talks? And how about the rainbows and puppies in Ben Scofield’s talk? I didn’t make it to Danny Blitz’s talk on Tiger Teams (Raarrr!), so I’d warrant I missed out on some great terms.

My Clojure Lightning Talk

I put together a 6-minute talk on Clojure, with Paul Barry’s help. The slides are here. I wish I’d also been able to mention type hints, for when you want to speed things up with static types; metaprogramming with macros and first-class functions; and Clojure’s robust metadata system. Maybe I’ll get to give another version of it again.

So Much Win at JSConf 2009

April 28th, 2009

Offered for your approval, one attendee’s observations of JSConf 2009, held this April in Rosslyn, Virginia.

First, propers are due to Chris and Laura Williams for setting this up. A conference for javascript is an idea whose time has come. The speakers were outstanding. The food and after-party were fantastic, too. If there’s a JSConf 2010, I’ll be the first to sign up.

Read the rest of this entry »

Caching, lazy sequences, and streams

January 10th, 2009

On the Clojure Google group there’s been a good discussion about lazy sequences and streams. The exchange goes to some of the fundamentals of the language, but if I have a decent grip on the issues, it sounds as though Mark Engelberg is concerned about the inefficiency of caching the results of evaluating n elements of a sequence like (def whole-numbers (iterate inc 0)). Here’s a bit from an excellent blog post in which he lays out his points:

No one would ever want to cache the whole-numbers sequence. It’s significantly faster to generate the sequence via incrementing every time you need to traverse the sequence, than it is to cache and hold the values. Furthermore, because the sequence represents an infinite sequence, there’s no upper limit to the memory consumption.

Engelberg would prefer non-cached lazy sequences, better described as streams, for most operations. Rich Hickey reveals that he in fact has an implementation of streams more or less up his sleeve, but he’s been holding back on adding it to Clojure’s core because streams bring their own issues and because it sounds non-trivial to add them–it would likely postpone the language’s 1.0 release. That’s my disco summary: please read Mark’s post and the whole discussion thread for everything I’ve missed and left out.

My own contribution to this debate might be to point out that there are plenty of scenarios in which caching is crucial to the construction of procedures. As I often do, I go back to SICP for examples. In the chapter on streams, Abelson and Sussman discuss how nice it would be to write recursive procedures, and gain the simplicity and readability of recursive code, but gain iterative efficiency, that is, linear growth of memory and execution time. They claim that laziness gets them that. As illustration, they provide a recursive definition of the Fibonacci sequence, which I here translate into Clojure:

> (def fibs (lazy-cons 0 (lazy-cons 1 (map + (rest fibs) fibs))))
#'user/fibs
> (take 10 fibs)
(0 1 1 2 3 5 8 13 21 34)

Without caching, this would be a bear. With caching, getting the nth Fibonacci number should be a matter of one addition operation. And we get beautiful code. Sure, this is an academic example, but consider how powerful the one-line definition is. It reads just like the natural language definition of the sequence: the first term is 0, the next is 1, and each successive term is the sum of the two previous terms. Awesoma powa.

Rich’s main worry about streams seems to be that since Clojure promises to let you treat many Java structures as sequences, it can’t be sure it is wrapping a source of immutable data. Between two evaluations of a lazy sequence, something could change in the Java object, and then the n elements of the sequence that your two evaluations share could be different.

That isn’t supposed to happen. With caching, it wouldn’t. Evaluating the first ten elements in a sequence like this fixes them for as long as the sequence is in scope. Later evaluating the first twenty, you will get the same items 0 through 9 as you got before.

So streams would not promise immutability, necessitating a separate abstraction interface from sequences and complicating the current everything-is-a-sequence/seq-able beauty of Clojure.

Perhaps there are other ways to get non-caching performance out of sequences. For example, some Clojure data structures are lazy without using lazy-cons. Stephen Gilardi explains how a clojure.lang.Range object responds to rest with another Range. Something like (doall (range 10000000000)) actually discards each of these “rest” Ranges as it goes. Maybe if you’re careful about your collections and the operations you perform on them, you can get better performance now without streams. Perhaps new seq-able structures that iterate like Range can help enough that we can avoid muddying the language.

When not handled in a functional setting, i.e. when side effects matter, structures like dorun and doseq that don’t retain the head of the sequences should provide speed and efficiency too.

Finally, as Mark pointed out, there’s scoping to consider. If you don’t bind your sequence to a name, then as soon as it’s evaluated, the JVM’s garbage collector should be able to clean it up. Not ideal, but at least the GC is very efficient, and the unneeded sequence will be unlinked quickly.

I’m curious to see what happens next with streams in Clojure. It will be hard to make everyone happy either way.

On Clojure: A close look at Luke VanderHart’s Markov Chain generator

January 7th, 2009

The DC Clojure Study Group is digging into Clojure. One of our members, Luke VanderHart, contributed a program that parses a text file to build a Markov Chain generator: it will produce an arbitrarily long text that should mimic the style of the file you gave it by basing its output on the proximity of words or characters in the file. Cool stuff.

What I’m posting here is a close reading and interpretation of Luke’s code. I’d like to understand it myself and elucidate it for others, and I want to identify ways to add future lessons about Clojure into its code. For example, how could, or should, concurrency be used to increase the efficiency or modularity of the creation of the index at the heart of the generator? As it stands now, the code makes excellent use of lazy sequences and Java interop for reading the file. So let’s roll up our sleeves and dig in.

Read the rest of this entry »