« May 2007 | Main | August 2007 »

July 27, 2007

Where Were You When You First Experienced the World Wide Web

Recently, I was writing up a self profile. I got to the part about starting to work with the Internet and it made me think about where and when I first saw the World Wide Web. To be clear, I was using the Internet before the WWW, but seeing the graphical web for the first time was consequential. I was in college, in the basement of Hill Center. This is where they used to (and may still) keep CS students. Computer labs and offices often have the distinction of finding space in basements or "dungeons".

In any case, it was 1993 and I was back in one of the private offices in the bowels of Hill Center (I worked for the school's computer facilities department, so I had access to more people and equipment and software than most). A friend called me over to show me the original Mozilla web browser. I was floored. I had never seen anything like it.

In many ways this memory is fresh, like the memory of where I was when I heard that the Space Shuttle Challenger had exploded on January 28, 1986 (I was at a friend's house playing hooky from school). Or that Princess Diana had died in a car accident. Or some people remember where they were when JFK was assassinated (not me... that was before my time). These latter incidents are all tragedies, different from seeing Mozilla for the first time, but the memory is as clear. We don't have a shared cultural date for the experience, but I suspect I'm not the only one who found it a memorable one.

The iPod of the (Near) Future

In my last post, I talked about the problems with the current incarnation of the iPod. Today, I'm going to talk about the iPod of the future. What will a such a device be like?

Well, it will be much closer to Sansa's homely Sansa Connect than the iPod that comes with the iPhone. The Sansa Connect uses Wifi to connect to the Yahoo! Unlimited subscription music service. There is a recommendation service and some limited social interaction via recommendations from friends also on Yahoo's music service.

Though it's a an early attempt, it hints at the device of the future: the beauty and interface design of the iPod combined with the connectivity of the Sansa Connect and the social interaction and recommendation engine of services like Last.fm.

Frustratingly, the iPhone -- which has network access through both Wifi and AT&T's Edge network -- is amazingly close to achieving the what the Sansa device fails to. The iPod interface could have two modes, connected and disconnected (subway/airplane). In connected mode, the iTunes catalog can be browsed and listened to in it’s entirety. In disconnected mode, you can listen to a cache of songs that you've listened to recently, favorites, and recommended songs (proactively downloaded for you as Tivo does with TV shows). Basically, the networked iPod would turn itself into a standalone iPod when no connection was present.

The largest factor in delaying this inevitable future is not a technical or interface challenge but a business one. The current iTunes model been responsible for billions of dollars of Apple revenue. An "iTunes Unlimited" subscription model would effectively cannibalize the song buying model and potentially alienate customers who have spent money to "own" songs purchased from the iTunes music store.

What to do with all that music people have bought? When “iTunes Unlimited” launches, offer people a discount on their subscriptions for all or part of what they’ve spent to own songs on iTunes. So, for example, a person who has spent $100 at the iTunes music store would receive 3 months free of iTunes unlimited. Perhaps the discount could be greater if it proved to be a sufficient incentive to get people to buy a new high-margin device.

So, that is, as best I can imagine it, the near-term future of the iPod and portable music devices. Though none of it is technically impossible today, practical considerations are likely to, unfortunately, push off the arrival of "iTunes Unlimited" on the networked iPod for another 2 to 4 years.

July 26, 2007

Is online movie rental a commodity?

I got an email from Netflix yesterday that they were reducing my monthly rate: "We're lowering the price of your Netflix plan!". Great news, but I have to wonder why they are doing it? I already had a good deal, because I signed up nine or ten years ago, I have the original plan (4 DVDs at a time) for the price of the 3 DVD plan now. I love the service and I've never had an issue with the price. I was perfectly happy paying $20.99 a month. Or maybe it was $23.99? I don't really know, nor did I really care. The service is great, what matter a few bucks. The convenience and the quality of the service has always been much more important than the price. And in my mind, it's a substitute for paying for premium cable channels. We only have basic cable.

My favorite Netflix feature is the queue (which was around from the beginning). It's great because I can add movie titles whenever I see an interesting movie poster on the side of a New York City bus stop or hear about a cool old movie from a friend over a cup of coffee. I don't have to think back about what I was interested in seeing in order to pick my next movie. I can even add movies that aren't yet available on DVD. A brilliant move... I want to add titles as I think of them and not have to keep another list of things I want to add ("my queue of things to add to the queue") at some time in the future. I probably have 40 or so items in my queue now, many of which are new or recent releases in the theaters.

Netflix has great customer service, too. For example if a movie gets lost, they replace it immediately... no questions asked! A great example of The honor system at work.

So I had to wonder: why drop the price? I think a more typical marketing approach with regard to price cuts is to change the price for new customers, but leave existing customers where they are. Such a change would help acquisition, but not retention. So changing the price for existing customers, must be more about holding off defection to copy cat services. I.e. Block Buster, etc. I haven't tried these other services, but I have to wonder if the industry is really at the point of a commodity, where the key differentiator is price?

The recent Q207 Quarterly Earnings Call for Netflix sheds some light:

Our strategy evolution is shifting some profits into growth investments for as long as our competitor runs their online service at a considerable loss. The tactics of our increased growth investments are higher service levels, lower pricing and slightly less marketing because we believe that is the most efficient combination for Netflix at this point.
I hope this strategy works out. I have an emotional attachment, since they were the first in the market. I'm sure the industry will evolve to a download or streaming model. And Netflix will still be at the forefront of that movement. The delivery method isn't critical to this business model. Instead, the important factors are the queue, the recommendations, customer service, ease of use and so on. This evolution will also make Block Buster's one advantage (the ability to swap a DVD at a local store) obsolete.

What To Do With Old Books

I happened upon this totally unexpected, very creative service at my local coffee shop the other day.

Sitting on the coffee table was a novel with this note on the front.

Bookcrossing Sticky Note

Bookcrossing? Let me flip through. I quickly found a bookmark and a bookcrossing sticker on the inside front cover:

Bookcrossing Sample Label

What a great idea! I have lots of old books, but I prefer a lighter lifestyle. Less baggage, it's good to be mobile. This is a new found desire, so coincidentally; I just dropped off a couple of boxes of books to the local library as a donation. I could take the rest of them there, but I like the idea of the low overhead distribution of bookcrossing. Plus, with this method I can follow the path of each book as it makes its way into the hands of new owners. Evidently, they've been around for a while with half a million books in 120 countries, but I've never run into them.

Let the journey begin. After signing up with bookcrossing, the first step is to "Register" your book. This is where each book gets its own book crossing id (or BCID) and is added to the bookcrossing database. You enter author, title and category info (there is a box to enter ISBN and have the book info looked up on Amazon.com, but this didn't work for me). You can also rate the book and add comments or a review if you like.

Now you need to label the book with the BCID. You can print labels and stickers, or buy them from the bookcrossing supply store. I did the latter, as I want to support the concept. I bought a 25 pack (25 each of a bookmark, a sticker for the inside front cover, and a sticky note for the outside). They arrived 3 or 4 days later.

Next step is to "Release" the book. This simply means to drop it in some public space where it can be found by an unsuspecting stranger. At the web site you mark the book as released and make a journal entry of where you released it. If you want, you can receive email whenever someone else catches your book or makes a journal entry about it.

I've released my first book at another coffee shop. It's a fantasy novel I read years ago. I'll release the others at different locations around New York City, and maybe some in other cities I visit.

The one oddity is the "Tell-a-Friend" service. There are links for common mail clients (online and offline) to help automatically load friend's email addresses, such as Gmail and Outlook. If you click Gmail, it requests a username and password with assurances that they don't save this information. This is probably true, but it's a terrible practice. Web sites should not be encouraging the casual disclosure of personal data. Thankfully, you can bypass the email clients and just type in email addresses directly.

July 25, 2007

Give Intelli J a Try

When I first started working at The Ladders, I used Eclipse. It was the standard editor for a programmer. Most people in tech use it. However, Josh kept raving about how great Intelli J was. I was skeptical at first, but after Eclipse kept crashing on me, I decided to give Intelli J a try.

After a few days of using Intelli J, I was amazed. It increased my productivity by at least 300 percent. Tracing and debugging code is a breeze in it. Every piece of code that refers to another piece can be reach by simply ctrl + clicking.

There are many “haters” of Intelli J. Their main argument is that Eclipse is free while Intelli J costs $499 for a commercial license. That is where their argument ends. There is really nothing in Eclipse that’s actually better than Intelli J. There are however many things that Intelli J does better than Eclipse:

-Click through every thing. If there is a .jspf file in a jsp, I can ctrl + click it and go to the file. If there is a jstl tag, I can ctrl + click it and go to the .tld file. I can even ctrl + click the function signature in the tld file and it’ll bring me to the function definition. Amazing! If I’m perusing an interface, there is a little button next to every method that allows me to go to the method implementation instantly. Eclipse has no such button. This saves a lot of time especially with manager interfaces that implement a method that calls a DAO interface that implements a DAO method.

-A change list for all your changes. For example, I create a change list called “fix ladders bug”. All the changes I make to fix this bug gets stored in this change list. But let’s say while I’m fixing the ladders bug, I have to switch to a recruit ladder bug. I just create a new change list and start working on my changes. When I finish, I can commit my recruit ladder change list and nothing that I changed for the ladders fix gets committed. Ingenious? Yes.

-Search results are tabbed! What a wonderful idea that Eclipse chose to never implement. If I do a search for a usage of a method, the search result is saved and tabbed so I can go back to it at anytime.

-There are a bunch of navigation features in Intelli J that are quite useful. You can use Ctrl + Alt + Left or Right arrow to go back and forth where you’ve been editing. It’s kind of like a go back button in a web browser except it goes to different places in the same file.

Do yourself a favor and get the Intelli J 30 day free trial. You can thank me later.

Lessons from my 1st Encounter with Event Handling in Javascript

When I first started writing Javascript code (not long ago), the first few things that I started to play with were onclick and onload events. So, how did I use to attach event to elements. Well, I would simply do this:


  element.onclick = foo;
  function foo()
  {
    …
  }

As I found out, this kind of event handling would not cut it. For instance, how would I add more than one event handler to the same element.

  element.onclick = foo;
  element.onclick = bar;

That was my first attempt to solve that problem and failed miserably since only bar() would be executed. So I thought, maybe I could delegate those two functions; that seemed like the perfect solution.

  element.onclick = foobar;
  function foobar()
  {
    foo();
    bar();
  }

Hey, it worked so I was happy. However, it did not took long to find out that this method of event handling was error prone, and it would create nasty bugs in the very likely case that some of other developer had already registered an onclick event on the same element in the same way I did. Well, then I started to look to more advanced ways to do this. The solution came from the W3C event-handler registration model. The W3C provides two methods: addEventListener and removeEventListener. This model would allow me to register many events to an element without totally wiping out someone else’ code. Ok, I know some of you are like “This doesn’t work in with IE”, and you are 110% right. I found out this serious browser incompatibility the hard way. But it was not hard to find an answer, use IE’s attachEvent and detachEvent methods! Putting it all together would look something like this:

  function registerMyEvent(element, event, fn)
  {
    …
    if(element.addEventListener)
    {
      …
      //false allows event bubbling, while true allows event capturing
      element.addEventListener(event, fn, false);
    }
    else if(element.attachEvent)
    {
      …
      //in W3C model the events are not preceded by the ‘on’ word
      element.attachEvent(‘on’+event, fn);
    }
  }
  function removeMyEvent(element, event, fn)
  {
    …
    if(element.removeEventListener)
    {
      …
      //false allows event bubbling, while true allows event capturing
      element.removeEventListener(event, fn, false);
    }
    else if(element.detachEvent)
    {
      …
      //in W3C model the events are not preceded by the ‘on’ word
      element.detachEvent(‘on’+event, fn);
    }
  }

This script allowed registering and removing event handlers. It is important to note that I did not use browser sniffing at all. Instead, I use object detection, so when IE sees if(element.addEventListener), it will return false, and it would go into the next condition, and that is the behavior I want. Now going back to event handling, that solution is nice and simple, and most importantly it works (beware another ‘but’coming). But, there is a serious problem that lies in the use of Javascript’s keyword this within a event handler function.

  //registering an event with the code found above
  x.registerMyEvent(myElement, ‘click’, foo);
  function foo()
  {
    this.something = ...;
  }

In IE’s model, using this refers to the window object!!! It does not refers to the object in which the event is registered on!!! Why? The explanation would be that IE considers attachEvent and detachEvent as a global function, and not a method belonging to the object that is invoking them. So, just be careful with the this keyword usage in the event-handling functions. Also, you can also opt for more advanced approaches which I will not discuss here, or perhaps use of other solutions like the ones that YUI or Dojo offer. However, for me it was a great exercise to experiment with event-handling the way I did. It did not only teach me about event handling, but it also introduced me to serious browser incompatibilities, but most importantly taught me a lot about how Javascript works.

YSlow Review

Yahoo! YSlow came out today and this is my mini review. It's an addon for the super useful Firebug.

It's very cool but gave http://www.theladders.com/ a grade of F. WTF? Looking deeper you going to want to configure your CDN After that our score improved to a D, still ugly. Had to be a way to squeeze more out without going around and rewriting all our front end code.

Unlike other tools that measure load time to judge page performance. This works much like a static code checker, and finds bad patterns that you should avoid. Because knowing your page takes 1200 milliseconds to load doesn't tell you a whole lot about what you can do to make it faster.

YSlow checks that your HTML follows these 13 Rules. They're kind of a laundry list of best practices for writing fast loading HTML. Running it on a url will point out which rules are not being follow and the areas of the page that violate them.

So back to how our homepage did. YSlow complained that we weren't gzipping our content. Now we've got a fancy ass load balancing NetScaler that does gzip for us. But it turns out we didn't turn on gzip for our akamai served content. A quick config change and we'll be gzipping all our text/html, text/css and application/x-javascript content from Akamai. This should provide a huge reduction in page just from that small quick change.

It takes a day or so for the change to propagate around akamai's network. So I'll have to run YSlow tommorow to see if we can get a passing grade from YSlow.

Some lessons here, I can't preach the value of tools that identify bad patterns enough. Now we all know "gzip your content", but without a nice clear tool to verify this, how many of us are going to start digging into HTTP headers to actually check?

On the Java side, I rely heavily on tools like FindBugs to keep my code free of common pitfalls. How many of you know that DateFormat's are not thread safe? Ever seen weird ArrayIndexOutOfBoundsException's in your server logs that you can't reproduce? I bet you it's cause two threads are parsing dates at once. We had this all over our code. Now the javadoc says it, but my IDE's autocomplete doesn't, so it's nice to have a tool like FindBugs to remind me to keep those DateFormats local.

Looks like YSlow will be a welcome addition to my suite of static code checkers.

July 24, 2007

Dynamic Entity Framework

Having a high number of web-pages means that the Product team keeps demanding for a variety of dynamically generated web components like popups and sliders on the pages. I will call them Dynamic Entities or DE henceforth. Currently we support three types of Dynamic Entities - DE's on our website. The most popular is the cloudover, which is nothing more than a popup having the focus while graying out the parent browser, thus actively forcing the user to act. Sliders are other user attention grabbers; these are small in size and slide out from the navigation tab, but they do not get the user focus. The last one is the good old popup which can be closed or ignored by the user; needless to say these are used only when the user should be given an option to ignore it, if he wishes so.

The framework has some basic code constructs like a small controller which applies the various rules such as sampling rate, maximum number of samples, views/ web pages containing these dynamic entities, entry conditions, recurrence conditions and exclusion conditions. All the DE's are available as rows in the dyn_popup table; an interceptor filters over each of the user request and delegates to the framework. It applies the various rules of all the DE's and chooses one to be shown. Each web page has a component which triggers the DE if it has been selected and passed to the page by the framework.

All the visitors to the website are not shown the same content. There might be slight differences in wordings, placement of a link or availability/unavailability of a field in a form. These help in fine tuning the site and also keeping a control group of users who are not exposed to a campaign. DE framework takes care that only a specified percentage of the visitors be exposed to a DE (sample rate), and that the campaign be stopped after the specified number of total views (max samples).

Two key concepts are 'Entry Conditions' and 'Recurrence Conditions'. Entry conditions for example can be used to distinguish a specific type of targeted user such as guest, basic or premium; or the user hitting a page second time in a session; or the user haven't visiting an important area of the website for a long time. Recurrence conditions allow a DE to be shown multiple times such multiple times in session, month or even once in a lifetime of a user. It helps to have a separate construct for each condition, although they may all derive from a single abstract type thus providing a convenient interface.

As soon as a user requests a page, framework picks up the associated DE's for that page, 'Entry Conditions' and 'Recurrence Conditions' these are checked and non-conforming ones are removed. Selected DE's are fed to an 'Exclusion Manager', which applies exclusion conditions to exclude the ones not needed, and then the first one in the list is selected to be shown to the user.

Needless to the say that all the information about a DE being shown should be entered in the database with the various parameters for Business Intelligence and data-warehousing purposes.

Optimizing TheLadders Website for the iPhone

It sounds like additional work for the UI and Design teams at TheLadders but with a little bit of tweaks and following some guidelines, we can optimize our website to look good on a small screen on the iPhone or any cell phone.

The iPhone uses the Safari browser which itself uses the Web Kit engine. I am not going to talk about designing and testing pages for the Safari browser in addition to the debugging for IE6. But by following good development standards, we can ensure that the site will work and look good on a small screen.

Here are iPhone specific issues in a small browser:

- There is no input device except fingers.
- Web pages are designed to receive mouse events not finger events.
- Fingers pinch. Mouse clicks.
- Because of the smaller screen, the text size is much smaller as compared to the standard screen so the links will appear too close to each other. The links should not be too close to each other.
- There is no scrollbar in the browser.
- Tapping on a webpage, iPhone centers on the block of the element <div> <img> etc. Avoid wide blocks of texts and use columns that organize content into small sections.
- The iPhone does not render WML. It does support XHTML mobile doctype or sites at .mobi domains.

Even though this support requires a website to be 100% styled and optimized for mobile phone, as well as a desktop browser, a site still can be optimized to look good on a mobile bowser. In addition to rendering as a standard webpage, an iPhone specific style sheet can be used.


Specifying an iPhone Style Sheet:

The following code can be used only for iPhone and wont affect other devices.


<link media=”only and (max-device-width: 480px)”
href=”iPhone.css” type=”text/css” rel=”stylesheet” />

The iPhone Safari browser supports GIF up to 2 MB. JPEG up to 128MB. For larger images, the iPhone alters the layout of the page to fit them.

Surprisingly, the Safari browser on the iPhone does not support:

Window.showModalDialog()
Mouse-over events
Hover styles
Tooltips
Java applets
Flash


So we need to design the pages with smooth degradation.

Regarding security, Safari on the iPhone uses the same SSL implementation that it uses on desktop. So encryption is secure to prevent the information from being listened to on the wire.

These were few simple suggestions that if followed by the Product, Design and UI teams, can make TheLadders website look good in iPhone browser.

July 23, 2007

Development Project Plans Made Simple

While looking for Requirement Doc (Functional Spec) samples, I stumbled upon Joel Spolsky's piece on "Painless Software Schedules". It's old (in Internet time), written back in March 2000. Yet, many years later I still find it to be tremendously insightful and, basically, "the right approach".

I've used similar practices for quite a while with great success. Alternatives like critical path dependency tracking just don't enlighten the delivery date. Like eXtreme Programming, Joel took the instinctive solutions that practical developers use and dialed them up to 10:

  • Avoid MS Project -- "Use Microsoft Excel": As most software developers know, it's a great tool to organize just about anything, and now I know why (read Joel's article for the answer)!
  • List tasks -- "Pick very fine grained tasks"
  • Estimate each task -- "Only the programmer can estimate how long each one will take". And don't "let managers tell programmers to reduce an estimate".
  • Estimates can change -- This is managed practically by tracking the "Original estimate" and "Current estimate" and updating "the elapsed [time] column every day".
  • Account for all the time that will be consumed during the course of the project --> track everything: Vacations, Holidays, Debugging Time, Integration Time, some extra buffer time, and development time.

Commentary

Here's my commentary. You should read Joel's article first. Otherwise, it will be like hearing half a cell phone conversation.

4) Only the programmer who is going to write the code can schedule it.

This is ideal. Although developers initial estimates tend to be fairly inaccurate, they do get better with time. Especially if there's historical feedback about how long a task actually took to compare to. I'm doing this more and more.

I do see a limitation, though. The development group is often called upon to estimate some work effort for planning purposes. The estimate is then used for budgets, hiring plans and scoping decisions. At that early stage, we have two problems:

  1. The requirements are to vague to mean much to a developer In this case, I like to get a tech lead to do the estimate. Since we don't have a great deal of insight into what we're building, we supply a Level 1 estimate (E0). The idea here is that it is an early estimate, with a very low level of confidence (see below for how I apply the confidence level for planning purposes). As we get more details on the spec, we can move to an L1, L2, etc. Each one with a successively higher confidence level.

    And, even when we get a better definition of what it is we need to build, we can run into this problem...

  2. We don't know when we're going to start the project or what developers will be available when we do start or even how many developers we'll be putting on the project.

    Not much you can do about this. Take your best guess. Maybe have a senior developer who is likely to be a lead for the project do most of the estimating. Make sure that they know that it may be a more junior developer who is doing the actual coding. Your only protection here is a lower confidence rating (or more buffer time).

As you get closer to the target date, have some specs to work with and know the developers involved, you can provide a more accurate Level 2 or Level 3 estimate (E2 or E3).

8) Put in line items for Vacations, Holidays, etc.

