Wednesday, May 30
I ask you, grasshopper, which is better: flexible code or tiny code?
"Ah," you exclaim, "Learned master, it is a trick question: code which is tiny yet flexible is best!"
WRONG! Tiny code is always best. Now you must carry water up the hill for the rest of the day.
--
What can we learn from this simple tale? Well, one thing is, I'm not very good at writing stories. But is there something deeper?
When I first started coding, way, long ago (on a PDP-11, which was essentially when I'd get eleven Pterodactyl Dinosaurs to sit down and do some Processing for me), I thought code should be flexible at all costs. If I were creating, say, a program to write a one-line message to the screens of other people logged in to the same machine, I'd write it, say, so you could plug in other kinds of screen-manipulation packages besides curses(3). Even though, you know, none would be invented until "time sharing" was something you did with condos, not processors.
The fundamental nature of coding is that our task, as programmers, is to recognize that every decision we make is a trade-off. To be a master programmer is to understand the nature of these trade-offs, and be conscious of them in everything we write.
You've probably seen some variant of this, but I'll show you my version. In coding, you have many dimensions in which you can rate code:
- Brevity of code
- Featurefulness
- Speed of execution
- Time spent coding
- Robustness
- Flexibility
Now, remember, these dimensions are all in opposition to one another. You can spend a three days writing a routine which is really beautiful AND fast, so you've gotten two of your dimensions up, but you've spent THREE DAYS, so the "time spent coding" dimension is WAY down.
So, when is this worth it? How do we make these decisions?
The answer turns out to be very sane, very simple, and also the one nobody, ever, listens to:
"START WITH BREVITY. Increase the other dimensions AS REQUIRED BY TESTING."
--
In Delicious Library 2 we have a feature where we will automatically find the libraries of your friends if they have published them. Of course, with any matching system, the trick is, how do you know this is really *my* friend named "Mike Lee", and not one of the other 17 million "Mike Lee"s around the world (that whore).
So, I came up with a basic algorithm for pulling all Delicious Libraries by the owner's name first, then disambiguating within those afterwards. One of my programmers said, "Well, what happens if we get 1,000 hits for John Smith?"
And my reply, not at all tongue-in-cheek, was, "Well, then we would be very, very rich." Seriously, if 1,000 John Smiths had registered our program, think of how many customers we'd have total: millions. Multiply that by $40, and one possible response to the problem of "too many John Smiths" would be: "Who cares, let's all move to Tahiti and spend the rest of our lives on the beach sipping rum."
I kid! Mostly. My point is, we'll have PLENTY of warning and PLENTY of resources when 1,000 John Smiths start to plague us. Note that both of these are necessary -- if I were, say, deploying just some website, and I didn't make money based on the number of people using the site, I'd be a lot more worried about it blowing up before I was ready -- there would be no guarantee that I'd have the time or resources needed to handle the problem.
In this particular case, there is a slightly slower (execution time) way to do the search that would eliminate the 1,000 John Smith problem, which I will do the day it starts to become a problem. Then I'll push a free update, and my customers will never know that it could have been an issue.
But note that, even though I *know* how to solve this problem (and increase the flexibility dimension), I'm not going to solve it now. Why? Because (a) this would kill my code brevity, (b) it would make the program run slower for everyone in the meantime, (c) it would introduce more instability, and (d) it would take a bunch of time to program and debug, so I couldn't do other, cool features.
This is really key: there's a solution out there that I know is more flexible -- many people would instantly consider this the "best" solution, and consider everything else a hack. My point, which I'll say again and again, is that there are MANY dimensions with which to evaluate any solution to a problem, and flexibility is NOT paramount.
--
When most people learn objective languages, the first thing they do is go ape. I mean, they create superclasses that have one method, which is stubbed out, and twenty children classes, each of which varies by one line of code. They fall so in love with objects that they think everything needs to be its OWN TYPE of object.
Often this is done in the name of flexibility. "Look, I have this abstract superclass which currently does the drawing for all my buttons, but you could subclass it to, say, draw 3D text!"
There is a related ailment, which is the "complete class" syndrome. Many programmers, when they create a new class, add a ton of features to that class to make it "complete" -- that is, they try to anticipate everyone who may ever use this class, and they add methods that those hypothetical users may want.
Let's say, for instance, Apple didn't have an NSArray class. So, you write your own. Great! I support you. Now, in your program you need to add objects to the end of the array and remove them from the end of the array. Ok, write those methods. But, wait, you say. Maybe I should add some more methods? Get an object from any index? Insert at the beginning? Why don't I make this more flexible, you say? NO! NO NO NO!
Now, you may be saying to yourself, "What's wrong with flexibility?" Strangely, I was about to tell you. The problem is YOU ARE NOT A LIBRARY PROGRAMMER. YOU WRITE APPLICATIONS. (Note to Ali Ozer: IGNORE THIS SECTION.)
If you find yourself writing a class for your "library," then:
(a) You're not writing your application, which is where you make your money,
(b) You're writing something that you're hoping Apple will someday replace, which is a sucker's game,
(c) You're writing code you are going to have to test SEPARATELY from your app, because BY DEFINITION you've added functionality you didn't need,
(d) You're never going to really know which methods in your library work and which ones don't (eg, which ones are used in shipping programs) because you don't have user base that a company like Apple does (and witness how buggy even their under-used frameworks are),
(e) You're writing code that is going to need documenting (or some other way to comprehend it), so you're requiring yourself and everyone at your company to understand not JUST all of Apple's APIs (which are, at least, SOMETIMES documented) but also yours, and, possibly worst of all,
(f) You are attempting to predict how your application's needs will change in the future, and spending time NOW on your guess, instead of shipping the damn application, getting feedback, and THEN making changes.
Let's look more closely at (f). It's the same old thing again, isn't it? "Don't optimize your code until after you time it" becomes "Don't make your code more flexible until after you have a plan for what your app."
--
Here are some concrete rules I enforce at Delicious Monster, now:
- We don't add code to a class unless we actually are calling that code.
- We don't make a superclass of class 'a' until AFTER we write another class 'b' that shares code with 'a' AND WORKS. Eg, first you copy your code over, and get it working, THEN you look at what's common between 'a' and 'b', and THEN you can make an abstract superclass 'c' for both of them.
- We don't make a class flexible enough to be used multiple places in the program until AFTER we have another place we need to use it.
- We don't move a class into our company-wide "Shared" repository unless it's actually used by two programs.
--
So, next time your boss tells you to "be more flexible," tell him Wil Shipley says you shouldn't. He'll probably give you a raise!
Labels: code
Monday, May 28
More than any machine, the original iMac can be said to have single-handedly turned Apple's fortunes around -- making once-'beleaguered' Apple Computer simple, cool, and fun again. Besides bringing Apple much-needed mindshare, the iMac brought in scads of cash for Apple before the iPod was even a glimmer in Ives' eyes.
Thus, it would shock many to hear that Apple is, in fact, planning to retire the iMac this year.
Of course, they're not. That would be stupid. Still, I bet I could get a ton of other rumor sites to pick this up as "news" if I kept going with it.
Labels: humor?, mac community
Sunday, May 20
Today I got mail from a young, impressionable lad that read thusly:
Hey Will,
I've been reading your blog for about a year now, and I thought you would be the best person to answer this question.
I'm coming to the point in my life when I need to decide what it is I want to do (I'm 16). I've been programming for 4 years on mac and for 6 years in general, and I'm looking into computer science as a major, but I just don't know what it is! I've read the pamphlets, course outlines, etc, but they don't just answer it, what the fuck is computer science? Is it math, physics, programming? I honestly can't get a straight answer.
I've seen people parade their knowledge of O(N*log(2)) or whatever, but I just don't see how its relevant to programming. Everywhere I go I get mixed signals about what I will actually be learning during Comp Sci (for instance, my high school 'computer science' course consisted of Microsoft BASIC, and boolean logic, the fuck?).
I guess what I'm trying to ask is what you learned during you comp sci days, and what you actually gained out of it and continue to apply to this day (if anything).
Well, young lad, I think this is an excellent question, mainly because you asked it of me, and that means I get to go blah blah blah some more, which is my nigh-favorite activity.
--
First off, high school computer classes are, in my experience, a joke. In my day I literally got an 'A' for showing up -- the teacher knew I could program circles around him so he didn't even bother assigning me problems, I would just go to class (sometimes) and do whatever I wanted for an hour, and every quarter I'd get an 'A'. I'm disappointed with this teacher for not trying to challenge me more, but, hey, free period, so I didn't complain. (Now that I think back on it, a lot of my high school teachers gave up on me this way -- "Here, have a free 'A', in return you must not bug me for the rest of the quarter.")
--
There are myriad reasons why nobody can answer what kind of science is "computer science" -- prominent amongst them is that it is its own science, so it's not math or physics or programming, per se. Also, most people don't
know, since unlike math or physics, computer science is not something most people experience every day in their normal lives. You drop an apple, you see physics in action. Tip a waiter, you're doing math. But what the hell is computer science? (To be fair, I think most people think majoring in math would mean, "like, learning 2+2 and shit.")
Another reason is that "computer science" programs vary INCREDIBLY from school to school. At a Real University(TM) you're going to be studying actual science and engineering principles in the context of designing and programming systems; at one of those technical institutes you see advertised on late-night TV you're going to be taking a class in "Advanced Java Programming" where you learn how to print "hello" over and over.
--
I went to the University of Washington, which was, at the time, ranked one of the top schools in the nation by some ranking organization. I honestly have no idea who does those ranking, or what kind of criteria they use. There were distinct advantages and disadvantages to going to a big school.
Let me first say some good things: I got to study under some amazing professors at the UW. Dr. Jean-Loup Baer was our department chair (which is a catchy rhyme if you sing it) and taught a course on machine language that I still remember. (I wrote a "Connect-Four" program in VAX assembly that won... some of the time.) I did my honors thesis for Dr. Hank Levy, who literally wrote the book on assembly that we used for Dr. Baer's class.
Dr. Ed Lazowska was pretty famous in the community and taught a bitching course on operating systems which explained the fundamental functions of and problems faced by any operating system, in the context of real operating systems (mostly UNIX) -- we wrote a fully-functioning OS for that class, with demand-paging and protected memory, and it was cool as hell. My student advisor was
Dr. Tony DeRose, who now is a Pixar bigwig and was and is a hell of a nice guy (but unfortunately I took my graphics class from the OTHER graphics professor in our department, who was, well, a big jerk-head). It's pretty cool to go to the movies and see my old advisor's name in the credits.
I got to take classes from
Dr. Alan Borning (who was part of XEROX Parc in the really cool old days) and got to think about what programming languages
could be instead of what they are.
And, yes, I learned O(n) and O(log(n)), and they
are extremely valuable to everyone who writes code. I learned the then-current approaches to simulations and to artificial intelligence (which was mostly, "uh, maybe one day") and to operating system design and graphics libraries and all kinds of things that I have used over and over, because it turns out that none of this knowledge ever goes out of style -- optimizations will ALWAYS be about finding ways to do less work instead of finding ways to do the current work faster, and there will ALWAYS be bottlenecks in the system that require thinking about; whether they are giant mag tapes or hard drives or nvram or holo-memory doesn't make a difference.
--
But this points to the problem of the school I attended, and my strongest advice for anyone considering colleges and universities: at state-funded Universities, professors live or die by the papers they publish in coordination with grad students. Their performance in the classroom counts for almost nothing, and most of them wouldn't teach at all except that they are required to by the state. Their funding comes from research projects (that the grad students do), and the more successful and widely-praised their projects are, the more money the professors get. Period.
For instance I had the extreme privilege of learning compilers from a professor who was famous in the industry and who was one of the best teachers I have ever met -- he actually taught using the socratic method, letting you figure out the answer by asking you exactly the right questions. Every year students rated him the best professor on their evaluation forms. However, he left while I was there -- he didn't get tenure at the UW, because he hadn't done enough research for them -- he spent all his time teaching undergrads, which is verbotten at the UW.
This system also means the grad students are in a lofty class above you, the lowly undergrad -- to an extent that I believe puts most other departments to shame. I'm not even going to try to guess at the millions of dollars flowing into the UW over the years from DEC, Intel, Microsoft... but it's a LOT. The computer industry has money, and loves research, because turning a research project into a real product takes years in our industry, not decades. Microsoft backed a dumptruck full of money up to the UW shortly after I left, and I'm not sorry I missed that.
So, at the UW, the grad CS students all hang out in locked labs with personal desks, and hang out with the professors in their offices, go to picnics and BBQs at professors' houses... whereas undergrads worked in public labs, had no access to the 'better' equipment, and were only allowed to talk to their professors during very restrictive "office hours" that were, like, from 7am to 8am every other Tuesday. There was no learning by osmisis for undergrads. The idea of an undergrad going to a party at a professor's house was anathema! We weren't even invited to the TGIFs that were held
in the very same building.
Now, in contrast, my sister, who was a year older, attended Reed, a small, liberal college, and majored in medicine or drugs or some this. She constantly told me how she'd have dinner parties with her favorite professors, get high with them, etc, etc... mind you, this was Reed, but, still, I really felt like there was some happy medium I was missing. I wanted more from my college years. I wanted some professor to takes me under his wing and teach me there is joy and subversion in poetry, and then he's fired for it, but not before one of my classmates kills himself because he wants to act, or something.
--
I'll give you a story from my undergrad years that still sticks in my craw, to this day:
- As head of the student chapter of the UW ACM, I walked into a professor's office (not one of the ones mentioned above) to ask for something for undergrads. I wait and wait while he shoots the breeze with two graduate students, who are lounging around his office with their legs over the sides of the chairs, talking about some scandal or BBQ party or some damn thing. Finally, he looks up at me, and I present my case: could one of the many, many laser printers that are scattered around the building in locked closets (so that only the graduate students could get at them) be opened up to undergrads, so we could use laser-printing on occasion, instead of only having access to a line-printer on a public second-floor lab?
This professor asked me some question in response -- I don't remember what it was, or what my response was -- this was 20 years ago. But I do remember what he said after that: "Why are you wasting my time?"
I looked at the two grad students still flopped down in the chairs in his office -- his office, which I had never been inside, before; even now, I was just hovering at the doorway -- and I left. I never spoke to him again.
--
But let's not end this on a bitter note. There are many nice postscripts to my college career.
Years later, when I was at Omni, we were asked by Apple to meet with some representatives from Pixar, who were considering using Cocoa technology, and wanted to talk to some outside experts, and, you know... we were just so damn bitching at the time. So we're at WWDC, and we're sitting at a table with some Apple homies, and a certain Pixar fellow sits down, and we start talking about how great Cocoa is and what all Pixar could do with it, and then he stops and turns to me, "Hey, don't I know you from somewhere?" and I say, "Yes, Dr. DeRose, you were my student advisor fifteen years ago. And you were awesome, thank you." I can't tell you how happy I felt to be able to tell him that.
(I should mention at this point that normally I wouldn't blog about a meeting like this from WWDC, since it would be assumed to be NDA, but pretty much every NDA says you're allowed to talk about events that have been announced through other channels, and it's well-known now that Pixar uses Cocoa -- in fact
Wave gives talks about the amazing things he does with it fairly often.)
Plus, Dr. Lazowska saw my name in the paper a few years ago and wrote me, as well, and I was pretty touched that he remembered me and that I was his student. I don't know if he remembered what a snot-nosed brat I was -- hopefully not.
It's got to be a neat thing, to see your students go on to success, to know you were a part of it -- I really do owe a lot to Dr. Lazowska and the other professors. I realize that more and more as I try to teach people myself -- I find that I'm using their lessons to teach a new generation, just much less formally.
--
So, those are my tales of college CS. Is it worth it to go through a CS program? Yes, if it's a good one. I would certainly recommend a smaller college or university if you're an undergrad, but even large ones are going to teach you a lot, you just can't expect that you're going to have drinks and dinner with your professors. Unless you are a hot co-ed, and the professor is my dad. (Just kidding, dad, I know you stopped dating your students after you married one... Oh, SNAP!)
Are you going to use the lessons you learned in CS in 'real-world' programming? Yes. Not all of them, but the ones you do use are going to make a HUGE difference. The delta between programmers who know when to use a hash table and those who don't is enormous. The delta between programmers who understand the O(n) stuff and those who don't is also huge. Too many programs are written by programmers who, frankly, suck at theory, and they write slow, crappy programs as a result. Get a solid basis in the science before you become a programmer.
Labels: advice, mac community