Archive for March, 2011

Writing, n.

Thursday, March 24th, 2011

Over on Tumblr (where I have also started writing), Andy Matuschak and Christopher Bowns have challenged each other:

Long story short: Andy and I threw down our respective gloves after throwing back the third glass of whiskey, and came up with this: every Tuesday, we’ll spend 20 minutes of our respective shuttle rides to work writing something. It doesn’t matter what, but when those 20 minutes are up, you publish it.

After Christopher published that, Colin Barrett entered with this piece. Discussion ensued on Twitter, as it so often does, and it included this tweet from Christopher:

@cbarrett Perfect. I think “overthinking it” can cripple your writing, but it’s hard to let go of, because it’s so useful in engineering.

I responded there, but I’d now like to expand in a somewhat different direction here.

Writing programs is writing.

Consider this: If you write a program that no human can read, you have written it badly, and may have even written an outright bad program. Switch out “program” for “manuscript” and I hope you see my point.

Don’t confuse this with literate programming. That has you write a more-or-less human-only text, and then run a program such as WEB or CWEB to translate it to source code.

The problem with literate programming is the problem with all translation from one language to another, especially automatic translation: Error.

Just as translating a human-only text from one human language to another human language can produce a garbled mash, so can translating a program from one language to another produce a nonsense, or at least broken, program.

Hence the justified suspicion of programs that “upgrade” a program even just from one version of the same language to another: It isn’t the same language; not really. Similar, but not the same. Going from Python 2 to Python 3, for example, is not much different from going from 18th-century English to 21st-century English. Do these words mean the same thing? Maybe not. This is why such translators invariably come with warnings to check the hell out of the result.

No, I’m not talking about literate programming. I’m talking about regular programming, where you write the true text of the program, the text that the interpreter interprets or the compiler converts into machine code.*

Programming is a fusion of a couple of skills. It’s often called “software engineering”, but that’s only half of it. Writing is the other half. I define “writing” here as writing text into an editor, whatever the language, and “engineering” as designing a thing to be built. Things like OOP, unit testing, and design patterns are aspects of software engineering. Things like DRY, commenting practices, naming practices, and style rules are aspects of writing.

If you write a program well, you write it not only for the interpreter or compiler, but for any humans who will read the program after you, including yourself. It is a text like any other.

Writing a program is writing. Every rule, observation, and prescription you apply to writing for humans only, apply also to programming, and vice versa. If the rule does not work, chances are it was not a good rule to begin with.


Suggested reading


* This is, itself, a form of translation; the C standard even calls it such. That’s part of why compiler bugs are possible, and why compiler authors are extremely careful about their work, which is why compiler bugs are so rare.

The application delegate and the new singletons

Friday, March 18th, 2011

Here is a global variable:

Wizard *gWizard;

I’ll call this a zeroth-order global, on the premise that I need to talk to exactly zero objects (including classes) to gain access to this object.

Next, let’s look at a singleton:

[Wizard sharedWizard]; //hope he's not busy

I’ll call this a first-order global, as we need to ask the class for it (1 step) to gain access to it.

Now, here’s a second-order global:

MyAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];

(I use UIApplication here because I see this most frequently in Cocoa Touch code, but the pattern applies equally to Cocoa.)

And here’s a third-order global:

Wizard *wizard = [appDelegate wizard];

I need to (1) ask the UIApplication class for the application object, (2) ask that for its delegate, and (3) ask that for the wizard. (Assume here that wizard is a property, not a factory method that creates Wizards on the fly.)

None of these is any less global. If I can get to it from anywhere in the program without knowing about it directly, it is global.

Therefore, all the problems of globals apply:

  • What if two threads want to use the same Wizard?
  • What if the Wizard has a delegate of its own, and I have two objects that want to be its delegate?
  • What if the Wizard keeps internal state that may be corrupted by multiple objects trying to use it? (Nothing should have to worry about this outside of the Wizard itself.)

Your application’s objects form a graph. It should not be a complex one like this:

At the top, the application object. From it, its delegate. From it, your controller objects and a wizard. From each controller object, a path (colored in red) back to the delegate and then to the wizard.

Whenever you have paths bouncing around off of other objects like that, that’s a problem. The red arrows in the problem graph show where you violate the Law of Demeter.

Your object graph should, instead, be straightforward:

At the top, the application object. From it, its delegate. From it, your controller objects. From each one, a wizard.

Note that each of your controllers should own—or, if you prefer, hire—a Wizard all to itself. This eliminates contention between objects and reduces the likelihood of contention between threads (assuming each of the owning objects is supposed to only work on a single thread and not juggle multiple threads).

If contention is not a problem and you have a good reason why there should be only one Wizard, such as memory pressure or union regulations, then use a singleton. But use a real singleton, and only when necessary, and beware of singletons in disguise.

The new and improved Cocoa links card

Tuesday, March 15th, 2011

I’ve previously mentioned that I made a business card full of useful Cocoa and Cocoa Touch links to give to new Cocoa and Cocoa Touch programmers at events such as CocoaHeads.

