namespace constants in C

Saw this on mikeash’s Twitter. Namespace constants in C.

#import <Foundation/Foundation.h>

// .h file
struct MyConstantsStruct
{
    NSString *foo;
    NSString *bar;
    int baz;
};

extern const struct MyConstantsStruct MyConstants;

// .m file
const struct MyConstantsStruct MyConstants = {
    .foo = @"foo",
    .bar = @"bar",
    .baz = 42
};

// user
int main(int argc, char **argv)
{
    [NSAutoreleasePool new];
    
    NSLog(@"%@ %@ %d", MyConstants.foo, MyConstants.bar, MyConstants.baz);
}

So obvious once you see it… why did it take us this long to think about it? 🙂

Hacking vs. Programming

The hackers get a lot of attention these days. These are the basketball players who make the slam dunk that makes it to the highlight reel. But basketball games are won by teams of players executing on the basics – the solid play well executed, the dribble, the layup, the pass that gets the ball to the star. In the long run we need more real programmers to make solid, dependable programs that don’t have be be rewritten from scratch when a change is needed.

Full story.

My kingdom for a project where we can program, not hack.

on Prototyping

We prototype so we may fail and learn from our mistakes. There is little point prototyping if you have no time/budget to iterate.

Andy Budd, Twitter post.

He’s right, and it points out why prototyping is important — because we’re going to make mistakes. It’s rare that the first draft of anything is perfect: you will do things wrong, you will make mistakes, you may not fully understand the problem and may actually come to understand it better due to that first pass.

It’s also true that if you don’t have time or budget to do more than one pass, you can’t prototype because your first draft will be what you deliver.

What’s not directly stated in this is that if you can’t prototype, if you’re unwilling to budget the time and money and resources to prototype, then what’s the point? That is, unless you’re willing to accept shipping something half-assed. Unfortunately so much of the computer software world is willing to do so, and that explains the sorry state of software today. *sigh*

It’s rare to find a company that gets it and is willing to invest what it takes to get there. That means many iterations, code review, and a willingness to not ship until it’s ready.

Do you know Visual Basic and Measurement Studio (or know someone who does)?

Do you know Visual Basic and/or Measurement Studio? Or if you don’t do you know someone who does?

There’s a group that needs some work done utilizing those tools, and I’m trying to help them find someone. If you know your way around there, drop me a line and I can fill you in on the details.

Thanx.

Cocoa Singletons

A few days ago I saw Mike Ash retweeted this:

“a lot of misinformation about singletons out there” Yeah, mainly from Apple and folks who followed their samples

– @schwa (Jonathan Wight)

Fair enough. I know that Apple’s Singleton discussion has taken a lot of heat. For one such criticism, see here. Now, figuring that Mike Ash retweeted that, plus since Mike does a lot of great Q&A stuff in his blog, here’s what Mike has to say about Singletons. Note however that Mike actually talks about it from a different angle.

Nevertheless, Apple seems to have listened to the criticism and has improved their Singleton implementation. Personally I’m fine with this. Yes I understand all the criticisms, but it’s like most tools out there: there’s a time, there’s a place. Understand things and work to get a job done as best you can at the time given what you know about your context and needs.

Yes, this is some old news… just that the recent retweet made me want to talk about it. I do wonder what exactly was going on that caused the original tweet. Something at WWDC?

svn hosting

I’m embarking on a little skunkworks project with someone. We need some sort of project hosting so we can share source code. My first thought was to things like Google Code’s project hosting, but that and many others require the project to be public and open source, or at least, must be public and open source if you want free hosting. Again, this is a skunkworks gig so, we need it to be private and we have no funding so free is the only thing we can do.

Within a couple hits in Google, I found this excellent website: Subversion Hosting Comparison. The last update was months ago, but it still seemed relevant enough. A few clicks to configure my requirements and I settled upon Assembla.

How nice!

Good source management

Troy Hunt writes on The 10 commandments of good source control management. They are:

  1. Stop right now if you’re using VSS – just stop it!
  2. If it’s not in source control, it doesn’t exist
  3. Commit early, commit often and don’t spare the horses
  4. Always inspect your changes before committing
  5. Remember the axe-murderer when writing commit messages
  6. You must commit your own changes – you can’t delegate it
  7. Versioning your database isn’t optional
  8. Compilation output does not belong in source control
  9. Nobody else cares about your personal user settings
  10. Dependencies need a home too

