Steve Yegge describes what’s wrong with Lisp

Steve Yegge, Lisp is Not an Acceptable Lisp:

You’ve all read about the Road to Lisp. I was on it for a little over a year. It’s a great road, very enlightening, blah blah blah, but what they fail to mention is that Lisp isn’t the at the end of it. Lisp is just the last semi-civilized outpost you hit before it turns into a dirt road, one that leads into the godawful swamp most of us spend our programming careers slugging around in. I guarantee you there isn’t one single Lisp programmer out there who uses exclusively Lisp. Instead we spend our time hacking around its inadequacies, often in other languages.

Steve does a very good job of articulating a lot of the things I dislike about Lisp, especially Common Lisp. One interesting thing, though, is that a lot (but not all) of the issues he raises are addressed by Dylan.

One of the more interesting things about Dylan in this context is that, despite not adopting a traditional message-based object system like Smalltalk or Objective-C (or their more static cousins C++ and Java), Dylan does push objects all the way down, but in a functional style. It appears to work pretty well, making it easy to define both nouns and verbs in the combinations a developer might need, and even (through its hygienic macro system) allow developers to extend language syntax too.

“Enterprise” thought leadership?

David Heinemeier Hansson, creator of Rails at 37signals, takes James McGovern — some Java/J2EE author — to task for his über-lame rant against Ruby in the Enterprise in a great post titled Boy, is James McGovern enterprise or what!

> So by Enterprise, Architect, and Enterprise Architect standards, this gent must be the top of the pop. Thus, allow me to make this perfectly clear: I would be as happy as a clam never to write a single line of software that guys like James McGovern found worthy of The Enterprise.

> If Ruby, Rails, and the rest of the dynamic gang we’re lumped together to represent, is not now, nor ever, McGovern Enterprise Readyâ„¢, I say hallelujah! Heck, I’ll repeat that in slow motion just to underscore my excitement: HAL-LE-LU-JAH!

> With that out of the way, we’re faced with a more serious problem. How do we fork the word enterprise? The capitalized version has obviously been hijacked by McGovern and his like-minded to mean something that is synonymous with hurt and pain and torment.

Indeed, McGovern’s rant reads more like a parody of a rant than the real thing:

> 13\. Lets say there is a sixteen week project and the productivity stuff was true and Ruby could save me an entire three weeks which would be significant. Since Ruby is a new vendor and not represented by existing vendors I already do business with, do you think that I will spend more than three weeks in just negotiating the contract?

Yes, because there is some vendor out there named “Ruby that you need to sign a contract with before you can begin a project.

Despite his claims to be agile, McGovern obviously doesn’t know the first thing about agile development. People come first, sure, but agile development doesn’t say that tools aren’t important. Not using good tools makes it harder for good people to do good work.

That’s why I love developing software for Mac OS X and why I love helping people develop software on Mac OS X: We have great tools like Cocoa, Core Data, Interface Builder, OCUnit, WebObjects, and Xcode, and these can be used by great developers to do great things.

Making Better Games with Test-Driven Development

Noel Llopis (Games from Within) and Sean Houghton, Backwards Is Forward: Making Better Games with Test-Driven Development:

> One of the questions we had when we jumped into TDD is
> whether it was going to hold for high-level code. We had
> seen in practice from previous projects that we can
> certainly do TDD to create low-level and intermediate-level
> libraries (math, collision, messaging, etc). But would it
> really work for high-level code that would build on
> low-level code?
>
> The answer is an unconditional yes. We have developed a
> full codebase doing TDD from the start, and we had no
> difficulty writing high-level code with TDD. Things like
> character state machines, game flow, or specific game
> entities were done through TDD without any problems, and
> greatly benefited from the TDD approach.

Noel’s blog is great, and this paper is being presented at the 2006 Game Developers Conference.

