What is “Nougat”? — Part 2
September 21, 2012 in iOS, Mac, Nougat, Oxygene
In this second part of our series on the upcoming edition of Oxygene for Cocoa, codenamed “Nougat”, i want to go into some more details about the compiler — the heart and soul of the product — and what we plan for it to deliver.
Target Platforms
As mentioned in Part 1, Nougat is a compiler for the Objective-C runtime, and will generate code on the same level as Apple’s Objective-C compiler (Clang/LLVM) does. As such it will generate (Delphi lovers, rejoice ;) CPU-native executables —a first for Oxygene — for the following three targets:
- 64-bit Intel Mac OS X Applications
- 32-bit ARMv7 iOS Applications
- 32-bit Intel iOS Simulator Applications
Your first question might be “why only 64-bit for OS X”, and the answer is twofold:
One: No-one really, seriously, still creates 32-bit Mac applications. Every Mac sold has been capable of running 64-bit for way over 5 years now.
Two: Much more importantly, with OS X Leopard (that’s 10.5, which shipped, again, five years ago), Apple introduced what is commonly referred to as the “modern” Objective-C runtime. This is a newer, better version of the runtime that Cocoa apps run on, and many advanced features, such as ARC, are only available on that new runtime. This “modern” Objective-C runtime, you guessed it, supports the above three platforms, but it does not support 32-bit Mac OS X.
We could go out of our way to support the older runtime, but the current thinking is Nahh, it won’t be worth the hassle. If nothing else, the lack of ARC would be a major bummer.
Automatic Reference Counting
As you might have guessed from the above, Oxygene supports and fully embraces ARC, the Automatic Reference Counting model Apple introduced at last year’s WWDC. In fact, we’re so sold on ARC that we’re planning to make it non-optional.
For those unfamiliar with the matter, what does ARC mean? ARC means that the compiler automatically keeps track of reference counting for you. Under the hood, Objective-C uses a retain/release model for keeping track of object lifetimes (similar to COM and Delphi Interfaces). When wanting to hold on to an object, it used to be you’d call “retain” on it. Once you were done, you’d call “release” (and there’s the concept of autorelease pools which sweetens this memory management model some more). With ARC, you don’t have to (in fact, you cannot) keep track of retain/release — the compiler handles all of that for you.
The end result is that memory management is pretty much taken care of for you, and the kind of code you write in Nougat will be comparable to what you do in the Garbage Collected .NET and Java environments (although ARC is not garbage collection, but deterministic memory management).
Auto-Boxing
Like most platforms, Objective-C (due to its roots in C) has both simple types — such as integers, booleans, C-style zero-terminated strings — and class-based types that can represent the same kind of data.
Staying in line with its counterparts for .NET and Java, where such a thing is common and expected, “Nougat” will automatically handle boxing and unboxing for numbers, string and arrays.
For example, you can simply write 5, and the compiler will take care of converting that int to and from an NSNumber for you, when boxing is needed. For example, you can write
var x := 5; // "x" will be an Integer.
myDictionary.setValue(x) forKey('five');
or
var y := NSNumber.numberWithInt(5); // silly, i know.
z := y+5; // "y" will be unboxed.
In a similar fashion, string literals and C-style strings and NSString will be interchangeable, with the compiler doing the right thing for you.
References
As a native Cocoa compiler, Nougat will need to let you reference other frameworks and libraries — be it the core operating system frameworks provided by Apple (such as Cocoa, UIKit, MapKit, you name it) or third party (or even your own) frameworks and libraries.
As mentioned in Part 1, Nougat is no bridge, and requires no mappings to be defined. Rather, Nougat directly understands and consumes the exiting Objective-C frameworks — just like you would expect, and just like Oxygene does on its other two platforms.
Now, Objective-C frameworks and libraries don’t have the rich meta data that Oxygene is used to — they are just binaries with compiled code, and C-style header files. Because parsing C (and Objective-C) headers is a time-consuming and inefficient process, Nougat introduces an intermediary format, which we call “.fx Files” that the complier references. .fx files are generated automatically by a tool that comes as part of Nougat, and you can think of them as something like pre-compiled headers — a binary representation of all the definitions found in a framework’s headers.
Nougat will come with pre-created .fx files for the major OS versions we’re supporting (right now the internal alpha drops provide OS X 10.6, 10.7 and 10.8, as well as iOS 5.1 and 6.0), so the compiler (and the IDE) is ready for you to use those frameworks right from the Go. But if there’s a new OS (or beta) coming out that you want to use, it will be as easy as a single click to get that new SDK exposed to Nougat — no need to wait for the NDA to expire and/or us to ship updated support.
How does this look/work from the developer’s point of view? Simple. Just as always, you’ll go to Add Reference to add a new reference to your Oxygene project. The IDE will show you a re-filled list of frameworks in the SDK your current project is targeting (say, OS X 10.8), and all you have to do is, say, pick “CoreLocation” from the list, and you are ready to use the APIs exposed there.
Objective-C itself does not use or know namespaces. For Nougat, types and other external definitions will automatically be partitioned into namespaces based on the frameworks they come from. So, for example, your code files might have uses UIKit, CoreGraphics; in their uses clause, and your code will automatically have all identifiers from those frameworks in scope. If you want to use a class that’s not in scope, you can always prefix it with the namespace, just as you’d expect, i.e.
CoreLocation.CLLocationmanager.startUpdatingLocation();
Czesnik said on September 21, 2012
It would be interesting if not in visual studio. how i can program mac in visual studio? this is crazy idea…
marc said on September 21, 2012
Rome wasn’t built in a day.
Czesnik said on September 21, 2012
will we be at least able to compile on mac from command line? so we could use textmate or something for editing
marc said on September 21, 2012
let me put it this way: the current command line compiler for .NET/Mono and Java/Android works on Mac OS X, yes.
Vincent said on September 21, 2012
“CPU-native executables”
…
This is *huge !*
congrat. Really.
a forseen about the “when” for the beta ? :)
marc said on September 21, 2012
thanx. we’re expecting the beta to hit early next month (October).
Colin said on September 21, 2012
“Shut up and TAKE MY MONEY!” :)
Well done marc and RemObjects.
This is how it should’ve been done.
marc said on September 21, 2012
http://www.remobjects.com/shoppingcart?add=1289 ;)
Colin Johnsun said on September 22, 2012
Done! :-)
Just purchased Oxygene!
marc said on September 22, 2012
excellent! ;)
Simon J Stuart said on September 22, 2012
What’s not to love? Object Pascal language, OSX and iOS output.
Sounds like a no-brainer to me… but then again I am a self-confessed Pascal Fanatic!
Fawzib Rojas said on September 24, 2012
Question: Nougat will create native code? No Mono/.NET/Java required?
If that’s true have you considered a native Windows version (or even Linux)? :-)
Thomas Lohrum said on September 24, 2012
I thought about this myself. Besides any problems RO would have to solve to make this work, what framework would you use to build applications? Windows core does not have a native object oriented framework (.net is managed). Windows API is still procedural, decades old, uses structs, etc. There is no VCL. Actually this made it clear to me, how poorly Windows evolved from a developers (object orientied) perspective. Oxygene for native Windows could be an option, if MS would extend WinRT to the classic desktop. I doubt this will happen though.
marc said on September 25, 2012
“Oxygene for native Windows could be an option, if MS would extend WinRT to the classic desktop. I doubt this will happen though.” actually, we could also do a CPU-native Oxygene *just* for WinRT — but the same question remains: aside form the checkmark on the box, “CPU-native: YES”, what would really be gained?
if we went ahead and did a CPU-native Oxygene compiler for WinRT and did it well, you would *literally* not be able to tell the difference between it and Oxygene for .NET (except that you’d have to compile and ship three different .exe files for your app, and would lose out on a lot of great classes).
marc said on September 25, 2012
What Thomas said. have we considered it? sure. and frankly, once Nougat is done, doing a cpu-native compiler for Windows or Linux would probably pretty simple — but (a) the compiler is only half the story (or maybe even just a quarter), without a proper framework to use, and more importantly (b) we don’t really see the need and use-case. .NET and it’s framework lets you do just about anything you want to do, on Windows. The majority of reasons to not use it are based on an irrational fear and misunderstanding of what .NET and “managed code” really is, or misplaced loyalty to Delphi — and frankly, the people who reject Oxygene/.NET for those reasons would reject a hypothetical native-CPU Oxygene compiler just because “it’s not exactly Delphi” too.
Nougat is not CPU-native because we think that’s somehow *better*. Nougat is a CPU-native because that’s what the native development platform on Mac and iOS is. On Windows and Android, the two big targets for the other flavors, that’s simply not the case. Oxygene for Java JVM code is *more* native on the Android platform than CPU-native code would be, for example.
Fawzib Rojas said on October 5, 2012
Well lack of a framework is not really a problem if you are doing low-level stuff. Right now you cant make drivers (or other low level stuff) in Delphi (or C++ Builder) because its too linked to Windows. I guess you think I’m one of those .NET haters and want only CPU native stuff. I’m not, after all I have Oxygene for .NET and Java, soon the new one. Having Oxygene for .NET, Java, MacOS, IOS, Windows (even without framework) , Linux would be awesome. Anyway, there’s Freepascal framework, porting that can’t be that bad. :-)
PS: Is there an option somewhere to “Notify me” when someone posts/answers me? I forgot I had posted here. :)
marc said on October 5, 2012
“Well lack of a framework is not really a problem if you are doing low-level stuff.” — agreed. but the question is, how a big a market is there for that, compared to the R&D needed (and opportunity cost on other fronts).
“Is there an option somewhere to “Notify me” when someone posts/answers me? ” — not sure, we’d have to check. this is a pretty run off the mill wordpress.