A couple of days ago, I was catching up on my [Wait Wait… Don’t Tell Me!] podcasts during a long car ride and listening to the episode where they play [“Not my Job” with Biz Stone], co-creator of Twitter. I had a bit of an epiphany while listening. It struck me that there were some really good reasons for *why* Twitter worked.
First, let’s point out that [Twitter] probably *shouldn’t* have worked. When it first debuted, it was limiting, had no collaborative features, and crashed frequently. Now, it’s a go-to “social media” (I still hate that phrase) portal (this one, too, unless it refers to a video game series) for celebrities and corporations. Once a service breaks into the corporate mainstream, it’s officially successful.
At the beginner, there were obviously far better methods to communicate. Have something to say to someone? Use email or an IM service. Want a group conversation? Try IRC (if you’re a geek) or a chat room (a/s/l check). Want to publish something? Start a blog. There was practically no reason to use Twitter at the beginning. Sure, it was new and shiny, but only techies seemed to be onboard. These early adopters are also the ones most likely to use any of the other technologies. Although it seems like the best reason to be on Twitter is because everyone else already is, that was hardly the case for a long time.
So, why did the early adopters actually use Twitter? Twitter offered a couple of things that no one realized they needed.
The 140 character limit is pretty much the great innovation for Twitter. I think that is the basis of success. I know, it sounds weird and it’s counter-intuitive, but that’s the magic. You’d expect such a stark limitation to be a liability. “Microblogs” likes [Tumblr] were becoming popular, but they were too flexible. Yes, that’s a problem.
In my opinion, Twitter works well because it works how people want to use it. I could post something to this blog, but I tend not to because I like to post long-form, introspective essays. I want to use it for code and editorials. I don’t want to post brief observations. For that reason, I haven’t posted nearly as often as I’d like. A lot of blogs start like this. Many blogs start off strong, but then trail off after just a few days or weeks. Of course, many Twitter accounts are abandoned soon after they start, but that’s another issue. People are more likely to put up a dozen words about their day or what they’re eating than to write a paragraph about something on their mind. By enforcing 140 characters, Twitter avoids the problem of blogging services. No one sits down at a blank page and wonders about what they’re going to write. Everyone that uses Twitter uses it almost reflexively. No need to think, just tweet. This limitations gets people to use it because it lowers the psychological barrier to entry.
Twitter also gained traction because it was flexible. A lot of Twitter features like replies, retweets, and hashtags were created in the community. They were adopted as official features over time. Early users took the limitations of the service and pushed it further. Twitter had an easy to use API (for a while) that could be easily scrapped, extended, and added upon. Twitter also allowed wide leeway to 3rd party clients to expand upon the feature set. They saw what was happening in the community and wrote the code to expand these ideas into actual functions. Twitter responded by making them official and extending the backend and API to offer better support to the user and the developer. It is with great sadness that Twitter appears to be shuffling off 3rd party clients in order to bolster the official offerings. Twitter was greatly enhanced by outside innovation, especially in the early days.
Twitter is one of the few services that gets both “friending” and “following” right. Blogs are great and syndication through RSS and Atom make them more easily accessible. Despite this, they remain fairly opaque. Twitter allows for commenting, conversations, and syndication in a simple and easy manner. Sure, it all happens within the Twitter service rather than across an large number of systems and platforms, but they got the workflow right. I hope that if there is more innovation in the blogging space, that it borrows these elements. Conversations should be as easy to follow as on Twitter (as well as offering the ability to avoid the noise of other conversatiosn). Comments should be easy to send and centrally authenticated. “Following” is also a low-barrier form of subscribing. This would also require a central authentication, but it’d be awesome to simply click a link and your RSS reader knows about it without needing to be activated.
These three basic features were a perfect storm for Twitter. The artificially low barrier for posting (and high barrier to complex expression of thought) generates use. The flexibility and extensibility by the system (especially by early 3rd parties) expanded upon the basic use. The collaborative elements were the best options for both advertising the system as well as encouraging frequent checking and use. Twitter got these right and that’s why it’s become so popular. That’s why it works so well. It didn’t make sense as a service (and still doesn’t to me), but it works because people use it and it adapts to usage patterns. For that, I salute the founder and developers of Twitter for giving us something we didn’t need with limitations that didn’t make sense. Sometimes, that’s what the user needs, even if it doesn’t make sense.
Apple announced yesterday yet another online service, [iCloud](http://www.apple.com/icloud/). iCloud supercedes MobileMe, which replaced .Mac, which overtook iTools. 4 generations deep and lots of server technologies later, Apple is still trying to sell iDisk and email addresses. Except, with iCloud, Apple isn’t really selling anything other than the music sync component. Still, I wanted to take a moment to remember where we’ve been and offer a short eulogy for MobileMe.
When iTools came out, it was simultaneously underwhelming and useful. At the time, OS 9 was still holding on and the notion of “cloud services” or even AJAX was still foreign. iTools provided a few essential services for general computer users. It introduced the iDisk, a WebDAV storage space, HomePage, website development software in the browser, and email addresses. For savvy computer users, the storage was small, iDisk was slow, HomePage was limiting, and, honestly, who needs *another* email address? Still, for $100, the average Mac user could build an online presence and play with technologies that would later become standard.
As it grew, Apple’s online services seemed to suffer from identity problems. Apple was never able to connect any particular feature to a uniquely Mac experience. Perhaps worse, Apple implemented several features that were outclassed by other services. Apple’s email was servicable, but GMail was arguably better. iDisk was fine, but Dropbox used a different online metaphor that felt more responsive and solid. Even more damning, the other services were free.
When Apple finally settled on MobileMe, they had a crew of web designers that they had poached for Safari development as well as a talented crew of programmers and artists. MobileMe became something more than anyone really foresaw. Apple’s online applications went from second-rate, to first in class examples of web applications. MobileMe’s online offerings feel like robust, real alternatives to Desktop software. GMail looks quaint in comparison.
Unfortunately, MobileMe was always a bit of a tough sell. Even though the online applications were top notch, why would any Mac user go online for their email and calendaring when they’ve got native applications? GMail also provided email, calendaring, and address book services that just worked when synced with the native apps and was free. MobileMe was still being sold as a gateway to web publishing with iWeb as well as an application syncing service.
The syncing service was spectacular, too. You could purchase a new laptop, set it up with MobileMe, and then start using it for actual work within 30 minutes. Unfortunately, 3rd parties didn’t appreciate the genius. Many are using Dropbox as a syncing solution. Others are rolling their own. Perhaps iCloud can sell the developers on the need for a 1-login syncing solution.
Over the years, Apple’s online services tended to be overpriced for the product that they provided. Now that Apple is providing the service for free, they’re also building on top of one of the best online experiences available. I had a laptop stolen this year and consider my $99 MobileMe fee to have been worth every penny when I got my replacement. Over the air syncing with iOS devices has been brilliant (although a lot of that could be wrangled for free due to the robustness of the native apps with other services). I still don’t use the iDisk or the web hosting feature, but I’ve been a fan of MobileMe.
When Steve Jobs says that MobileMe “wasn’t our finest hour”, I have to respectfully disagree. Anyone who has used MobileMe’s online email client knows how powerful and surprising web applications can be. Apple led the way in championing certain technologies and ate their own dog food in creating these services. MobileMe was a great service even if it followed the trend of Apple’s overpriced online service lineage. Now, with iCloud, I’m expecting an even better experience than with MobileMe. Apple slowly built to this point and I can hardly wait to get my hands on it.
I recently had a request of showing how to execute arbitrary Nu code inside of an Objective-C context. I’ve created a simple project to demonstrate this. It is available on [Github](https://github.com/Grayson/NuTermExample).
The first step when working with Nu is to add the framework to your project. The example project creates a small app that simply accepts Nu input in one text field and outputs the results in another. Any errors are eaten by the console, so you may want to run Console.app if you actually try to use the program for anything more than an example project. For the most part, though, you can ignore the example app. Everything is detailed below if you just want to dive in.
With Nu added, you’ll need to set up a Nu parser, pass in some Nu code, and execute it. Fortunately, Nu is really easy to use inside of Cocoa. Once you’ve imported the Nu framework into a file (`import `), you need to create the parser (`id parser = [Nu parser]`). Now, there are two steps to actually executing Nu code. The first step is to parse it into tokens (actually, NuCells internally). The second is to evaluate the tokens. This evaluation is the actual execution. Fortunately, this is simple. First, the parse, `id parsedNu = [parser parse:nuString]`, then evaluate the parsed code, `id result = [parser eval:parsedNu]`. Of course, I prefer to use the convenience method that handles both at once:
id result = [parser parseEval:nuString];
So, how do we use this in a real application? From the example above, the only thing that is missing is the `nuString`, that is, an NSString containing Nu code. That string could come from anywhere. You could pull it from your application (`NSString *nuString = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@”nufile” ofType:@”nu”]];`) or put it directly into the code (`NSString *nuString = @”(+ 1 1)”;`).
Now, the question is “How do we set up the Nu environment?” Well, everything in the runtime is already included in our Nu environment, so we get access to all of the other frameworks that we’ve brought in:
; This just works if you’ve imported CalendarStore.framework
(set store (CalCalendarStore defaultCalendarStore))
(set calendar ((store calendars) lastObject))
; Close the main window for the example project linked to above
appdelegate = ((NSApplication sharedApplication) delegate)
((appdelegate window) orderOut:nil)
This is great, but what about injecting our own objects into the Nu runtime? This is just as simple as everything else:
NSString *example = @”This is an “;
NSString *nuCode = @”(+ exampleInjection "example")”;
id parser = [Nu parser];
[parser setValue:example forKey:@”exampleInjection”];
NSLog( [parser parseEval:nuCode] ); // result: “this is an example”
Basically, inject whatever objects you want into the Nu code by calling `setValue:forKey:` on the parser. You can also get objects back out fairly easily by calling `valueForKey:` as in:
NSString *nuSource = @”(set rejectionExample "Nu->ObjC")”;
id parser = [Nu parser];
NSLog( [parser valueForKey:@”rejectionExample”] );
When you’re done, you can just clean up and close the parser (`[parser close]`). Working with the Nu parser is fairly easy once you know where to look. Nu.h has all of the information there if you want to read a bit more into it.
For further reading, check out my [Nu PluginManager](https://github.com/Grayson/pluginmanager/blob/master/src/NuPluginManager.m). Of special interest in the code is how I call functions by injecting objects and then calling the top-level functions using those objects as parameters by simply parsing and evaluating a bit more code. I could always get a reference to the actual function NuCell using `valueForKey:`, but this may be the most simple way without need to know anything about how Nu works internally.
[Jeff Atwood](http://www.codinghorror.com/blog/archives/001317.html) makes a particularly salient point in taking about the lack of direction for [Markdown](http://daringfireball.com/projects/markdown). The specification for Markdown seems to languished for the last five years while the number of implementations have sky-rocketed. I have also written an [implementation][num] for [Nu](http://programming.nu/). My implementation was based on [PHPMarkdown][phpm]. At the time, I had realized that Markdown was somewhat abandoned and that PHPMarkdown was undergoing rather frequent updates and revisions. It also came with a test suite. In the end, I had decided for myself that Markdown proper was no longer the reference version of the specification, but rather that PHPMarkdown had usurped the original implementation. As more implementations of Markdown are written (available in nearly every popular language and using all manner of parsing algorithms), we must ask if we need one to be the basis of comparison or if the spec is already pretty much complete.
[phpm]: http://michelf.com/projects/php-markdown/ Read the rest of this entry »
My day job is now as a system’s administrator for a school. I basically keep the servers running, all of the computers in working condition, repairs and tech support as needed, and tons of other things vaguely computer related. I’ve had a lot of headaches and I wanted to make a quick list of some of the problems that I’ve had and the solutions that *seem* to fix them. Any comments, corrections, or additions are greatly appreciated.
Read the rest of this entry »