Noel and High Moon Studios have been a lot of pioneering work using Extreme Programming in the game development space. Game development can definitely make good use of Extreme Programming to manage the development process, dramatically improve the quality of code, and do wonders for scheduling accuracy and schedule predictability.

Extreme Programming in game development also presents special challenges due to the exploratory nature of a lot of the work, as well as the highly-interactive nature of the software itself. As Noel points out, you wind up writing much more finely-factored code when doing TDD, which will be alien to a lot of game developers but will help greatly with maintenance, debugging, and the ever-more-important portability. (Not just between Windows and Mac OS X, but also between Xbox and PlayStation 2 and Nintendo GameCube and Xbox 360 and PlayStation 3 and Nintendo Revolution…)

Cooperative User Threads vs. Preemptive Kernel Threads

James Robertson, Cooperative Threading:

> Well, in Cincom Smalltalk, this model gives you predictability –
> you know exactly what a thread is going to do. The issue with runaway
> threads rarely comes up for a simple reason – most processes end up
> pausing for I/O (user input, db access, file access, sockets –
> what have you). That wait for I/O state is what prevents a problem
> from arising.

This is a classic problem and I’m honestly surprised to find out that Cincom Smalltalk implements cooperative user-level threads rather than supporting preemptive kernel threads.

Here’s what I posted in response to James, unattributed thanks to the torturous comment interface on his blog:

> One issue with cooperative threads relative to preemptive
> OS-supplied threads is that you get far less opportunity
> for true concurrency within an application. In an era when
> multi-core processors are becoming significantly more common,
> this is becoming exceptionally important to application
> developers. It’s not just about doing I/O concurrently with
> other operations or allowing an application to perform
> multiple tasks at once; it’s about allowing a task to be
> completed faster because more efficient use is being made
> of machine resources. This is why I take an extremely
> skeptical view of user-level threading packages, especially
> in software built on platforms that have reasonable
> kernel-level threading.

You’ll note that the various threading APIs in Mac OS X are all built on kernel threads.

Furthermore, the Mach microkernel schedules exclusively in terms of threads. The microkernel doesn’t even have a conception of processes! It only knows about collections of resources — *tasks* — such as address spaces and IPC ports, and flows of control — *threads* — that it can schedule on processors.

Xcode: Working With Xcode Build Settings

The Apple Developer Connection just posted Working with Xcode Build Settings. It builds on Understanding Xcode Projects:

There is a lot of flexibility in the Xcode build system for customization, so you can choose to keep your settings simple or make them as complex as you like. But for most purposes, a basic understanding of how build settings and build configurations work will make this topic easy to master—once you have these concepts clear, you can choose the settings that work best for you.

If you’re developing Mac OS X software with Xcode, read Understanding Xcode Projects and Apple Developer Connection posted Working with Xcode Build Settings

Xcode: Understanding Xcode Projects

Anyone interested in Mac OS X development should check out the latest Xcode article on the Apple Developer Connection, Understanding Xcode Projects:

To become truly proficient with Xcode, whether you’ve been using it for a while or are just starting to make the transition, an understanding of the Xcode user interface and how it is used to organize a software project is required. This understanding will take you a long way towards understanding the philosophy behind Xcode and how it works, and will help to make it work better for you.

In short, the article introduces what we call the Xcode project model, which defines how Xcode projects are organized, how Xcode generates products from targets, and how projects and targets relate to one another.

It doesn’t cover the details of the build settings that are used by targets or how they’re collected in target and project configurations. Both topics are covered in depth in the Xcode User Guide. I also wrote about configurations when they were introduced in Xcode 2.1 as a replacement for build styles.

Update: The article Working with Xcode Build Settings was recently posted covering configurations and build settings.

Xcode: Debugging Cocoa application unit tests

A couple weeks ago as part of my Unit Testing Series I talked about how to use Xcode to write unit tests for Cocoa frameworks, debug unit tests in Cocoa frameworks, and write unit tests for Cocoa applications. However, I haven’t yet described how to debug your unit tests in Objective-C Cocoa applications. I’ll take care of that tonight.