Read Troy’s article for all the details. I’d like to elaborate on a few.

VSS – stop using it. Totally. “Back in the day” I worked at Metrowerks and they made the Mac version of Visual SourceSafe… or as it was jokingly called, SourceSuck. There were a lot of cool things about it, and sometimes I still think the ability to lock can be useful. But the main repository was constantly down, constantly being rebuilt. It was terrible. Thankfully tools have progressed since then. Subversion is great. I haven’t had the opportunity to try git yet, but that it’s maturing is a good sign.

Commit early and often. Very true. It always gives you a rollback point. A lot of people are afraid of this for whatever reason, especially fearing the merge. Understandable, but it’s just part of life and certainly using version control will help ease the pain — if you use it right. So put your work into a branch, every so often merge in changes from the trunk to keep you building and current, but still doing your thing. When it’s time for you to go back into the trunk, the merge won’t be so painful. If you must reconcile, you must. It happens, but it’s not the end of the world. Maintain that history, give yourself the protection that version control is for.

Going with this, #10. Over time I’ve changed how I lay out my Subversion repository. The basic recommended layout is:

/trunk
/branches
/tags

and while that’s a good start, I expanded upon it:

/branches
/sandbox
/tags
    /builds
    /candidates
    /development
    /releases
/trunk
/vendor
    /archives
    /src

Branches hold branches, labeled in a manner that describes what the branch is about. There’s no need to get too formal about the branch name, so long as it along with the commit message adequately describe what’s going on. Sandbox provides a place to play, perhaps you wanted to write a little testbed application that is relevant to the project, this is where to put it. Why put it into the repository? See #2, along with just all the good reasons for versioning source. Tags is broken down into a little more organization. Development tags are tags defined to ease development, like you’re about to make some big change and want to demarcate a clear rollback point. Build tags are tags made during your build cycle, perhaps by the automated build server, to of course denote a particular build. Candidate tags are tags to say “this is a release candidate”, and these tags are made from a build tag (e.g. “svn copy tags/builds/1.0.0.005 tags/candidates/1.0.0FC1”). Release tags then are the actual public releases, made from the candidate tags (e.g. “svn copy tags/candidates/1.0.0FC2 tags/releases/1.0.0”). This hierarchy of tagging allows a tracking of history. Trunk of course is the main development trunk. The vendor area is for any sort of third party product that is relevant to go in. I like to put the archive, as downloaded, into the vendor/archives/ area (e.g. the .gz or .zip or .dmg or whatever), so the archive as received is maintained. Into vendor/src I then like to put the expanded/opened distribution, but with minor modifications. For instance, they didn’t make a clean distribution and included .svn folders, or build products or other things that are irrelevant or dirty things up, or renaming the top-level folder to something more descriptive (e.g. from “distro” to “boost-1.46.1”) ; it should be as close to the original distribution as possible, just cleaned up. From there, the /vendor/src/whatever/ is svn copied into the /trunk. This allows the original distro to remain clean, but if say it’s necessary to make changes to the local version we can do that without risking dirtying the original distribution.

Of course, this setup may not work for you and your projects, but over the years it’s what has evolved to work for me and my needs.

#8 and especially #9 – yes. Please stop checking in your cruft.

Remember, version control is there to help us write better code. Not directly, but once code is written it will always have to be maintained. History is a part of that maintenance cycle. The more relevant history we can preserve, the better off we can be in the long run.

Never? I wouldn’t go that far.

OK, programmer geek time.

I subscribe to a newsletter that mentioned an article saying “It *never* made sense to learn Java“.

I agree, and I disagree.

First, I generally agree with the guy because yes, just about anything you can do in Java you can do in C++, and perhaps better. I say perhaps because in all my years of using many programming languages I have found that people think C++ is a great object-oriented programming language, but it’s not. It’s a language where you can write OO-like code but there are lots of little idiosyncrasies involved that can make true OO difficult. C++ is a fantastic generic language tho, witnessed by templates.

