Nu Substance and Style

I was recently asked for an Objective-C to Nu conversion guide. That’s a good idea, and although it’s not yet written, I have a few example conversions online that may be helpful. One big one is NuPagePacker, my Nu port of Aaron Hillegass’ open-source PagePacker program. I’ve also posted the git repository for NuAnimatingViews, a port of the AnimatingViews example in the Leopard Developer Tools. That example uses CoreAnimation and required some improvements to Nu that aren’t in any existing release. To run it, you’ll need to either build your Nu from my git repository or wait for the next release of Nu.

After looking back over my code and the glimpses I’ve gotten of other people’s Nu code, here are some thoughts on the substance and style of programming in Nu:

Substance

Pointers to instances of Objective-C classes should always be declared of type (id).

For enumerated types, use (int).

Arguments that pass Objective-C class instances by reference should be declared of type (id *). On the Nu side, they are instances of the NuReference class.

Methods declared as (IBAction) in Objective-C should be declared to return (void) in Nu.

IBOutlets are just instance variables. Declare them in Nu with the ivar operator. Their type should be (id).

Don’t put @ in front of your Nu strings.

Don’t call retain and release; Nu automatically retains objects when they are assigned to values and releases when new values are assigned or the associated contexts are released.

Use the new import macro (in the git repository only) to read function and constant definitions from the Leopard BridgeSupport files. (import Cocoa) loads all of the definitions for Cocoa.

Watch that your class +initialize methods are getting called. For pure-Nu class implementations, you will need to call them yourself. Put the call in your application delegate’s applicationDidFinishLaunching: method.

Make sure that your methods have the correct type signature. If you don’t specify a signature (by leaving off the type specifiers), Nu will first try to look up the method in the runtime. If it finds it, the signature of that method will be used. If not, the return value and all arguments are assumed to be of type (id). To check the signature of a method, examine:

((MyClass instanceMethodWithName:"methodWithArg1:arg2:") signature)

Also, currently type signatures are all-or-nothing. If you declare a method with partial type information, the method declaration will fail. So either specify types for a method’s return value and all its arguments, or omit them all and use the default.

Refer to selectors by name: use "myMethod:" instead of @selector(myMethod:).

Style

Code formatting is a menial task, and menial tasks are for machines (and Pythonistas). Use nubile to format your code. The easiest way to do that is to use TextMate. If you can’t use nubile, use emacs.

Don’t leave parentheses dangling on separate lines. Unless someone beats me to it, someday I’m going to enhance nubile to automatically pull up dangling closing parentheses.

Symbols that end with a colon (’:’) are called labels. The Nu parser recognizes the colon as the end of a symbol, so you don’t need a space between a label and the value that follows it. Leave it out; that makes the association more clear. I’m considering also enforcing this with nubile.

Use the other Nu tools: nuke, nutest, and nudoc. I’ve learned a lot about my code from using each of them.

Anything else?

I’ll come back and add more to this list as I think of it. If you have suggestions or questions, email me or post a comment below.

4 comments ↓

#1Grayson on 2007-12-20 at 12:58:28 America/Los_Angeles

So far, I’ve been in the habit of leaving a trailing ending parenthesis after a long block as a visual reference that the block ended there. Is there an official Nu style guide? Do you (officially) recommend indention rules to make code blocks more defined instead?

#2Patrick Thomson on 2007-12-20 at 14:20:47 America/Los_Angeles

“Code formatting is a menial task, and menial tasks are for machines (and Pythonistas).”

EPIC BURN!

Seriously, though, very good suggestions. For my part, (Foo new) should ALWAYS be used in place of ((Foo alloc) init).

#3Tim on 2007-12-20 at 14:27:39 America/Los_Angeles

So far, this is the only thing that I’ve written on coding style. The starting point is established Lisp convention, which is to use an editor that automatically indents your code (thus defining the indentation conventions) and to not leave dangling parens (because the editor can balance them for you).

#4Tim on 2007-12-20 at 14:52:35 America/Los_Angeles

Patrick—yeah, loosely quoting Jason Hoffman (speaking at a Ruby conference), “If you’re the kind of person who likes to spend a lot of time adjusting the whitespace in your code, Python is your language.”

I’m not totally sold on the use of “new”. I like its conciseness, but the alloc/init pairing is deeply ingrained and often the “init” is “initWithSomething:...” But it’s tempting to build all these rules directly into nubile so there’s no ambiguity. An automatic transformation of ((Foo alloc) init) into (Foo new) (or vice versa) would be easy to include.

Leave a Comment (sign in with Twitter)