After you’ve set up unit testing in your Cocoa application, debugging your unit tests is similar to debugging them in a Cocoa framework. All you have to do is adjust the arguments and environment variables your application’s Executable is configured to use in Xcode. You don’t even have to create a new executable.

To start, bring up the Info window for your application’s executable (which is its entry in Xcode’s Executable smart group). In the Arguments tab, add the argument -SenTest All. This tells the unit testing infrastructure that you want to run all of the unit tests, not just the ones that are built in to the executable. (After all, you don’t have any unit tests in your executable itself.)

Now we’ll need to engage in a little bit of environment variable magic. When you test an application, what you’re really doing is injecting your unit test bundle into the application and telling it to run its tests at its first opportunity. This is accomplished through by telling dyld to insert a private framework, DevToolsBundleInjection.framework, into your application on launch, and telling that framework via an environment variable, XCInjectBundle, the path of the test bundle to inject.

You also have to tell the injection framework itself the full path to the application executable you want to inject the bundle into, via the XCInjectBundleInto environment variable. This is needed to avoid injecting your test bundle into other executables that are run by the application you’re testing, or that are run as a side-effect of running the application you’re testing. (For example, gdb generally wants to run applications from within a shell, so that environment variables are expanded in its environment and command-line parameters.)

In the Arguments tab of your application executable, first add an environment variable named DYLD_INSERT_LIBRARIES. Set its value to the path to the DevToolsBundleInjection.framework/DevToolsBundleInjection library in the framework of the same name that’s included in the developer tools. Prior to Xcode 2.5, this was in $(SYSTEM_LIBRARY_DIR)/PrivateFrameworks but as of Xcode 2.5 and Xcode 3.0, it has been moved to $(DEVELOPER_LIBRARY_DIR)/PrivateFrameworks

Then add a second environment variable, XCInjectBundle. Set its value to $(BUILT_PRODUCTS_DIR)/MyTestBundle.octest.

Add a third environment variable, XCInjectBundleInto. Set its value to the full path to your application’s executable — not just the application bundle — e.g. $(BUILT_PRODUCTS_DIR)/MyApplication.app/Contents/MacOS/MyApplication. This is the debugging equivalent of the Test Host build setting you used to tell Xcode what executable to inject your tests into when running them.

For Xcode 3.0 and later, add a final environment variable, DYLD_FALLBACK_FRAMEWORK_PATH to your executable. Set its value to $(DEVELOPER_LIBRARY_DIR)/Frameworks.

Why do you need to do this? In order to support moving and renaming the Developer folder, all of the frameworks within it — including OCUnit — use runpath search paths. This means that the internal name of the framework, including the one copied into your test bundle, will start with @rpath rather than an absolute path starting with /Developer/Library/Frameworks. Unfortunately this means that your unit tests won’t find SenTestingKit.framework without some extra help. That’s what DYLD_FALLBACK_FRAMEWORK_PATH does: It tells dyld to try an additional set of directories in place of @rpath when it can’t be resolved. (More information on runpath-relative install names can be found in the ld(1) man page.)

Make sure the check marks next to all three of these environment variables — and your -SenTest All argument, of course — are set.

Troubleshooting note: Troubleshooting note: If this doesn’t work — that is, if your test bundle isn’t found and run — change the executable’s working directory (in the General tab) to Built Products Directory and remove $(BUILT_PRODUCTS_DIR) above. Generally this is caused by $(BUILT_PRODUCTS_DIR) not being expanded to a full path, but rather to a partial path relative to your project directory.

Now if you choose Run Executable from the Debug menu, your application should launch, you should see the results of executing your unit tests in the Run Log, and as soon as your unit tests are complete your application should quit!

To debug a failing test, build your tests and set a breakpoint on the line where the failure occurs. Now choose Debug Executable from the Debug menu. As with a Cocoa framework, do not choose Build and Debug from the Build menu. You need to use Debug Executable because your build will fail due to the failing test. Debug Executable will work as long as your executable itself is actually present.

