Platform Differences
This page collects an overview of the few subtle differences for the Elements compiler and its languages on the different Platforms – .NET, Cocoa, Java, Android, Windows, Linux and WebAssembly).
We strive for 99% language and feature compatibility, but due to the nature of the platforms and underlying runtimes, a small handful of features will not be available on all platforms, and a few platform-specific features are provided that don't make sense on the other platforms.
The following table marks the core points of differentiation between the different Compiler Backends
Feature | Echoes (.NET) | Cooper (JVM) | Toffee (Cocoa) | Island |
---|---|---|---|---|
Lifecycle Management | GC | GC | ARC | ARG & GC* |
Pointers & Direct Memory Access | In Unsafe Mode | No | Always | Always |
Generics | Full Support | Type-Erased | Type-Erased | Full Support |
Function Pointers | No | No | Yes | Yes |
Aspects | Write & Use | Use | Use | Use |
Garbage Collection vs. ARC
Memory management on .NET, Java and Island-backed uses Garbage Collection while Cocoa uses Automatic Reference Counting, also referred to as ARC.
On Island projects targeting the Cocoa platform, both GC and ARC are used, the former for Island-native objects, and the latter for Objective-C Runtime-based Cocoa objects and Swift objects. Please refer to the Object Models topic for more details.
In most code scenarios, GC and ARC will behave pretty comparably, and code written that deals wit object references generally will look the same — i.e. will not worry about explicitly freeing object memory. There are however some subtle differences, in particular when it comes to dealing with retain cycles, which GC has no problem resolving, but that can cause leaks in ARC. Special Storage Modifier keywords ,strong
(implied by default), weak
and unretained
, are provided to help with this on the Cocoa platform (and will be ignored on .NET and Java). In C# these three keywords start with two underscores.
Also unique to ARC, a keyword is provided to manually instantiate additional auto-release pools, where needed. This is seldom the case, but might be necessary in some specific cases. The topic on ARC will go into this in more detail.
See Also
- Storage Modifier for ARC
- Auto-release Pools for ARC
- Object Models for Island/Darwin
- Automatic Reference Counting vs. Garbage Collection
Blocks (a.k.a. .NET Delegates)
Blocks types, i.e. method references (also called delegate
s), are supported on on all platforms, but there are some limitations.
The block
keyword is provided on all platforms, and synonymous with the now deprecated delegate
keyword (refer to the Blocks topic for reasons for this change).
Oxygene has support for inline block types in method or property declarations. This syntax is supported on all platforms, but limited to block signatures that match an existing
.NET Framework Action
or Func
delegate signature on .NET.
Note that on Cocoa, the function
, procedure
and method
keywords will declare C-level Function Pointers when used for block type declarations, rather than true Objective-C blocks (i.e. C's *
syntax opposed to ^
block syntax). Only the block
and delegate
keywords declare true Objective-C blocks. (On .NET and Java, all 5 keywords behave the same way.)
Since on .NET and Java it has never been recommended to use function
, procedurep
and method
for block declarations, it is recommended to consistently stick to [[block (keyword)|block]]
for cross-platform code.
Note: For RemObjects C#, this equally applies to delegate
types. Inline
delegate type declarations are permitted. On all languages, the FunctionPointer
Aspect can be applied to mark a delegate as a function (and not a block) pointer in C#.
C Runtime Heritage and Influences on Elements for Cocoa
Due to it being built on the Objective-C runtime, which itself is a true superset of standard C, Oxygene on Cocoa and Island-backed platforms gains support for a wide variety of concepts from the C language, not the least of which being access to the vast C runtime library, with printf()
and thousands of other well known functions, records and types. Due to C being inherently non-object-oriented, this means Oxygene for Cocoa provides access to non-OOP libraries and functionalities in a manner that would have been deemed "unacceptable" on the strictly-OOP .NET and Java platforms.
Examples of these are more liberal use of pointers and reference parameters, global constants and functions, and the more traditional method-less Record types.
For the purpose of cross-platform code, this is mainly irrelevant, as such code can (and should) stick to using the higher-level OOP based features and functionality.
Aspects & Custom Attributes
Custom Attributes are supported on all platforms, but are more limited in scope on Cocoa and Island. Querying for custom attributes at runtime currently relies on platform-specific APIs (provided by the platform on .NET and Java, and by libToffee on Cocoa and Island RTL), but a higher-level cross-platform abstraction is available as part of Elements RTL's Reflection APIs.
The standard attribute syntax with square brackets ([]
) in Oxygene and C#, the at symbol (@
) in Swift and Java and angle brackets (<>
) in Mercury is also supported to specify a limited range of Special Attributes defined by the compiler. These special attributes are not backed by classes.
Attributes and Aspects are not supported by the Go language.
- Special Attributes (.NET)
- Special Attributes (Cocoa)
- Special Attributes (Java)
- Special Attributes (Island)
Cirrus (Implementing Aspects)
The compiler supports applying aspects on all platforms. But Since aspects essentially run as part of the compiler, aspects can be written using in .NET (Classic and .NET Standard 2.0), no matter the target platform. Aspects can be created so that they are platform-independent and can be applied to any of the four platforms. In fact, that is the default behavior.
Miscellaneous and Minor Differences
- Boxing semantics differ between .NET, Java and Cocoa.
- Nullable Types, like boxing, have some limitations on Cocoa (namely that they support only numerical values, and no Records).
- Arrays support differs on Cocoa, with the availability of non-object Open and Static Arrays.
- As part of ARC, Storage Modifiers are supported on Cocoa only.
- Interfaces/Protocols support
optional
members, on Cocoa. - The
dynamic
type is only supported on .NET and Cocoa, and on the latter maps toid
type and provides sightly different usage semantics. unsafe
code is not supported on Java, and all code is assumed to beunsafe
on Cocoa and Island, making the keyword ignored/unnecessary on that platform.- Generic co/contra-variance is supported on .NET only.
- Differences in [Pointer References in Oxygene for Cocoa](Pointer References in Oxygene for Cocoa).
- The
external
keyword is supported on .NET (P/Invoke) and Java (JNI), but not applicable on Cocoa. - Parallel "for" loops, parallel sequences and queryable sequences are currently only supported for .NET.
- Special Java-style exception handling extensions will be a new platform difference, once implemented.
.NET-Specific Features
- Garbage Collection, also see ARC vs GC
- Special Attributes (.NET)
- Parallel For Loops in Oxygene
- Parallel Sequences in Oxygene
- P/Invoke and the
external
keyword unsafe
code- BigInteger
- implementing Aspects with Cirrus
Cocoa-Specific Features
- ARC & Auto-Release Pools
- Special Attributes (Cocoa)
- Storage Modifiers –
strong
,weak
andunretained
or variations of them selector()
Expressions- Constructors map to/are interchangable with
init*
Methods - Bridging via
bridge<T>()
- Optional interface/protocol members
Java-Specific Features
- Garbage Collection, also see ARC vs GC
- Special Attributes (Java)
- Java Native Interface (JNI) and the
external
keyword - Unsigned Integers are not supported by the Java runtime, but get emulated by the compiler
Island-Specific Features
- Garbage Collection, also see ARC vs GC
- ARC & Auto-Release Pools
- Life-Time Strategies and the
lifetimestrategy
keyword in Oxygene - Special Attributes (Island)