Today, I have updated it and given it a web page. 1-up and 10-up (US Letter) PDFs are available there, as well as the full list of unshortened links.

I encourage you to print out the 10-up onto perforated business card paper, or have it professionally printed (keeping in mind that you probably won’t need 1000 of them), and make the cards available to novice Cocoa and Cocoa Touch programmers at the CocoaHeads or NSCoderNight events you attend. Just please be sure to print both sides, since my credit link is on the back.

Mentoring

Tuesday, March 8th, 2011

I originally wrote this for the Adium development list, in a discussion of the upcoming Google Summer of Code, for the benefit of those of our developers who have never mentored students in GSoC before and may be considering doing so. Read this in that context; for example, “our” means “the Adium project’s”.


  • Work with students from the very beginning on the quality of their [application] submissions. 90% of the submissions will be crap. Look past this. See what lies within. If it can be improved, try to get them to improve it. Those who do will be good students.

  • Spur your student to work on code. Make sure they’re committing at a regular and satisfactory rate.

  • Ensure your student actually writes code and doesn’t just crib together tutorials and/or Stack Overflow answers and/or ask you to provide code* for various tasks they need to accomplish. Wildly varying coding styles, inconsistent variable and method naming, and poor indentation are warning signs.

  • Communicate constantly. This includes the aforementioned spurring your student to work as well as being available to answer any questions they have about where things are in our code base, what they need to do to achieve certain goals or specific sub-tasks, etc. These questions are virtuous; you should encourage them, just short of demanding them. The student is not that only in name; they are here both to write code and to learn.

  • Find a medium that works for both of you. For me, email (or Twitter, nowadays) would be best. Maybe you prefer IM, or even voice chat/phone (if it isn’t too expensive). Don’t try to force your habits on the student; if you love the phone but they hate it (or vice versa), a happy medium will work better.

  • Be sure they understand and use Mercurial and good VCS practices generally. Frequent, discrete commits; neither waiting “until it’s done” to commit (it should compile) nor committing half-done work periodically (e.g., daily) nor committing amalgams of unrelated work (they should commit specific sections that comprise a single change).

  • Nowadays, I recommend that you have them fork our Bitbucket repo and push to their fork.

  • Review their code constantly. Subscribe to the commits list (or their fork’s commits feed) and review everything they write.

  • Read their commit messages, not just their code. Lists are a warning sign (unrelated changes lumped together). Inadequately describing the change is also a problem. Work the student out of these habits as soon as possible.

  • Don’t wait until mid-term exams to sit your student down for a serious talk about their work or lack thereof. If they’re committing garbage, set them straight as soon as possible—do not wait. If they don’t commit, get them writing and committing as soon as possible.

  • Always be ready to fail your student. Be compassionate, understanding of life’s realities; they’re not a slave. But they are here to work, and if they don’t do the job or if they do a bad job, be ready to fail them.

  • Make sure they know where they stand. If there’s 1–2 weeks before exams and they’re still in danger of failing, make sure they know what’ll happen if they don’t shape up.

I can’t claim to have been perfect in all of these points in my own mentoring (many of these I learned by not doing them), but it’s what I’ve found works.

There might also be something on the GSoC sites about this. Some viewpoints vary, particularly along the leniency-to-hardassness spectrum.

If you are not willing to do all of this, or don’t think you’ll have the time, you should not mentor a student.

* Six words that should worry every mentor or other help-offerer: “Can you show me a sample?”

Apple documentation search that works

Sunday, March 6th, 2011

You’ve probably tried searching Apple’s developer documentation like this:

The filter field on the ADC documentation library navigation page.

Edit: That’s the filter field, which is not what this post is about. The filter sucks. This isn’t just an easy way to use the filter field; it’s an entirely different solution. Read on.

You’ve probably been searching it like this:

Google.

(And yes, I know about site:developer.apple.com. That often isn’t much better than without it. Again, read on.)

There is a better way.

Better than that: A best way.

Setup

First, you must use Google Chrome or OmniWeb.

Go to your list of custom searches. In Chrome, open the Preferences and click on Manage:

Screenshot with arrow pointing to the Manage button.

In OmniWeb, open the Preferences and click on Shortcuts:

Screenshot of OmniWeb's Shortcuts pane.

Then add one or both of these searches:

For the Mac

Chrome OmniWeb
Name ADC Mac OS X Library
Keyword adcmac adcmac@
URL http://developer.apple.com/library/mac/search/?q=%s http://developer.apple.com/library/mac/search/?q=%@

For iOS

Chrome OmniWeb
Name ADC iOS Library
Keyword adcios adcios@
URL http://developer.apple.com/library/ios/search/?q=%s http://developer.apple.com/library/ios/search/?q=%@

Result

Notice how the results page gives you both guides and references at once, even giving specific-chapter links when relevant. You even get relevant technotes and Q&As. No wild goose chases, no PDF mines, no third-party old backup copies, no having to scroll past six hits of mailing-list threads and Stack Overflow questions. You get the docs, the right docs, and nothing but the docs.

For this specific purpose, you now have something better than Google.