Home > Development > C4[3]: Each decision is an opportunity to fuck up

C4[3]: Each decision is an opportunity to fuck up

September 30th, 2009

I was fortunate enough to attend the fourth edition of the C4 conference in Chicago, September 25th to the 27th.

Synopsis

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[3], 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.

Juxtaposition
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.

Full-length talks

Rentzsch – JSTalk

JSTalk is a language with optional bracket syntax, so it is easily accessible to both Obj-C and Javascript developers

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.

Finally, JSTalk isn’t really about Javascript, it’s about scripting over Distributed Objects. Because that’s really what’s going on behind the scenes, as opposed to AppleEvents.

http://github.com/ccgus/jstalk

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

Information

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.

Get organized

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: poorguy@apple.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

System 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.

Functional Tests

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.

Unit Tests

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.

http://progit.org/book/ and http://hgbook.red-bean.com/read/ are the two books that are online. Both are good content.

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.

Three points

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.

Delegate:

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.

Blitz Talks

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.
RE:Trace
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?
Outliner?

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.

http://github.com/fraserhess/boutique

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 to 65 characters and your <meta> to 156 characters.<br /> 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.</p> <p> 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.</p> <p> 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.</p> <p> 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.</p> <p><h4>Gerbarg – Compiler engineering</h4> <p> So you found a bug, and you think the compiler is generating bad code. There are good news and bad news.<br /> 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.<br /> 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.<br /> <s>Clang is the static analyzer and llvm is a gcc front-end.</s> clang is a compiler front-end, while llvm is a low-level virtual machine which <a href="http://llvm.org/docs/CommandGuide/html/llvmgcc.html">can also generate native code</a>. They are written in easy-to-read, easy-to-maintain C++.</p> <p> You can subscribe and submit patches to the cfe-dev mailing list.<br /> You can check out the code from svn for clang-llvm and build it with current tools: congratulations, you have built your own compiler!</p> <p> 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.</p> <div class="fixed"></div> </div> <div class="under"> <span class="categories">Categories: </span><span><a href="http://developer.casgrain.com/?cat=1" title="View all posts in Development" rel="category">Development</a></span> <span class="tags">Tags: </span><span></span> </div> </div> <!-- related posts START --> <!-- related posts END --> <script type="text/javascript" src="http://developer.casgrain.com/wp-content/themes/inove/js/comment.js"></script> <div id="comments"> <div id="cmtswitcher"> <a id="commenttab" class="curtab" href="javascript:void(0);">Comments (8)</a> <div class="fixed"></div> </div> <div id="commentlist"> <!-- comments START --> <ol id="thecomments"> <li class="comment regularcomment" id="comment-5574"> <div class="author"> <div class="pic"> <img alt='' src='http://1.gravatar.com/avatar/b9012970f22b84c5b344ffa6f8a884d5?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G' class='avatar avatar-32 photo' height='32' width='32' /> </div> <div class="name"> <span id="commentauthor-5574"> Nico </span> </div> </div> <div class="info"> <div class="date"> October 1st, 2009 at 12:01 | <a href="#comment-5574">#1</a> </div> <div class="act"> <a href="javascript:void(0);" onclick="MGJS_CMT.reply('commentauthor-5574', 'comment-5574', 'comment');">Reply</a> | <a href="javascript:void(0);" onclick="MGJS_CMT.quote('commentauthor-5574', 'comment-5574', 'commentbody-5574', 'comment');">Quote</a> </div> <div class="fixed"></div> <div class="content"> <div id="commentbody-5574"> <p>FYI… </p> <p>“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.<br /> First, it runs natively on Windows. No need for a “Yellow Box” or a reboot.<br /> Second, it does not use the GPL license.”</p> <p>1/ GNUstep does run natively on Windows…<br /> 2/ GNUstep’s license is the LGPL, not the GPL. Which means you can certainly use GNUstep in a proprietary application.</p> <p>Not sure about the fact that Cocotron was started at the same time as gnustep. In any case, the first release was in 2006…</p> </div> </div> </div> <div class="fixed"></div> </li> <li class="comment admincomment" id="comment-5576"> <div class="author"> <div class="pic"> <img alt='' src='http://0.gravatar.com/avatar/0fa717da8f1eae00282b56dda66045b7?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G' class='avatar avatar-32 photo' height='32' width='32' /> </div> <div class="name"> <a id="commentauthor-5576" class="url" href="http://philippe.casgrain.com/" rel="external nofollow"> Philippe </a> </div> </div> <div class="info"> <div class="date"> October 1st, 2009 at 13:02 | <a href="#comment-5576">#2</a> </div> <div class="act"> <a href="javascript:void(0);" onclick="MGJS_CMT.reply('commentauthor-5576', 'comment-5576', 'comment');">Reply</a> | <a href="javascript:void(0);" onclick="MGJS_CMT.quote('commentauthor-5576', 'comment-5576', 'commentbody-5576', 'comment');">Quote</a> </div> <div class="fixed"></div> <div class="content"> <div id="commentbody-5576"> <p><a href="#comment-5574" rel="nofollow">@Nico </a> </p> <p>1. I know that it does not run natively, but you could run it in a VM with full integration. Or you could reboot in GNUStep.<br /> 2. Updated license. Thanks!</p> <p>About the time comment, I believe it something that Christopher Lloyd said during his talk. I will try to contact him for clarification.</p> </div> </div> </div> <div class="fixed"></div> </li> <li class="comment admincomment" id="comment-5584"> <div class="author"> <div class="pic"> <img alt='' src='http://0.gravatar.com/avatar/0fa717da8f1eae00282b56dda66045b7?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G' class='avatar avatar-32 photo' height='32' width='32' /> </div> <div class="name"> <a id="commentauthor-5584" class="url" href="http://philippe.casgrain.com/" rel="external nofollow"> Philippe </a> </div> </div> <div class="info"> <div class="date"> October 1st, 2009 at 20:49 | <a href="#comment-5584">#3</a> </div> <div class="act"> <a href="javascript:void(0);" onclick="MGJS_CMT.reply('commentauthor-5584', 'comment-5584', 'comment');">Reply</a> | <a href="javascript:void(0);" onclick="MGJS_CMT.quote('commentauthor-5584', 'comment-5584', 'commentbody-5584', 'comment');">Quote</a> </div> <div class="fixed"></div> <div class="content"> <div id="commentbody-5584"> <p><a href="#comment-5574" rel="nofollow">@Nico </a><br /> I just got word from Chris Lloyd and Cocotron was closed-source until 2006. I have added this clarification in the post.</p> </div> </div> </div> <div class="fixed"></div> </li> <li class="comment regularcomment" id="comment-5592"> <div class="author"> <div class="pic"> <img alt='' src='http://1.gravatar.com/avatar/b9012970f22b84c5b344ffa6f8a884d5?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G' class='avatar avatar-32 photo' height='32' width='32' /> </div> <div class="name"> <span id="commentauthor-5592"> Nico </span> </div> </div> <div class="info"> <div class="date"> October 2nd, 2009 at 02:45 | <a href="#comment-5592">#4</a> </div> <div class="act"> <a href="javascript:void(0);" onclick="MGJS_CMT.reply('commentauthor-5592', 'comment-5592', 'comment');">Reply</a> | <a href="javascript:void(0);" onclick="MGJS_CMT.quote('commentauthor-5592', 'comment-5592', 'commentbody-5592', 'comment');">Quote</a> </div> <div class="fixed"></div> <div class="content"> <div id="commentbody-5592"> <p>Er… no, really, it _does_ run natively <img src='http://developer.casgrain.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> — you recompile your program on windows, etc. GNUstep on windows uses a native GDI graphic backend, no X11. Random example of a gnustep app running on windows: <a href="http://multixden.blogspot.com/2009/06/gshisen-on-windows.html" rel="nofollow">http://multixden.blogspot.com/2009/06/gshisen-on-windows.html</a> … note the “in-window” menu automatically used. The only thing is that the UI theme is not the windows one, although you could change the theme. Greg Casamento is (iirc) working on creating a theme that uses the windows theme api directly.</p> </div> </div> </div> <div class="fixed"></div> </li> <li class="comment regularcomment" id="comment-5593"> <div class="author"> <div class="pic"> <img alt='' src='http://1.gravatar.com/avatar/b9012970f22b84c5b344ffa6f8a884d5?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G' class='avatar avatar-32 photo' height='32' width='32' /> </div> <div class="name"> <span id="commentauthor-5593"> Nico </span> </div> </div> <div class="info"> <div class="date"> October 2nd, 2009 at 02:58 | <a href="#comment-5593">#5</a> </div> <div class="act"> <a href="javascript:void(0);" onclick="MGJS_CMT.reply('commentauthor-5593', 'comment-5593', 'comment');">Reply</a> | <a href="javascript:void(0);" onclick="MGJS_CMT.quote('commentauthor-5593', 'comment-5593', 'commentbody-5593', 'comment');">Quote</a> </div> <div class="fixed"></div> <div class="content"> <div id="commentbody-5593"> <p>(thanks for the summary of the conf by the way — pretty interesting)</p> </div> </div> </div> <div class="fixed"></div> </li> <li class="comment regularcomment" id="comment-5605"> <div class="author"> <div class="pic"> <img alt='' src='http://0.gravatar.com/avatar/424994f6d4329c51d9448d9c8b4a5fad?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G' class='avatar avatar-32 photo' height='32' width='32' /> </div> <div class="name"> <a id="commentauthor-5605" class="url" href="http://www.cocoacast.com/?q=blog/189" rel="external nofollow"> Philippe Guitard </a> </div> </div> <div class="info"> <div class="date"> October 2nd, 2009 at 15:03 | <a href="#comment-5605">#6</a> </div> <div class="act"> <a href="javascript:void(0);" onclick="MGJS_CMT.reply('commentauthor-5605', 'comment-5605', 'comment');">Reply</a> | <a href="javascript:void(0);" onclick="MGJS_CMT.quote('commentauthor-5605', 'comment-5605', 'commentbody-5605', 'comment');">Quote</a> </div> <div class="fixed"></div> <div class="content"> <div id="commentbody-5605"> <p>Great post Philippe! </p> <p>For those looking for more details, listen to the podcast Philippe and I produce on a regular basis: <a href="http://www.cocoacast.com/?q=blog/189" rel="nofollow">http://www.cocoacast.com/?q=blog/189</a> (in French).</p> <p>I know this is a shameless self promotion but we’re looking for more listeners!</p> </div> </div> </div> <div class="fixed"></div> </li> <li class="comment regularcomment" id="comment-5616"> <div class="author"> <div class="pic"> <img alt='' src='http://0.gravatar.com/avatar/4030f7e8f6b6d3c09d10ec12691773c1?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G' class='avatar avatar-32 photo' height='32' width='32' /> </div> <div class="name"> <span id="commentauthor-5616"> John C. Randolph </span> </div> </div> <div class="info"> <div class="date"> October 2nd, 2009 at 21:13 | <a href="#comment-5616">#7</a> </div> <div class="act"> <a href="javascript:void(0);" onclick="MGJS_CMT.reply('commentauthor-5616', 'comment-5616', 'comment');">Reply</a> | <a href="javascript:void(0);" onclick="MGJS_CMT.quote('commentauthor-5616', 'comment-5616', 'commentbody-5616', 'comment');">Quote</a> </div> <div class="fixed"></div> <div class="content"> <div id="commentbody-5616"> <p>“Clang is the static analyzer and llvm is a gcc front-end.”</p> <p>No, Clang is the C and Objective-C parser (C++ still under construction). LLVM is the Low Level Virtual Machine. Details available at LLVM.org.</p> <p>-jcr</p> </div> </div> </div> <div class="fixed"></div> </li> <li class="comment admincomment" id="comment-5617"> <div class="author"> <div class="pic"> <img alt='' src='http://0.gravatar.com/avatar/0fa717da8f1eae00282b56dda66045b7?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G' class='avatar avatar-32 photo' height='32' width='32' /> </div> <div class="name"> <a id="commentauthor-5617" class="url" href="http://philippe.casgrain.com/" rel="external nofollow"> Philippe </a> </div> </div> <div class="info"> <div class="date"> October 2nd, 2009 at 22:19 | <a href="#comment-5617">#8</a> </div> <div class="act"> <a href="javascript:void(0);" onclick="MGJS_CMT.reply('commentauthor-5617', 'comment-5617', 'comment');">Reply</a> | <a href="javascript:void(0);" onclick="MGJS_CMT.quote('commentauthor-5617', 'comment-5617', 'commentbody-5617', 'comment');">Quote</a> </div> <div class="fixed"></div> <div class="content"> <div id="commentbody-5617"> <p><a href="#comment-5616" rel="nofollow">@John C. Randolph </a><br /> Updated. Thanks!</p> </div> </div> </div> <div class="fixed"></div> </li> </ol> <!-- comments END --> <!-- trackbacks START --> <div class="fixed"></div> <!-- trackbacks END --> </div> </div> <div class="messagebox"> Comments are closed. </div> <div id="postnavi"> <span class="prev"><a href="http://developer.casgrain.com/?p=94" rel="next">Automatically localize your nibs when building</a></span> <span class="next"><a href="http://developer.casgrain.com/?p=43" rel="prev">Display std::wstring in Xcode using a Data Formatter</a></span> <div class="fixed"></div> </div> </div> <!-- main END --> <!-- sidebar START --> <div id="sidebar"> <!-- sidebar north START --> <div id="northsidebar" class="sidebar"> <!-- feeds --> <div class="widget widget_feeds"> <div class="content"> <div id="subscribe"> <a rel="external nofollow" id="feedrss" title="Subscribe to this blog..." href="http://developer.casgrain.com/?feed=rss2"><abbr title="Really Simple Syndication">RSS</abbr></a> <ul id="feed_readers"> <li id="google_reader"><a rel="external nofollow" class="reader" title="Subscribe with Google" href="http://fusion.google.com/add?feedurl=http://developer.casgrain.com/?feed=rss2"><span>Google</span></a></li> <li id="youdao_reader"><a rel="external nofollow" class="reader" title="Subscribe with Youdao" href="http://reader.youdao.com/#url=http://developer.casgrain.com/?feed=rss2"><span>Youdao</span></a></li> <li id="xianguo_reader"><a rel="external nofollow" class="reader" title="Subscribe with Xian Guo" href="http://www.xianguo.com/subscribe.php?url=http://developer.casgrain.com/?feed=rss2"><span>Xian Guo</span></a></li> <li id="zhuaxia_reader"><a rel="external nofollow" class="reader" title="Subscribe with Zhua Xia" href="http://www.zhuaxia.com/add_channel.php?url=http://developer.casgrain.com/?feed=rss2"><span>Zhua Xia</span></a></li> <li id="yahoo_reader"><a rel="external nofollow" class="reader" title="Subscribe with My Yahoo!" href="http://add.my.yahoo.com/rss?url=http://developer.casgrain.com/?feed=rss2"><span>My Yahoo!</span></a></li> <li id="newsgator_reader"><a rel="external nofollow" class="reader" title="Subscribe with newsgator" href="http://www.newsgator.com/ngs/subscriber/subfext.aspx?url=http://developer.casgrain.com/?feed=rss2"><span>newsgator</span></a></li> <li id="bloglines_reader"><a rel="external nofollow" class="reader" title="Subscribe with Bloglines" href="http://www.bloglines.com/sub/http://developer.casgrain.com/?feed=rss2"><span>Bloglines</span></a></li> <li id="inezha_reader"><a rel="external nofollow" class="reader" title="Subscribe with iNezha" href="http://inezha.com/add?url=http://developer.casgrain.com/?feed=rss2"><span>iNezha</span></a></li> </ul> </div> <div class="fixed"></div> </div> </div> <!-- showcase --> <!-- posts --> <div class="widget"> <h3>Recent Posts</h3> <ul> <li><a href="http://developer.casgrain.com/?p=125">Upgrading to Xcode 4.3</a></li><li><a href="http://developer.casgrain.com/?p=115">Xcode 4.2 and older iOS devices</a></li><li><a href="http://developer.casgrain.com/?p=109">iPad or Netbook?</a></li><li><a href="http://developer.casgrain.com/?p=107">Introducing PhFacebook, a Cocoa framework to Facebook’s API</a></li><li><a href="http://developer.casgrain.com/?p=104">Eight guys, four weeks, one dream</a></li><li><a href="http://developer.casgrain.com/?p=102">Multiple developers, one iPhone app</a></li><li><a href="http://developer.casgrain.com/?p=100">Tap-enabled UITableView section headers (and footers)</a></li><li><a href="http://developer.casgrain.com/?p=94">Automatically localize your nibs when building</a></li><li><a href="http://developer.casgrain.com/?p=81">C4[3]: Each decision is an opportunity to fuck up</a></li><li><a href="http://developer.casgrain.com/?p=43">Display std::wstring in Xcode using a Data Formatter</a></li> </ul> </div> <!-- recent comments --> <!-- tag cloud --> <div id="tag_cloud" class="widget"> <h3>Tag Cloud</h3> </div> </div> <!-- sidebar north END --> <div id="centersidebar"> <!-- sidebar east START --> <div id="eastsidebar" class="sidebar"> <!-- categories --> <div class="widget widget_categories"> <h3>Categories</h3> <ul> <li class="cat-item cat-item-1"><a href="http://developer.casgrain.com/?cat=1" title="View all posts filed under Development">Development</a> </li> <li class="cat-item cat-item-3"><a href="http://developer.casgrain.com/?cat=3" title="View all posts filed under Graphics">Graphics</a> </li> <li class="cat-item cat-item-9"><a href="http://developer.casgrain.com/?cat=9" title="View all posts filed under iOS">iOS</a> </li> <li class="cat-item cat-item-5"><a href="http://developer.casgrain.com/?cat=5" title="View all posts filed under MacOSX">MacOSX</a> </li> <li class="cat-item cat-item-7"><a href="http://developer.casgrain.com/?cat=7" title="Quick Tips">Quickie</a> </li> <li class="cat-item cat-item-10"><a href="http://developer.casgrain.com/?cat=10" title="View all posts filed under Xcode">Xcode</a> </li> </ul> </div> </div> <!-- sidebar east END --> <!-- sidebar west START --> <div id="westsidebar" class="sidebar"> <!-- blogroll --> <div class="widget widget_links"> <h3>Blogroll</h3> <ul> <li><a href="http://borkwarellc.wordpress.com">Borkware Miniblog</a></li> <li><a href="http://wilshipley.com/blog/">Call Me Fishmeal.</a></li> <li><a href="http://chanson.livejournal.com/">Chris Hanson</a></li> <li><a href="http://gusmueller.com/blog/">Gus’s blog, adventures in Flying Meat.</a></li> <li><a href="http://www.latenightcocoa.com/" title="Mac Development Podcast">Late Night Cocoa</a></li> <li><a href="http://www.red-sweater.com/blog">Red Sweater Blog</a></li> <li><a href="http://rentzsch.com">rentzsch.com: Tales from the Red Shed</a></li> <li><a href="http://theocacao.com/">Theobroma Cacao</a></li> </ul> </div> </div> <!-- sidebar west END --> <div class="fixed"></div> </div> <!-- sidebar south START --> <div id="southsidebar" class="sidebar"> <!-- archives --> <div class="widget"> <h3>Archives</h3> <ul> <li><a href='http://developer.casgrain.com/?m=201202' title='February 2012'>February 2012</a></li> <li><a href='http://developer.casgrain.com/?m=201112' title='December 2011'>December 2011</a></li> <li><a href='http://developer.casgrain.com/?m=201009' title='September 2010'>September 2010</a></li> <li><a href='http://developer.casgrain.com/?m=201008' title='August 2010'>August 2010</a></li> <li><a href='http://developer.casgrain.com/?m=201002' title='February 2010'>February 2010</a></li> <li><a href='http://developer.casgrain.com/?m=201001' title='January 2010'>January 2010</a></li> <li><a href='http://developer.casgrain.com/?m=200912' title='December 2009'>December 2009</a></li> <li><a href='http://developer.casgrain.com/?m=200909' title='September 2009'>September 2009</a></li> <li><a href='http://developer.casgrain.com/?m=200907' title='July 2009'>July 2009</a></li> <li><a href='http://developer.casgrain.com/?m=200906' title='June 2009'>June 2009</a></li> <li><a href='http://developer.casgrain.com/?m=200905' title='May 2009'>May 2009</a></li> <li><a href='http://developer.casgrain.com/?m=200904' title='April 2009'>April 2009</a></li> <li><a href='http://developer.casgrain.com/?m=200902' title='February 2009'>February 2009</a></li> <li><a href='http://developer.casgrain.com/?m=200809' title='September 2008'>September 2008</a></li> <li><a href='http://developer.casgrain.com/?m=200807' title='July 2008'>July 2008</a></li> <li><a href='http://developer.casgrain.com/?m=200805' title='May 2008'>May 2008</a></li> <li><a href='http://developer.casgrain.com/?m=200803' title='March 2008'>March 2008</a></li> <li><a href='http://developer.casgrain.com/?m=200802' title='February 2008'>February 2008</a></li> </ul> </div> <!-- meta --> <div class="widget"> <h3>Meta</h3> <ul> <li><a href="http://developer.casgrain.com/wp-login.php">Log in</a></li> </ul> </div> </div> <!-- sidebar south END --> </div> <!-- sidebar END --> <div class="fixed"></div> </div> <!-- content END --> <!-- footer START --> <div id="footer"> <a id="gotop" href="#" onclick="MGJS.goTop();return false;">Top</a> <a id="powered" href="http://wordpress.org/">WordPress</a> <div id="copyright"> Copyright © 2008-2013 developer.casgrain.com </div> <div id="themeinfo"> Theme by <a href="http://www.neoease.com/">NeoEase</a>. Valid <a href="http://validator.w3.org/check?uri=referer">XHTML 1.1</a> and <a href="http://jigsaw.w3.org/css-validator/check/referer?profile=css3">CSS 3</a>. </div> </div> <!-- footer END --> </div> <!-- container END --> </div> <!-- wrap END --> </body> </html>