Having done all this, you should be stopped at the breakpoint!

Just as any other time you use OCUnit, instead of -SenTest All you can specify -SenTest MyTestCaseClassName to run just the tests in the test case class MyTestCaseClassName, or -SenTest MyTestCaseClassName/testMethodName to run just a single test.

Update July 7, 2007: Added the troubleshooting note about removing $(BUILT_PRODUCTS_DIR) if you get errors about not being able to load the bundle.

Update March 17, 2008: I’ve updated this a bit to handle some changes in the process introduced with Xcode 3.0.

Update September 5, 2008: I’ve updated this again to cover the changes that were made to bundle injection for Xcode 3.1; the change is the introduction of the XCInjectBundleInto environment variable.

Xcode: Unit Testing Cocoa Applications

Yesterday, I talked about how to add unit tests to Cocoa frameworks using Xcode. There’s only a little more set-up required to add tests to Objective-C Cocoa applications.

First, turn off ZeroLink for the application target you want to test. Just as with a framework, your unit tests will be built as a test bundle containing only the tests, completely separate from the code being tested. The test bundle will access the code in your application by linking against it, and you can’t link against something built with ZeroLink. Note: You only need to do this for Xcode 2.1 through Xcode 2.5. Xcode 3.0 removed support for ZeroLink, since the linker is now sufficiently fast as to obviate it.

Next, add a new Cocoa Unit Test Bundle target to your application project. This is the target that will actually contain your tests. When you add the test bundle target, Xcode shows its Info window. In the General tab of this window, press the + button and choose your application target from the sheet that appears. This will make your test bundle target depend on your application target, so you can just build your test bundle all the time and have your application automatically rebuild first.

Now you actually need to make your test bundle link against your application. You do this using the Bundle Loader property under Linker Options in your test bundle target’s configurations. You need to set the value of this option to the path of your application executable and not just its wrapper: $(BUILT_PRODUCTS_DIR)/MyApplication.app/Contents/MacOS/MyApplication. The $(BUILT_PRODUCTS_DIR) variable is expanded at build time to be the path to the build products for the currently-selected configuration, which lets you avoid using an absolute path.

The final step is to tell the unit testing infrastructure how to run your tests. For a framework, the dynamic loader does the heavy lifting; when the test rig loads your test bundle, the loader will automatically load the frameworks it depends on including the one you’re testing. However, for an application to be tested the application must be launched and the test bundle injected into it. You can specify that this should happen using the Test Host property under Unit Testing in your test bundle target’s configurations. Just as with the Bundle Loader property, you need to set the value to the full path of your application executable. Since you’ve already done that once, you can just re-use the value of the Bundle Loader setting by specifying $(BUNDLE_LOADER) — this is the underlying variable that the property is associated with.

Now just like with frameworks you can add test cases to your test bundle just by adding new files based on the Cocoa Objective-C test case class template. Your application code can remain in your application target and your unit testing code can remain in your test bundle target. Whenever you build your test bundle target, once everything is built your application will launch, its tests will be run, and it will quit — and the test results will be reported via the Build Results window just like compiler and linker errors.

Xcode: Debugging Cocoa framework unit tests

So you’ve set up unit testing for your Objective-C Cocoa framework and it’s been working great. But now you’ve written a test and it fails, and you can’t figure out why. It’s time to break out the debugger, but how, exactly, do you do that? Your unit tests are built as a bundle, and you can’t run a bundle.

It’s simple. All you have to do is set up an appropriate Executable in Xcode to run the test rig that runs your bundle, and then debug that. To get started, choose the Project > New Custom Executable menu item. For its name, specify otest — this is the name of the test rig used by OCUnit. Specify /Developer/Tools/otest as the path to your tool.

