#ifdef, redefined

Using #ifdefs, or your language's equivalent, is a common occurrence in code, not only when writing cross-platform code. #ifdefs (or #if in C#, Swift and Iodine and {$IF} in Oxygene), let you conditionally compile different parts of your project — for example to account for APIs not available on all platforms, or for code you want to run only in debug or in release mode.

Elements 10 does away with the need for ugly #ifdef syntax by introducing a new defined() system function. With defined(), you can express conditional compilation as part of regular code flow – the compiler will take care of the rest.

That's already much nicer, right? Notice how this now flows just like regular conditional code would. But also notice how you can still use platform-specifc APIs in each section of code! That's because the compiler still takes this if clause apart, and will compile one part when targeting Cocoa, and the other when targeting Java.

Here, how to react to a given "report" object depends both on the debug/release level of the app, but also on runtime logic. In debug builds, all reports will be sent, while in release builds the level will be taken into consideration at runtime.

Swift and #defined

While defined() is a system function provided by the Elements compiler and available on all languages and platforms, we've also added a second syntax specifically for Swift that is more aligned with existing #available() and similar constructs:

So in Swift, regardless of platform, you can use #defined() and omit the quotes, e.g.:

if #defined(COCOA) && #available(iOS 11.2) {
...
}

This works the same as defined("COCOA") would, just looks more Swifty.

#if Isn't Going Away

Of course #if and {$IF} continue to be supported as well, and still have their place when conditionally defining larger scopes than an if statement can handle – such as whole methods or classes.

But you will find that inside method bodies, the new syntax allows for much more expressive and easier to read conditional compilation – not to mention better integration of compile-time conditions with runtime decisions, as seen in the samples above.

The new defined() infrastructure is just one of many, many new features for Elements 10 already available in the current builds. Check it out and let us know what you think!