Avatar of marc

by

What is “Nougat”? — Part 1

September 12, 2012 in Elements, iOS, Mac, Nougat

When we launched our new Oxygene website and Oxygene 5.2 last week, we also gave a sneak peek at an upcoming new edition/platform for Oxygene, codenamed “Nougat“.

This is the first in a series of posts about “Nougat”, in which i want to go into a few more details about our plans and the technologies behind Nougat, so you can get a feel for what to expect from the product, as we wait for the first beta to be made available.

So what, exactly, is Nougat?

Nougat is a third independent target for the Oxygene language and compiler, targeting the Apple Cocoa and Cocoa Touch development platforms.

More strictly speaking, Nougat is Oxygene for the Objective-C Runtime.

What does that mean?

Similar to Java, the term Objective-C has overloaded meanings. Of course there is Objective-C, the language, which is what most people think of when they hear the name. It’s the language that Apple’s Xcode IDE uses to let developers create native applications for both of its platforms: (Mac) OS X and iOS.

But underneath the language (and to a large degree influencing how Objective-C as a language works) lies the Objective-C Runtime (OCR, for short). That runtime (oversimplified, a set of C APIs) defines how objects look in memory, manages run-time type information, handles the passing of messages (a.k.a. method calls) to objects, and so on.

The way i like to think about it, the Objective-C runtime puts Cocoa someplace in the middle of “managed” platforms (such as .NET and Java) and “unmanaged” development architectures such as Delphi or C++. So when talking about this, i often call Objective-C “half managed”.