9) Put debugging time into the schedule!

11) Put buffer into the schedule.

It's terribly important to make your schedules realistic by accounting for real developer time that will be lost to a number of activities.

I start by taking out time lost to being out of the office. Vacation, Personal days, holidays, sick days. At TheLadders.Com this comes out to about 11% (10 holidays + 10 vacation days + 5 personal days + 5 sick days on average / (52 * 5))

I then estimate what portion of time is lost to non-project activities like team meetings, TPS reports and so on. This comes out to around 23%. At TheLadders.Com this includes things like:

  • Training (including conferences and lectures)
  • Non-project-related meetings
  • Time sheets
  • Social Committees
  • Interviewing new hires (few things are more important than filling that next open req for a Software Engineer)
  • Mentoring new hires
  • Performance Reviews, grades, goals
  • Work on internal presentations

These activities are important for a well run company. Just remember that they do take up time. Even a half hour here and there adds up. Not to mention the added burden of the frequent interruptions.

Unless this is a new development shop, a good portion of time will be spent on maintaining code that is already in production. The time spent on this will vary greatly depending on your situation. How many applications do you have in production? How often do you do releases? Are the same developers that work on new projects, also working on defects?

You have some leeway here to set this number, but if you go too low, you will have a rapidly increasing issue queue and you'll have to manage the debt on that. At TheLadders.Com, we're targeting a fairly trim 20%.

