C4: Each decision is an opportunity to fuck up
I was fortunate enough to attend the fourth edition of the C4 conference in Chicago, September 25th to the 27th.
C4 is a developer conference, oriented towards Mac and iPhone independent (“indie”) developers.
The talks are intended to get you out of your comfort zone, and to expose you to new ideas. To make you think about a new way to explore problems.
This year, several BlitzTalks were presented. These talks are five minutes long and have 20 slides, auto-advancing every 15 seconds. It is fair to say that the BlitzTalks stole the show and were very appreciated by the audience. It was obvious that a lot of craftmanship went into each of those bite-sized talks.
I gave a BlitzTalk at C4, which was titled “Friction-free documentation” and was very well-received. I have included it in this post for completeness’ sake, because I obviously did not take notes during my own talk.
One of the funnier, and probably coincidental, aspect of this year’s C4 was all the contradictory advice that was given. For instance, “you should have a web form for contact info” (Aspeslagh) vs “You should never have a web form” (Welch). Or “Don’t use private APIs” (Drance) to “Here’s how to load a plugin in 64 bits now that Input Managers are gone” (Morrisson). Or “JSTalk is the future. Applescript is dead” (Rentzsch) to “You should always have an AppleScript interface” (Correia).
After all, the conference was exciting, thought-provoking and insightful. The food was excellent, and a lot of beer was drunk.
Apologies in advance…
This is my account. It has my biases. I may have summarized things in my own words, this is not verbatim. For that, you will have to wait for the videos.
I took quite a few notes, but some talks just did not lend themselves to note-taking. For example, Mark Boszko’s excellent “Video and You” was, well, very visual, and I don’t draw that fast.
It was especially hard to take notes in the BlitzTalks, they were, as Mike Ash put it, “like a shotgun blast to the frontal lobes, in a good way“.
So this is a transcription of my notes. There are probably some errors in there; if you see some please let me know and I will gladly fix them.
And if I did not capture your talk fully, or at all, that can also mean that I was so absorbed by it that I could not take notes.
I do have a special apology for Marshall Culpepper. I do not have any notes from his talk about Appcelerator, but the only reason is that I was physically drained from giving my BlitzTalk, which felt like giving a 30-minute talk in 5 minutes. That’s a lame excuse, but it’s the only one I have.
Rentzsch – JSTalk
One will note that JSTalk is intended for Desktop applications, while Objective-J (see 280North.com) is intended for Web apps.
JSTalk contains a framework, an optional editor and a command-line tool. You can add JSTalk support to your app with one line of code:
[JSTalk listen]. This exposes your classes and object model in much the same way that FScriptAnywhere does. No need to write an object model wrapper like you do for AppleScript.
Benefits: fast and easy to do
Drawbacks: everything is exposed, nothing is documented unless you have sample code.
Note that you can save a JSTalk script as a truly stand-alone applet, as the script bundle can contain the JSTalk framework, which is pretty small.
Drance – How to be a Good Developer
Matt Drance was a developer at Apple, moving from DTS to System Software. He became indie a few weeks ago and would like to share, from the inside, how to be a Good Developer™.
First, you must have and cultivate your contacts at Apple. To do this, it helps a lot if you make great stuff.
Find your focus, and polish that application. Don’t be shy, do some marketing and it will attract Apple’s attention. Get listed on MacOSX downloads: it’s free!.
Adopt Apple technologies early and often. Submit to the ADA: you may not win, but some smart and influential people will look at your application.
Go to Apple Events as much as you can. WWDC is not mandatory every year, but don’t avoid it either. If there are TechTalks or kitchens in your area (or relatively close), try to attend as much as possible.
When you have contacts at Apple, stay in touch. Sending promo codes to Apple employees is a great way to do this.
Information, Organization and Diplomacy
Log bugs! If it’s not in Radar, it does not exist. Never assume that Apple knows.
Try to log good bugs. For the title, think keywords: ER (enhancement), REGR (regression), 10A342 (build number).
Note: bug titles are editable, so make sure that this information is also in the description.
More info is better. Shark samples are very useful.
If you can, attach the smallest sample project that reproduces the issue. A screen recording is also a very good way to explain a problem: more often than not, an engineer will look at a screencast and think: “I know exactly why this is happening”. This is good.
Think big! There may be a larger perspective here. You don’t know who else can be affected by this, might be thousands.
Your Enhancement Request can make Apple products better. For instance, the overlay controls in the iPhone camera were originally an ER for putting mustaches in front of people’s faces. Now they are used for Augmented Reality apps on the iPhone.
Duplicates happen, but they are important in weighing a bug. A good bug might also contain more info and help pinpoint the problem.
Answer your bugs. You may disagree politely (for instance “as designed”). Be civil, but you can also ask that it may be converted to a feature request. Make sure that documentation bugs are marked as such, as they are on a different track / release schedule.
If the Next Major OS release is not soon enough, you can request a Clone for Software Update. No guarantees, of course.
Your elevator pitch for your bugs should always be ready. You should know your bug numbers: keep a prioritized hitlist / wishlist, complete with bug numbers. If it is a clear, brief and forwardable document, and you send it to a contact at Apple, it has a good chance of being passed around.
Diplomacy and Trust
It is very important to establish trust. Assume things are under NDA. If unsure, ask. Keep things quiet: don’t blab about next releases, and the possible fixes in them.
If you see one of your Apple contacts listed in the press, on a blog, something, tip them off.
Don’t name names: email@example.com may not have been supposed to help you!
Stick to the public API. Private APIs will break the trust you spent years building up.
Control yourself. Be fair in public, and firm in private. Be nice in Radar, and think before speaking.
Overall, stay positive and friendly. Apple is made of humans too!
Dribin – Unit Tests
These tests are difficult to automate. They are usually slow. This is often your UI.
Several solutions exist for this (e.g. Eggplant) but they tend to be very high-maintenance.
You are better off having good QA people, and beta testers.
System tests often don’t do well with edge cases, because they are so rare.
These tests can be fully automated, or launched on-demand (e.g. nightly). They tend to test several areas in-depth (ex: file I/O).
They can be relatively slow, their time is counted in minutes. 20 minutes is not unusual.
These tests are very, very fast. So fast that you could run them at each compile and not notice. His app has over 200 unit tests and they run in less than a second.
Unit Tests are always automated, repeatable and self-checking (meaning that they report failures in a standard manner, be it a build break or an exit code).
Unit tests should not talk to a database, the network, the file system, or require a special setup of your environment.
UTs rely a lot on fake (mock) objects. For example. Core Data has the option of an in-memory store which is blazingly fast because it is not serialized to disk on every transaction. That has limited uses in the real world, but for Unit Tests it is essential.
Benefits include regression testing (did I break something that worked 5 minutes ago?), the ability to refactor, code that is cleaner and easier to maintain. It also allows testing hard-to-run conditions (what if that counter was 40,000?) and helps pinpoint the locality (scope) of errors.
Tests are often used as sample code, and so promote faster development.
Refactoring is improving your design after it has been written, in order to make your software easiter to understand. It will help you find bugs, and program faster, but to do that you have to have good unit tests.
Note that the MVC pattern in general makes code easier to test (see the Delegate pattern), but watch out for huge, all-encompassing controller classes.
Wayer – Translucent databases
What if you had a database of truly anonymous data?
Note that most americans can be uniquely identified by age, sex and zip code. Scary, huh?
If you remove the root user, you push the security to the edge, to your users: they have to remember their passwords since what is stored in the database is a hash combining their name and password. That way, if the database is compromised, no private information is divulged.
You may run the names through a simplification function first (e.g. ALLCAPS, no spaces) to help with entry name variation.
If you do not have a password-recovery system (and you may not have one, it is acceptable) you may have to throw away data, make a new account. This might be acceptable (e.g. throwaway email accounts) or not (bank / health records).
Welch – Carrot and the Stick
What to do when your users are angry at you.
Listen to your users: they have something to say. As long as they are talking to you, they are still passionate about your product. This is good.
Even if they use profanity, they still are professional.
Communication is a two-way street. Engage your users with modern means of communication. You can even call them: they will listen. Don’t have a simple web form as the only way to reach you.
Don’t tell them what to think. “Not a bug, but a feature” is not the correct response.
Your users are human, too. And if they can feel that you are human, that will go a long way.
Don’t try to cater to every user. If you honestly can’t do a certain thing, because you either can’t or there is no business case for it, tell them. And maybe recommend another product. You will make two people happy: the user who wanted to buy your product (but won’t) and the other company whose product you recommend. And you have not lost anything: it’s not money you would have had anyway. But this kind of honesty tends to come back in terms of trust, especially for future products.
Finally, there are two classes of users whom you may ignore, because the insignificant amount of money you will get from them pales in comparison to the time that they will cost you.
The New Media Douchebag can be totally ignored. The Scobles, Winers and Arringtons pretend to wield a lot of power but in fact they do not. Don’t be intimidated by them. They are a fickle bunch, and if you start to kiss their ass they will love you until the next shiny thing comes around, which may be tomorrow. And then you will have kissed ass for nothing.
The blogloon can also be ignored. But make sure that beneath the bile that they are trying to spread there is not a valid issue. Because blogloons typically don’t express their ideas clearly, good things can be lost in the noise. But once you have identified their issue (if there is one), you can ignore them.
Fackler – DVCS internals
Augie Fackler wrote and maintains hg-subversion, the premier hg interface to svn. He had the following tidbits of information regarding the lesser-known DVCSs.
Darcs was written by a physicist, in Haskell, over the principle of commutable patches. With those patches, you are essentially transforming your source tree from one version to another using a transform function, which is reversible. While seductive in theory, it turns out to be extremely slow in practice (on non-trivial source trees). Plus did I mention that you have to install a Haskell compiler?
Monotone is so security-conscious that every patch is signed, to the point that if you remove a patch in the middle of a chain, every subsequent patch has to be re-signed, in order, by the original signers. This is a big deal for most organizations, as people come and go all the time and key management becomes a nightmate.
BitKeeper was the premier DVCS system, until the point where a smart kernel hacker realized he could telnet into the database, run a few commands and get a full dump with history. BK were so irate that they pulled their Open Source licenses for kernel development, and Linus had to write git (but that’s another story all in itself).
Modern DVCS are fast and work offline as well as online. They are very efficient for storage, and make revisionist history obvious. It is easy in CVS and possible in SVN to go back and change files & history in an undetectable manner. Not at all with DVCSs, which store md5 hashes of every change, making it easy to detect reporsitory corruption and tampering.
The two main modern DVCSs are Git and Mercurial.
Lloyd – Cocotron
Cocotron is an open-source, liberally-licensed project to port Cocoa to Windows. It is similar in intent to GnuStep, but has two big advantages.
First, it runs natively on Windows. No need for a “Yellow Box” or a reboot.
Second, it does not use the
GPL LGPL license.
Cocotron started at about the same time as GNUStep, right after the publication of the OpenStep spec in 1994. It was not open-sourced until 2006, when it became possible to do so in part because of the Xcode developer tools.
Cocotron does not have native controls. Everything is custom-drawn.
Implementation is surprisingly efficient: Foundation relies on ~160 native OS calls, while AppKit has ~200 OS calls.
In graphic terms, CoreGraphics is a wrapper for the native drawing functionality. A project called Onyx 2D plans to implement the complete, native CoreGraphics suite in the near future.
You can build Cocotron using cross-compilation in Xcode. There are modified versions of binutils, for example -F / -framework options are added to ld, gcc and gdb are also modified. Xcode plugins are available.
Cocotron looks like a compiler to Xcode, accessible through build rules. It requires MinGW and the System headers/libs for the target system.
Remote debugging of the Windows executable is possible from gdb on the Mac, and should be possible with a VM though Christopher had no first-hand experience in this.
Lopp (aka Rands) – Talking shit, delegating and knowning what you want
When you do a presentation, have an arc, and three points.
For this presentation, the arc is that software development is a series of small decisions. There are of course large decisions, but these are more milestones than the small, day-to-day decisions that we continually make: “what will I name this variable? this class?” etc.
The milestones: Holy Shit, We could do this, We’re doing it, I’m screwed, We’re screwed, Glimmer of hope, Actual hope, Done.
Skills: talking shit (see Jerk City. Or don’t. Rands disavows any knowledge of this.)
You have to develop your comedy skills. It’s the art of improvisation. With time, this will become less about the funny and more about the “quickly parse everything you know and find the best answer.” Rands believes that all geeks are extremely good at this, even though they may not show it.
We are all control freaks. We like to detect the system to figure out its rules so that we can win. And winning is good. Only problem is we’re all very bad at something, which we may or may not be aware of. It may be graphic design. Maybe finance. Or managing a group of people to get them to do what you want. What do we do then?
The simple answer is to improve. We’re so bad at this skill that if we work at it, we can improve it and it will be better. And that’s often a good idea.
The better idea is to delegate: find someone who’s a rock star at that skill you suck so badly at. But to do that, you have to trust that others an help you. Which is difficult since you’re a control freak, remember?
Each decision is an opportunity to fuck up.
Knowing what you want.
This takes a shit ton of work. It goes from “Holy shit!” to knowing every. single. fact. ever. about something, and building your confidence about this subject. You may be a font nerd who cringes when he sees Arial, or a graphic design nerd, or a color nerd. But Knowing What You Want allows you to push all the decisions as early as possible
[Note: I'm not sure I agree that Big Design Up Front, which was touted by Rands, is the most appropriate method, but it is certain that the earlier you make the decisions, the better your product will be. Kind of like doing the riskiest things first.]
Using your new skills
This will help you make decisions in a crisis, and will give you leverage when negociation comes around. Because who wants to make compromises? Knowing what you want gives you measure, structure, direction.
Thomson – MacRuby
Objective-C is great, but it is not modern. It lacks several features of newer languages.
Code reuse could be much better. Single inheritance is often a barrier. For instance, the Singleton design pattern implies lots of boilerplate code. Who wants to write boilerplate code? Modern languages use either multiple inheritance (ugh!) or mixin classes.
Safety is limited. C is powerful at the price of safety. Raw pointers are often a major source of problems. Garbage collection means one less thing to worry about when writing the code you really care about.
Syntactic abstraction. Why is it necessary to declare an NSArray? Why aren’t hash tables part of the language? Things are getting better, slowly (e.g. foreach loops).
MacRuby is not a bridge to Cocoa. It is a first-class citizen in Cocoa, with complete access to all the frameworks. It is as fast, sometimes faster than Obj-C when dispatching methods. It has IB and debugging support.
When you use MacRuby, you get all the power and flexibility of a modern language. MacRuby boasts the first Ruby pre-compiler, which explains why it is so fast.
However, like all duck-typed languages, you sacrifice static type safety when you use MacRuby. That may be an issue for you, but years of Objective-C have shown that programs are fairly resilient to those dynamic issues.
Rhyne – Briefs
Briefs is a small application framework that allows you to create simple mockups for the iPhone, directly on the iPhone. It is also possible to create a fairly complex application that way. Perfect for elevator pitches. Check it out at http://giveabrief.com.
Aspeslagh – Full Time
Going indie full-time can be a lot of work. You have to automate your workflow as much as possible. Don’t manually authorize every sale, for instance.
When you build your store, assume you have more than one product. This will help tremendously when growing,
Have a support form, and (if possible) a support person. Get a virtual phone number.
Diversify your portfolio: people who buy one of your products are already predisposed to buying another one, especially if the experience was positive.
Bobtiki – Filming and photographing
Check out HowTube.com, and http://github.com/atebits/ for SimFinger, screencasting for the iPhone.
Speirs – One-man band
http://ecorner.stanford.edu is a great learning resource for things, even non-programming-related. Fraser learned all he knows about business and marketing from these free courses.
Czerniak – Security tools
CrashWrangler is a great tool from Apple to help you analyze crashes.
Dtrace for analysis. Good paper to read is Beauchamp & Weston.
PyDbg is a Python debugger.
Vazquez – App Categories
Apps on the iTunes store can be categorized in multiple ways. Here are three of them, along with the observation that you can charge a fair price for some of those apps without too much difficulty.
Quick Hit – Twitter, email
Immersive – games
Accessory – subordinate to main activity. For instance, a guitar tuner is subordinate to playing guitar.
You are marketing to a group of enthusiasts that care about quality. There is no race to the bottom for 0.99$: you can charge a good price if your application is well done and polished.
Example: people that pay 10,000$ for a saxophone will not mind paying 800$ for a case if it is the best, toughest, lightest case out there.
Correia – AppleScript Matters
Your application’s scripting interface matters, because there are a lot more scripters out there than you think. And they will think up ways of using your app that you never thought of.
Your scripting interface is your UI, for scripters. It does not have to be pretty, but it has to be consistent.
Especially with AppleScript. Learn AS and its idioms, and adopt them in your scripting interface. For example, don’t do “do new window” (one commanr) where “create new window” (verb, qualifier, noun) is the accepted idiom.
You should design your scripting interface along with your object model. Cocoa makes this easier than you think.
Benefits include connections with thousands of other apps out there, and Automator, the Scripts menu, etc.
Casgrain – Friction-free documentation
The Blank Page syndrome
“Where to start?” can be paralyzing. Coders’ “blank pages” usually have some scaffolding
Help reduces your Tech Support. Time spent on Tech Support is time not spent on developing your app. Having the user help herself is always faster than email. Writing Help will pay for itself many times over.
Tech Support staff can double as Technical Writers. Definitely worth it on a larger app, but not if you’re just getting started. Hiring someone leads to management/synchronization issues, so friction.
Keep It Simple
Help is just HTML, so you could hire a web designer for your css instead of making one yourself.
Help is just a localizable folder. Users expect to find Help in the Help menu (Spotlight-searchable). Do you like writing html? Go nuts! It’s essentially Safari in a top-window. Don’t overcomplicate things for now
It’s easy if you’ve never done it. Don’t worry about structure: all the html files could be in the same folder.
Resist the urge to write a pdf. It won’t be searchable, and in most cases will open in a separate app (Preview) unless you do something clever. Don’t do it, it’s a time sink and you will tend to sweat the details.
Writing Help should be Friction-Free
What tool do you currently use to capture text? Text Editor? Snippet editor? Wiki?
Avoiding the Blank Page
It should be easy to lay down new thoughts with your tool. No need to create a new document per page. Auto-save is great. You should have minimal structure: titles, lists, maybe bold / italics. Automatic linking between sections if you can get it. I use VoodooPad.
Integrating Help in your Dev Tasks
Think of Help as a Unit Test: document the feature, how it should work, then write the code for it. Don’t sweat the details just yet (no screen grabs!); it’s all “code” for now. Spell-check is your friend.
One page per feature is a good rule of thumb. Spell-check is invaluable, as this “code” is not compiled but interpreted by humans. IT IS NOT A FEATURE SPEC.
Just like code, you will throw some of it away, but less than you might think. Also why it’s important to avoid putting images in your documentation when you start: those can be expensive to re- create.
Integrate Help in Version Control
Sometimes simpler is better (we like to diff) Pure text, Markdown, HTML, XML, RTF, VoodooPad, OmniOutliner…
Help should be a first-class resource in your app, just like the app icon and MainMenu.xib. Make sure it lives where your resources live.
Integrate Help in your build using Shell script build phases. Automate, automate, automate… For instance, you could automatically convert Markdown to HTML.
On-line help is seductive
Just a couple of stub html files, and you’re ready to go (_target=“blank”, anyone?). You can change the content without updating the whole app
Don’t do it unless your app depends on being on-line, since Help becomes dissociated from your app (you broke your version control). Plus your server infrastructure must be kept alive. It’s a great way to procrastinate: “I’ll do it after I ship the app…”
Version Control is broken, unless you do something clever in which case you’re just procrastinating
Example: iChibi http://apps.casgrain.com/iChibi
Godwin-Jones – Opacity
Opacity is a Quartz-based, vector image editor that specializes in icons. It can save to a variety of formats using factories, most interestingly as NSView subclasses and HTML5
<canvas> objects for quick prototyping. Highly recommended.
Hess – Cocoa Boutique
Cocoa Boutique is an open-source, in-app purchase for your app. It uses Aquatic Prime for the licensing, and php/mysql/paypal for the back-end processing.
It has not been written because Wil Shipley is greedy (Golden-Braeburn). The Potion Store is also good but runs on Rails.
Mitchell – PyObjC
It is a scripting bridge from Python to Objective-C. You can import most Cocoa frameworks directly into python.
For developers, the language is faster / easier than Applescript.
You can debug it with pdb.
ipython gets you an interactive AppKit shell.
Morisson – Loading plugins in 64 bit applications
[I have no notes for this because I was too absorbed by the presentation.]
Wood – Marketing
The “Google Keyword Tool” helps you fine-tune your title and meta-data to rank better in Google. In general, limit your
Try to link yourself to your products (from a blog or your main page or something) using descriptive text, because Google indexes the link, as well as the text that generated the link. Don’t use “Click Here” as your hyperlink text.
Look for the Google Website Optimizer, it is full of good tools to help you make the most of your website by tracking where your users go and what helps them to buy your product.
Have an email list with an incentive to join (eg freebie app, more templates for your app). Send good content to that mailing list so your users stay subscribed. When the time comes to announce a new product, do it on the mailing list and your users will help you with your marketing, because most of the time you give them valuable content for free, so they don’t mind (and in fact appreciate) the occasional marketing message.
These users are very good: work to keep them. They are predisposed to liking your product, and maybe recommending it to friends. That kind of marketing cannot be bought, it has to be earned.
Gerbarg – Compiler engineering
So you found a bug, and you think the compiler is generating bad code. There are good news and bad news.
Bad news: gcc’s code is old and scary. It is very hard to go in there and find, much less fix issues. Few mortals can do this.
Good news: 90% of the issues are in the front-end parser, and Apple has just released (Open Source) a new tag-team: clang/llvm.
Clang is the static analyzer and llvm is a gcc front-end. clang is a compiler front-end, while llvm is a low-level virtual machine which can also generate native code. They are written in easy-to-read, easy-to-maintain C++.
You can subscribe and submit patches to the cfe-dev mailing list.
You can check out the code from svn for clang-llvm and build it with current tools: congratulations, you have built your own compiler!
Louis said he was not a compiler engineer, having worked on the front-end only, and he was able in a few hours to create a patch to llvm that allows pushing and popping a stack of pragma warnings. In those few hours he also submitted the patch, got it approved and committed to the clang-llvm source tree. His contribution should appear in the next release of Xcode.