“Nougat” brings the Oxygene language to this Objective-C runtime, in that it compiles Oxygene language code into objects that natively live in this runtime, and seamlessly interact with other objects in the same runtime. It is not a “bridge” (such as MonoTouch, RubyCocoa, or the (now deprecated) Java/Cocoa Bridge, but a fully native second language — in no way second to the Objective-C language itself — that runs on this runtime.

This is important for several reasons:

You’re creating true Objective-C objects

The classes your define in your Nougat application will compile down to true OCR objects. The runtime will see these objects and interact with these objects in the same way that it does with objects created by an Objective-C developer in Xcode. In fact, the runtime cannot even tell them apart.

When you, say, define

type
  RootViewController = class(UITableViewController)

then this “RootViewController” class you are defining will be a true descendant of UITableViewController — with no bridging magic inbetween. If the table view sends a cellForRowAtIndexPath: message to get data to display, the runtime will dispatch that call directly to the cellForRowAtIndexPath() method that you hopefully implemented.

You’re interacting with true Objective-C objects

Just like your classes are true Objective-C classes, all the classes and object instances you interact with will be true Objective-C classes, as well. If you hold a string object, that’s a true NSString instance, and if you are calling

myString:hasPrefix('foo')

you are simply sending the object the hasPrefix: message, just as an Objective-C developer would be with [myString hasPrefix:@"foo"]. (Note that Objective-C’s message sending is nil-safe, and thus corresponds to Oxygene’s colon operator, while a call such as myString.hasPrefix('foo') would throw an exception on nil calls, as you would expect from Oxygene code.)

No awkward manual mappings

Just to be completely clear, there is no manually defined “mapping” between APIs defined in Cocoa and the APIs Oxygene sees (or vice versa), as there is in most Cocoa bridge solutions. There’s no magic table in Oxygene that tells the compiler how to match a call to hasPrefix('foo') to the right method on the NSString.

The Oxygene compiler, instead, simply has full direct knowledge of the Objective-C APIs and does those calls directly — just as Objective-C itself would: it takes the name, packs it up in a selector, and calls the OCR’s objc_mmsg_send() function.

In fact, if you have a variable of type dynamic (or, aliased to that type, id), Oxygene will let you make just about any known method call on that object, just like Objective-C does.

Beautiful Cocoa-style method calls

This also means that Oxygene has full support for Objective-C’s more verbose method naming convention — something that is crucial, really, as a developer would want to interact with the Cocoa APIs as they have been designed and intended (for better or for worse — i personally find Cocoa beautiful).

I purposely picked a simple and uncontroversial example with hasPrefix: above, but what Cocoa APIs are known for are of course the infamous “muti-part” method names, where the method name reads like a sentence with the individual parameters interspersed in between. Consider for example stringByPaddingToLength:withString:startingAtIndex:. How would you call this in Oxygene?

Most bride-based solutions go for one of two options: they would either provide an (often overloaded) method named after just the first part, e.g. stringByPaddingToLength(20, " ", 5) or they would concat the entire name into one big chunk of text, such as stringByPaddingToLengthWithStringStartingAtIndex(20, " ", 5).

For one, yuck. For another, this would require manually crafted mapping tables, which Oxygene does not use — as explained above, Oxygene just handles the Cocoa APIs, any Cocoa APIs, straight up.

So how do you call this method in Oxygene? Simple:

myString.stringByPaddingToLength(20) withString(' ') startingAtIndex(5);

Simple, elegant, and it preserves the “readable as a sentence” aesthetics of the underlying API. What’s more, the syntax seamlessly works with any method an OCR object might declare.

The same goes, of course, for declaring methods in your own classes — both when implementing things such as delegates, but also when designing your own class APIs in Cocoa style:

method stringByPaddingToLength(aLength: Integer) withString(aString: String) startingAtIndex(aStartIndex: Integer);

What’s Next?

With this first post, we have only just begun to scratch the surface of “Nougat”. Stay tuned for more in this series over the next few weeks.

Oh, and be sure to buy or renew your copy of Oxygene now to be among the first to get access to Nougat when the beta hits early next month.

And let us know what you think in the comments below!

See also part 2 . . .

23 responses to What is “Nougat”? — Part 1

  1. Sorry, maybe i dont understand this article well. I read the article and i think that nougat is the same like xcode but in visual studio v.xxx. I assume that is C too. I understand this product if the language was pascal or ¿? but in C?.
    So the only thing is that the ide is other (plus best options, and so…. and other things ). ¿ is this correct ?
    My idea is not disturb you, but i have no clear some concepts …

    Thanks.

  2. Hi Marc –

    I want to congratulate you and Carlo (and any other Oxygene team members I’m not familiar with) for your dedication and great direction you have used in developing Oxygene to what it is today. I’ve been a Delphi developer since version 1.0 was released. With the imminent release of Nougat, and the existing .NET and Java releases…I’m seriously considering NOT upgrading to Delphi XE3 and starting to migrate new and existing projects over to Oxygene.

    And, yes, I have renewed my subscription to Oxygene 5.2.

    Alan

  3. Mark,

    Beautiful!

    Will Nougat be hosted in XCode or in VS? In other words, can I dump my Windows VM?

    Mike

    • for now, Nougat will run in Visual Studio, with the rest of Oxygene. long term, we are pursuing other IDE options, but we wanna focus on one thing first.

  4. I’m really interested in Cocoa Touch and iOS.
    How Nougat will run: From VS and Windows or from Xcode and OS X?
    How we will run iOS Simulator from Nougat? How we will test app?
    Will Nougat work with DA Xcode?

    Tadeusz

    • We’ll have more on how deployment and debugging will work, in a future post. suffice to say it will be cool ;)

      Nougat will handle any Cocoa frameworks, so that will include DA/Xcode, of course. (more on that too, in part two of this blog series — which i wrote a big chunk of, today ;)

  5. Great idea., great work.

  6. myString.stringByPaddingToLength(20) withString(‘ ‘) startingAtIndex(5);

    Will this syntax be supported in .NET and Java personalities? Also how are you going to strongly map the messages. I mean, will NSString know about it’s methods? AFAIK you can send any signal to any object with only a compiler warning. Will this be supported of will that require the use of “dynamic”?

    • “Will this syntax be supported in .NET and Java personalities” probably, but it will nt be CLS-compliant (ie C# o Java language devs wont be able to call methods named like this that you’d expose.

      ” Also how are you going to strongly map the messages. I mean, will NSString know about it’s methods” there’s no mapping. the compiler sees what the classes expose, and lets you call it.

      ” AFAIK you can send any signal to any object with only a compiler warning” sortof. with ARC this is a but more strict (and Oxygene will have the same restrictions). but yes, on a “dynamic”, you can call any method, just like on “id” in Objective-C. With known object types, the compiler will enforce that the method is known for the object (just like Objective-C ARC does).

      The next blog post will go into more details on this.

  7. I guess I’d have preferred : mystring.StringByPaddingToLength(9) & withString(‘.’) & startingAtIndex(0)

    that is, an actual operator character but NOT A DOT, instead of Space being used to combine the parts. Then the “selectorBegins(arg) & selectorContinues” is visibly more different. As it is, it looks like a typo.
    Especially when you format it on multiple lines, and then someone gets confused and starts adding semicolons. Pain. Pain. Pain.

    W

  8. Great to see that there will be a solution for iOS with Cocoa in near future! I really prefer such a solution with native Objects.

    Although I like it, some critical thoughts…
    Of course, your slogan is “it isn’t our daddy’s pascal”, but I think this language is getting more and more complicated and confusing. Pascal, as we like it, is simple and extremely useful when working on different projects at the same time, because at the fact that it is easy to read. To be honest, the Oxygene Syntax has some great improvements which should be influence Delphi, but it expands too much and way too fast.

    why not using
    function stringByPadding( toLength:Integer; withCharacter: Char; startingAtIndex:Integer ): String;
    ?

    Maybe with default values. This would be more pascal like and you do not need to create a complete new syntax type for this function? Of course, you maybe need more mapping tables and it is more work for you, but it is much more pascal style and user-friendly Is it useful to create every time a new syntax if you come to problems during compiler development? Even if you do not plan to support this syntax in other Oxygene supported systems. For us it is a big question if we will use Oxygene in future (or maybe switch to Delphi/FM), because we really need more stability…

    • “why not using function stringByPadding( toLength:Integer; withCharacter: Char; startingAtIndex:Integer ): String;”

      As i just posted on Jonyon’s Blog: We did explore a wide variety of options, including the second “named parameter” approach that you suggest, but our main issue with that one was exactly that: these ARE NOT named parameters, and that is the wrong way to think about these names.

      All parts together form the core name of the method. If you look at the docs, or into the implementation details of how a method call is encoded, you will see that the name, literally, is “stringByPaddingToLength”withString:startingAtIndex:”. The first part is indeed no more important than the other parts — and we wanted a syntax that properly reflected that.

      The whole point of this new syntax is that this is a new concept of how method calls on Cocoa work. Oxygene is al about exposing the real platform (even if that means having to learn a bit to understand it) and not abstracting it and pretend what makes the platform unique doesn’t exist.

      “maybe need more mapping tables and it is more work for you”

      The point is not the work for us. The point is: as a Nougat user, you will want to consume any and all framework out there. If you find a great third party library you wanna use, written in Objective-C of course, you dont want to have us create a mapping for it. If the iOS 7 beta comes out, you don’t want to have to wait til we add support for the new APIs.

      ” if you come to problems during compiler development”

      We’re not adding the new syntax because we have problems implementing it differently. We’re adding new the new syntax because it is necessary, in order to properly support the platform to the level we want to. This is not us being lazy — quite to the contrary. There’s lots of extra thought and work that goes into this, that we could have skipped by just going the easy route. But we prefer going the proper route.

      “because we really need more stability”

      No-one is forcing you to use new language features. I don’t see how adding new functionality to the language reduces stability of your existing code. All your existing .NET and Java code will continue to compile (and you can use non-Cocoa-style methods in all your own code, on the Cocoa platform as well, of course.

  9. Unless there are named parameters some where else in the scheme, then the difference is pretty much trivial over how you describe them, and getting hung up about it might mean you’ve spent too much time, too deep into the rabbit hole. We’ve all been there.

    I must admit, however, that I am deeply troubled by the “space” seperator. It breaks the convention where running in to a new procedural name means someone forgot a ; It would make more sense to use something, ANYTHING to convey to the compiler that you intend the statements to be joined. Obviously a “.” would indicate a nested reference, a comma could mean a bracket is missing… Perhaps it is time to add something new. A :: joiner is the first thing to jump to mind. so,

    myString.stringByPaddingToLength(20)::withString(‘ ‘)::startingAtIndex(5);

    Seriously, the if I had a startingAtIndex method in my own code, you might easily compile

    myString.stringByPaddingToLength(20) withString(‘ ‘)
    startingAtIndex(5);

    into something unexpected (whitespace is whitespace, unless you’ve changed that rule and made all our lives hellish on the right hand margin) just because I forgot a ; and Mystring:stringbypaddingtolength:withstring might be a thing too…. I assume since you indicat ed full conjoined names exist to the compiler, that similar call trees can happen without a conflict (tho, I don’t speak mac or ocr, so vote in, perhaps I am being naive)

    • “I must admit, however, that I am deeply troubled by the “space” separator” — there’s no space separator. Whitespace in Pascal is entire optional (except between keywords and identifiers, of course.

      “It breaks the convention where running in to a new procedural name means someone forgot a” — i didn’t realize there were conventions for what broken code means ;)

      your same argument could be made for just about any code construct. improper code will, pretty much by definition, be ambiguous.

  10. Hello Marc, i was reading this information about your product (NOUGAT) and i very excited. I know that there are three products oxygene : for .net / Java / y cocoa (nougat). I have some doubts about. because i imaging that all your products use Visual studio xxxxx. I think that you can help me. If i have some components from other companies like (www.devexpress.com) in Visual studio ¿ can i use this components in oxygene for .net, oxygene for java, nougat ? ¿ or i can use the components that comes with oxygene? I am sorry but i dont use Vs and i woul like to know this bebore to test / try / purchase this products.

    In the other hand, congratulations, i think that you have a great product.

    • Antonio,

      .NET, Java and Cocoa are pretty different frameworks, so third party components for .NET will not work on any of the other platforms (unless the vendor explicitly created them to work with Oxygene in such a scenario). They will work with Oxygene for .NET only.

  11. Wow Marc,
    that looks bloody amazing! :O
    I never managed to force myself long enough to use Objective-C to like it.

    Always looked like some not-thought-through pre compiler that some High school teacher fiddled together with some Smalltalk thrown in for OOP.
    I’d really like to take Nougat and Cocoa for a spin once it works in Monodevelop or XCode.

    Is Oxygene free of Embarcadero? Beta, Activation etc

    Cheers,
    Robert

    • Thanx! me, personally, i like Objective-C. but i’m still really excited about Nougat ;)

      “Is Oxygene free of Embarcadero? Beta, Activation etc” when purchased thru us, yes.

  12. Hi Marc

    I have been working with Pascal last 20 years. I was started with Turbo Pascal 3.0 for DOS.
    When I look Oxygene and all that platforms that you are going to support I feel spirit of Delphi again,
    What I can’t say when I look XE3 :(

    Is Nougat based on Free Pascal Compiler for ARM ?

    Best Regards

    Piko

    • “Is Nougat based on Free Pascal Compiler for ARM ?” — no, Nougat uses our own Oxygene compiler and the Oxygene language. It is not based on or using any part of FPC.