Perfect is the enemy of good, but far more importantly, perfect is the enemy of *practice*. Allow yourself to make weird flawed things
— Jaiden Mispy (@m1sp) April 28, 2016
Janie had a blog the other week about her self-destructive tendencies, one of which is to do things that feel productive but aren’t. A lot of her problem is reading a bunch of background information prior to starting a major project, something that has so many unknowns it’s imposing.
I get it because I’ve been in the same situation and done the same thing, and it didn’t work. But an approach far more naive turned out to work better.
Back when Bill and I (with Daniel as our editor) were starting the first iPhone SDK book in 2008, I knew it would help if I did an iPhone side project in something that really motivated me. Instead of just doing that sort of minimal project that has only enough scaffolding to show off a certain API, like most of the book examples were, I’d do well to create a useful, interesting app.
What I decided to do was to make a streaming web radio app. I figured “how hard could it be”, since I’d already gotten something similar working in Java (this is when my day job was editing java.net, and just off writing two Java books. Come to think of it, my jicyshout project still exists on Sourceforge. God, what’s more pathetic: working with Java Media Framework, or hosting an OSS project on Sourceforge?)
So, anyways, how hard could it be? Actually, I never got it working. At first, I was blindly ignorant — I’d used the QuickTime APIs via Java Native Interface a few times, but had no clue about basic Core Foundation facts like how
CFStringRef is not just a decoration around a
char* C string, and was surprised when I kept crashing every time I dealt with strings. And researching the basics of CF led me down a rathole of cross references that eventually led to digging into long-obsolete volumes of Inside Macintosh just for the sake of the Component Manager (but with a bunch of baggage I didn’t know to throw off).
So, doing a bunch of up-front research ahead of a big hard project that’s well above my skill level didn’t work. What does? This:
This is my “Throwaways” folder, at
/Users/cadamson/dev/iphone throwaways. It has 86 project folders… almost none of which work. The whole idea of a throwaway project is that I’m spitballing code and figuring things out. I do not care if it leads to a working app, and I go in expecting it will not.
The idea is to take what I know and give it a few hours or maybe a day to see how far I can get with it. If I do get to something that works, that’s great; more more often, it’ll help refine my questions, and clarify what I do and don’t know, and what I need to figure out.
In the case of these Throwaways, a lot of them from 2008-9 date back to when Apple Developer Connection contracted a bunch of feature articles from various freelances via an old editor friend of mine from O’Reilly, and I did a three-part series on low-latency audio with Audio Units and OpenAL (don’t go looking for these… none of the work ADC commissioned from me and others in the field ever got posted, but we did get paid at least).
At that point, all we had to go on for Core Audio on iPhone was the
auriotouch (for “Audio Unit Remote IO [Cocoa] Touch”) sample code from Apple, which is one of those projects that does not just the basics, but a bunch of extra stuff, like a fast-fourier transform for an onscreen waveform, which looks cool, but makes it hard to winnow things down to the absolute basics to get audio in and out of the phone. Apple’s examples are often like this — they want to make something big to cover all the bases and make something that looks cool, but it does make it harder for the true beginner to isolate the absolute basics from the extras. (This might be why I decided to have the Core Audio book do four different Audio Unit examples, instead of one big hairy one.)
(Things never change: Apple’s recently-released Audio Units v3 sample code project has 14 Swift files, 11 Obj-C, 3 and Obj-C++. You can’t say it lacks ambition or completeness, that’s for sure)
So anyways, I needed to start over and walk the path of bare-bones capture and output myself, and it took a series of throwaways to do it. And with no OpenAL sample code available for Mac or iPhone (and much of the cross-platform code depending on a deprecated
loadWAVFile() function that was never available on iPhone), it took nearly a dozen attempts for me to get an AL example working.
What I learned in this process was that much as I started by wanting to do this one cool thing, it was initially beyond my reach. And instead of getting blocked on that, I found it was more helpful to isolate parts of the problem (or of the framework I was studying) and just screw around with that until I could get a handle on it.
Swift playgrounds are very much in the spirit of this, although I find their applicability more limited than would be ideal (it’s unfortunately tough to build a working UI in a playground, especially for beginners).
But the point remains: a great way to learn by doing is to make your own throwaway projects in private. That way, when they don’t work (and they usually won’t work), nobody has to know, and you can build on that experience to get to where you want and need to be. Honestly, I should still do this more than I do.
EDIT: I don’t think this piece came off with quite the level of humility I’d hoped for, to express the fact that when I’m new at something, I really suck at it, and it takes a while before I even know how much I suck at it. What I’d hoped is that I could find that first failed web radio project — alas, I think it’s lost to time — and we could all have a good laugh at 2008 me trying to call
strlen on a
CFStringRef. Or, as Max the rabbity-looking thing would say, “let’s point and laugh at the ensuing carnage (oh crap, I said ensuing).”