Finally, include some time for post-launch support. No project is perfect, so you can count on having to put out a few fires afterward.

12) Never, ever let managers tell programmers to reduce an estimate.

As developers, we're frequently asked "can't you make that estimate smaller?" Of course we can, but then it would be less accurate than our best guess.

However, it might be helpful for a technical manager (or senior developer) to brainstorm about "cheaper" ways to do it. Ask "What solution did you have in mind when you estimated this?" And "How else can it be done?"

And work with the business owners or product people... they probably don't realize that the lightning bug that flies around under the user's cursor is going to double the cost of the project. Let them know if a particular feature is going to be unduly expensive to build. Maybe the triple validation on the birthday field isn't really that important.

These ARE acceptable ways to reduce an estimate.

Conclusion

This method has in its favor simplicity, adaptability, comprehensibility and, in the end, it sets much better expectations. The point to remember is to make the system, your system. Modify the techniques as much as you need to fit your needs. Every development group and every company is different.

Why I'm Not Getting an iPhone

I’m not going to get an iPhone. It’s going take monk-like to discipline to keep me away from the Apple store, but I’m not going to do it. I’m going to hold on to my Treo 650, despite my issues with it. Why?

The iPod is deprecated.

I know people have gushed over the iPhone’s musical abilities – Cover Flow browsing in particular– but the iPod/iTunes model, in general, is broken. Why? There are quite a few reasons, but there are two that stand out.