When you add the custom executable, Xcode will bring up its info window. Switch to the Arguments tab. Here you’ll need to enter some command-line arguments to pass to the test rig and some environment variables to affect how it’s run.

First, add the argument -SenTest Self to your executable. This tells otest to run all of the tests in your bundle. (It’s actually a pair of arguments, but you can add it as one as a convenience.) Then for your second argument specify $(BUILT_PRODUCTS_DIR)/MyTestBundle.octest where MyTestBundle is the name of your test bundle. This tells otest the path of the test bundle to load; $(BUILT_PRODUCTS_DIR) will be expanded to the appropriate build products directory for your project at run time. (If you get the order wrong, just drag the arguments around in the table.)

Troubleshooting note: If this doesn’t work — that is, if otest complains it can’t find your test bundle — change the executable’s working directory (in the General tab) to Built Products Directory and remove $(BUILT_PRODUCTS_DIR) above. Generally this is caused by $(BUILT_PRODUCTS_DIR) not being expanded to a full path, but rather to a partial path relative to your project directory.

Next add a pair of environment variables named DYLD_FRAMEWORK_PATH and DYLD_LIBRARY_PATH to your executable. These will tell the loader to check your build products directory first for frameworks and libraries whenever the executable is run from within Xcode. Specify $(BUILT_PRODUCTS_DIR) for the value of each variable.

Finally, from the Project > Set Active Executable menu choose your new otest executable. This way any time you run or debug within Xcode, it will run otest with the arguments and environment you’ve specified.

To actually debug a failing test, build your tests and set a breakpoint on the line where the failure occurs. Now choose Debug Executable from the Debug menu. Do not choose Build and Debug from the Build menu. You need to use Debug Executable because your build will fail due to the failing test; Debug Executable doesn’t try to build first, it only cares whether an executable is present.

You should successfully stop at your breakpoint!

If your tests take a long time to run — they shouldn’t, they’re unit tests after all, but it can still happen — you may want to just run the tests for one test case, or just one individual test. This is easy too. Rather than specifying -SenTest Self in your arguments to otest, you can specify -SenTest MyTestCaseClassName to run the all the tests in the specified test case. To run just a single test, use -SenTest MyTestCaseClassName/testMethodName instead.

Update July 7, 2007: Added the troubleshooting note about removing $(BUILT_PRODUCTS_DIR) if you get errors about not being able to load the bundle.

Xcode: Unit Testing Cocoa frameworks

It’s straightforward to write unit tests for Objective-C Cocoa frameworks with Xcode 2.1 and later.

First, turn off ZeroLink when building your framework. ZeroLink is a great technology, but you can’t link against something that’s built with ZeroLink, and that’s exactly what your unit tests are going to do. Note: You only need to do this for Xcode 2.1 through Xcode 2.5. Xcode 3.0 removed support for ZeroLink, since the linker is now sufficiently fast as to obviate it.

Next, add a new Cocoa Unit Test Bundle target to your framework project. This is the target that will actually contain your tests.

When you add the new test bundle target Xcode should bring up its Info window. Switch to its General tab and press the + button in the lower-left to add a new dependency. In the resulting sheet, choose your framework target. This tells the build system that your framework target needs to be built before your test bundle target.

Now that you’ve declared the dependency between the targets, you need to make sure your test bundle actually links against your framework. Make your test bundle target the active target by choosing it from the Project > Set Active Target submenu. Then highlight the Products group in the Groups & Files view at the left of the Xcode project window. In the detail view to the right, you’ll see all of the products that are built by the various targets in your project; one of the rows will be for your framework. Click the checkbox at the very right of its row, in the Target Membership column, to make your test bundle link against your framework.

Now you can add test cases to your test bundle by just adding new files based on the Cocoa Objective-C test case class template. You don’t need to add any of your framework code to your test bundle, and you don’t need to add any testing code to your framework. And you’re not restricted to using only header files with public visibility in tests, either; you should be able to use anything from your framework target, so long as it’s exported at link time.