I remember when I worked at Metrowerks, a developer tools company. Java had just come out. I was hired in their developer tech support group, and myself and another guy started on the same day. I was going to do Mac support and they gave him a bunch of “Learn Java” books and he became the Java guy. Java was all new, exciting, held the promise of “write once, run anywhere” but of course we all quickly learned that didn’t really work out well and over the years Java fell from grace tho it found a niche. When I worked on the Tango product, Java Beans was becoming a big enterprise thing so that’s the first time I got to actually do some Java dabbling, and while I thought it did a few things right and cool over C++, I still didn’t see the big deal. Ever since NeXT bought Apple, while it took me a moment to grok the syntax of Objective-C, I’ve loved it ever since because between that language and a good library like Cocoa (along with good tools to complete the development chain), I’m empowered to do true object-oriented programming and geez… I really haven’t had any desire to use C++. Sure, I did in a lower-level framework of a past project but when I had to use C++ and Objective-C side-by-side, there was no question that, especially with the framework support Apple provided, that ObjC was a far better language tool and you could really see the shortcomings of C++ as an OO tool. I’ve used a lot of other languages over the years, and well… while C++ is still a good language, it’s not the be-all-end-all.

But never made sense to learn Java? I think the problem with that premise is we’re looking at languages first. Most people do this, and IMHO it’s backwards.

We shouldn’t pick a language then forge ahead to solve a problem. We need to look at the problem, then utilize the best tools to solve that problem. The problem will dictate what languages, what libraries, what tools we choose. If you want to write Android apps, you’re going to have to learn Java. If you want some enterprise job, they may require Java because that’s what their backend uses. A project I’m working on now is separated into two main components: a background daemon that does the heavy lifting, which then communicates with a GUI app for the user to interact with. We are doing the GUI in Cocoa because that makes the most sense for writing GUI apps on the Mac. We write the background daemon in C++ using mostly generic libraries (e.g. standard lib, POSIX, BSD, some company-internal libraries) so the daemon can be easily reused on both Mac and Linux. The problem requirements dictates the tools and languages used, not the other way around.

But hey… if I want to answer his question, I’d say learning C++ is probably an evolutionary dead-end as well. If I was going to teach my kids programming today? I’d probably start with Python or maybe Ruby, along with web-based languages like HTML and XML. That will allow them to learn basic language structure without a lot of the complexities of C/C++/ObjC (e.g. pointers, memory management, etc.) but also giving them a lot of default power to do useful work because of robust library support. After that, see where they wanted to go. If they wanted to write desktop or mobile GUI apps, it’ll depend upon the platform: Mac OS X or iOS? learn ObjC and Cocoa (Touch). Android? learn Java. If they wanted to write web apps, JavaScript, CSS, AJAX, and all that. It just all depends upon what they want to do, what problem they want to solve.

So yes, I can understand and accept the author’s criticism of Java, but I do believe he’s answering the wrong question. We must look at the requirements of the problem to solve and let that shape what tools we choose, including language choice.

What Monty Python Taught Me About the Software Industry

A great blog post by David “Lefty” Schlesinger on what Monty Python can teach us about the software industry.

If you’re not in this industry, you might not get it all… but he nails it pretty well. The part that really struck a chord with me is Mr. Creosote:

“More” is Not the Same As “Better:” For years, the mobile phone industry — as typified by OEMs like Nokia and Motorola — marched along to the beat of the carriers’ collective “standards and requirements,” which essentially amounted to an extremely lengthy checklist of mostly extreme minor features, quibbles, and quid pro quos. In the case of one major carrier, the requirements specifications stretched to some 1,800 pages.

Apple turned that all upside down with its introduction of the iPhone, which failed to implement even such commonplace features as MMS messaging. Predictions of imminent doom for the device and for AT&T (the carrier foolish enough to go for an unproven phone from an inexperienced manufacturer) were rife (and I admit to being among the misguided doomsayers, initially).

It turned out that consumers didn’t care about the carriers’ checklists, and they pretty much didn’t care about niceties like MMS messaging, either. What they did care about was nice design and thoughtfully constructed — both surprising and consistent — user experience.

Adding features aimlessly guarantees that none of those features will be thoughtfully implemented; it reduces the likelihood that any of them are well-integrated. Worse, just-one-more-feature considerably increases the chances of the unexpected happening to your project (see point 1).

Product marketers love to try to squeeze just one more tiny feature — really, it’s wafer thin! — into everything they work on. It’s a bad idea.

Emphasis added… because I’ve dealt with this for so long.

Writing good software is a craft, which most people don’t get. It’s hard to do, it takes time. It takes iterations, revisions, even throwing everything out and starting over. We can add 1800 pages worth of features if you really want it, but the old saying stands: good, fast, or cheap — pick 2. Unfortunately they usually want it fast and cheap… with more features, and oh, can you just add this?