1. "Owning" music is a burdensome task for the consumer. You have to buy songs -- a financial burden -- and you have to maintain a music library -- a time burden -- on your hard drive. The activity required to maintain such a library is a distraction from the activity of actually listening to music. It doesn't seem like a big cost, but it's non-trivial compared to a zero-maintenance subscription service like Rhapsody. If you factor in having to backup and possibly having to upgrade your hard drive to store thousands of MP3/WMA/AAC files, it starts to add up. If you've ever tried to listen to DRM'ed files on a different device than they were purchased for, you've seen how consumer-unfriendly the current way of doing things is.

I think in a few years we'll regard maintaining physical music libraries in much the same way many now regard maintaining an analog photo library. For the photographer, all of the work associated -- paying to develop the photos (in both time and money), creating and storing physical photo albums, etc. -- detracts from the basic joys of taking and sharing photos.

Additionally, any personal music library will always be trivially small in comparison with the library of available recorded music that a network service can provide. An 8GB iPhone holds about 2,000 songs. Rhapsody, for example, has 3.5 million songs.

Furthermore, in the current model, a computer is always required to be an intermediary between the user's library and the iPod. Every time a change to the library is made, it must be synchronized to the device. You can't even purchase music from the Wifi-enabled iPhone directly - a computer must be involved.

2. The iPod/iTunes model allows for a very limited amount of music discovery and social interaction.

The iTunes model ignores the primacy of discovery in music listening. If the cost of listening to new music is too high, people will do it far more rarely than they would like. And when you're not listening to new music and you're just restricted to your existing library, it feels stagnant. Where is last.fm and Pandora on the iPhone? I've discovered more new music I enjoy in a short time using those services than in years of slowly building and maintaining an MP3 library.

-------------

So, what will the iPod of the future be? I'll talk about that on Friday.