Paradigm | object-oriented |
---|---|
Developer | RemObjects Software |
First appeared | 2005[1] |
Platform | Common Language Infrastructure, Java, Cocoa, CPU-Native, Windows 32/64 bit, Linux 32/64 bit, WebAssembly |
License | Trialware |
Website | elementscompiler |
Influenced by | |
Delphi's Object Pascal, C# |
Oxygene (formerly known as Chrome) is a programming language developed by RemObjects Software for Microsoft's Common Language Infrastructure, the Java Platform and Cocoa. Oxygene is based on Delphi's Object Pascal, but also has influences from C#, Eiffel, Java, F# and other languages.
Compared to the now deprecated Delphi.NET, Oxygene does not emphasize total backward compatibility, but is designed to be a "reinvention" of the language, be a good citizen on the managed development platforms, and leverage all the features and technologies provided by the .NET and Java runtimes.
Oxygene is a commercial product and offers full integration into Microsoft's Visual Studio IDE on Windows, and its own IDE called Fire for use on macOS. Oxygene is one of six languages supported by the underlying Elements Compiler toolchain, next to C#, Swift, Java, Go and Mercury (based on Visual Basic (.NET)).
From 2008 to 2012, RemObjects Software licensed its compiler and IDE technology to Embarcadero to be used as the backend compiler in their Embarcadero Prism product. [2] Starting in the Fall of 2011, Oxygene became available in two separate editions, with the second edition adding support for the Java and Android runtimes. Starting with the release of XE4, Embarcadero Prism is no longer part of the RAD Studio SKU. Numerous support and upgrade paths for Prism customers exist to migrate to Oxygene. [3] As of 2016, there is only one edition of Oxygene, which allows development on Windows or macOS, and which can create executables for Windows, Linux, WebAssembly .NET, iOS, Android, Java and macOS.
The Oxygene language has its origins in Object Pascal in general and Delphi in particular, but was designed to reflect the guidelines of .NET programming and to create fully CLR-compliant assemblies. Therefore, some minor language features known from Object Pascal – Delphi have been dropped or revised, while many new and more modern features, such as Generics or Sequences and Queries have been added to the language.
Oxygene is an Object-oriented programming language. Thus, it uses classes, which can hold data and execute code, to design programs.[ clarification needed ] Classes are "prototypes" for objects, like the idea of an apple is the prototype for the apple one can actually buy in a shop. It is known that an apple has a colour, and that it can be peeled: those are the data and executable "code" for the apple class.
Oxygene provides language-level support for some features of parallel programming. The goal is to use all cores or processors of a computer to improve performance. To reach this goal, tasks must be distributed among several threads. The .NET Framework's ThreadPool
class offered a way to efficiently work with several threads. The Task Parallel Library (TPL) was introduced in .NET 4.0 to provide more features for parallel programming.
Operators can be overloaded in Oxygene using the class operator
syntax:
classoperatorimplicit(i:Integer):MyClass;
Note, that for operator overloading each operator has a name, that has to be used in the operator overloading syntax, because for example "+" would not be a valid method name in Oxygene. [4]
Oxygene does not use "Units" like Delphi does, but uses .NET namespaces to organize and group types. A namespace can span multiple files (and assemblies), but one file can only contain types of one namespace. This namespace is defined at the very top of the file:
namespace ConsoleApplication1;
Oxygene files are separated into an interface and an implementation section, which is the structure known from Delphi. The interface section follows the declaration of the namespace. It contains the uses
clause, which in Oxygene imports types from other namespaces:
usesSystem.Linq;
Imported namespaces must be in the project itself or in referenced assemblies. Unlike in C#, in Oxygene alias names cannot be defined for namespaces, only for single type names (see below).
Following the uses
clause a file contains type declarations, like they are known from Delphi:
interfacetypeConsoleApp=classpublicclassmethodMain;end;
As in C#, the Main method is the entry point for every program. It can have a parameter args : Array of String
for passing command line arguments to the program.
More types can be declared without repeating the type
keyword.
The implementation of the declared methods is placed in the implementation section:
implementationclassmethodConsoleApp.Main;begin// add your own code hereConsole.WriteLine('Hello World.');end;end.
Files are always ended with end.
As a .NET language, Oxygene uses the .NET type system: There are value types (like structs) and reference types (like arrays or classes).
Although it does not introduce own "pre-defined" types, Oxygene offers more "pascalish" generic names for some of them, [5] so that for example the System.Int32
can be used as Integer
and Boolean
(System.Boolean
), Char
(System.Char
), Real
(System.Double
) join the family of pascal-typenames, too. The struct character of these types, which is part of .NET, is fully preserved.
As in all .NET languages types in Oxygene have a visibility. In Oxygene the default visibility is assembly
, which is equivalent to the internal
visibility in C#. The other possible type visibility is public
.
typeMyClass=publicclassend;
The visibility can be set for every type defined (classes, interfaces, records, ...).
An alias name can be defined for types, which can be used locally or in other Oxygene assemblies.
typeIntList=publicList<Integer>;//visible in other Oxygene-assembliesSecretEnumerable=IEnumerable<String>;//not visible in other assemblies
Public type aliases won't be visible for other languages.
Records are what .NET structs are called in Oxygene. They are declared just like classes, but with the record
keyword:
typeMyRecord=recordmethodFoo;end;
As they're just .NET structs, records can have fields, methods and properties, but do not have inheritance and cannot implement interfaces.
Interfaces are a very important concept in the .NET world, the framework itself makes heavy use of them. Interfaces are the specification of a small set of methods, properties and events a class has to implement when implementing the interface. For example, the interface IEnumerable<T>
specifies the GetEnumerator
method which is used to iterate over sequences.
Interfaces are declared just like classes:
typeMyInterface=publicinterfacemethodMakeItSo:IEnumerable;propertyBar:Stringreadwrite;end;
Please notice, that for properties the getter and setter are not explicitly specified.
Delegates define signatures for methods, so that these methods can be passed in parameters (e.g. callbacks) or stored in variables, etc. They're the type-safe NET equivalent to function pointers. They're also used in events. When assigning a method to a delegate, one has to use the @
operator, so the compiler knows, that one doesn't want to call the method but just assign it.
Oxygene can create anonymous delegates; for example methods can be passed to the Invoke
method of a control without declaring the delegate:
methodMainForm.MainForm_Load(sender:System.Object;e:System.EventArgs);beginInvoke(@DoSomething);end;
An anonymous delegate with the signature of the method DoSomething
will be created by the compiler.
Oxygene supports polymorphic delegates, which means, that delegates which have parameters of descending types are assignment compatible. Assume two classes MyClass
and MyClassEx = class(MyClass)
, then in the following code BlubbEx
is assignment compatible to Blubb
.
typedelegateBlubb(sender:Object;m:MyClass);delegateBlubbEx(sender:Object;mx:MyClassEx);
Fields can be used to delegate the implementation of an interface, if the type they're of implements this interface:
Implementor=publicclass(IMyInterface)// ... implement interface ...end;MyClass=publicclass(IMyInterface)fSomeImplementor:Implementor;publicimplementsIMyInterface;//takes care of implementing the interfaceend;
In this example the compiler will create public methods and properties in MyClass
, which call the methods / properties of fSomeImplementor
, to implement the members of IMyInterface. This can be used to provide mixin-like functionality. [6]
Anonymous methods are implemented inside other methods. They are not accessible outside of the method unless stored inside a delegate field. Anonymous methods can use the local variables of the method they're implemented in and the fields of the class they belong to.
Anonymous methods are especially useful when working with code that is supposed to be executed in a GUI thread, which is done in .NET by passing a method do the Invoke
method (Control.Invoke
in WinForms, Dispatcher.Invoke
in WPF):
methodWindow1.PredictNearFuture;//declared as async in the interfacebegin// ... Calculate result here, store in variable "theFuture"Dispatcher.Invoke(DispatcherPriority.ApplicationIdle,method;begintheFutureTextBox.Text:=theFuture;end);end;
Anonymous methods can have parameters, too:
methodWindow1.PredictNearFuture;//declared as async in the interfacebegin// ... Calculate result here, store in variable "theFuture"Dispatcher.Invoke(DispatcherPriority.ApplicationIdle,method(aFuture:String);begintheFutureTextBox.Text:=aFuture;end,theFuture);end;
Both source codes use anonymous delegates.
Property notification is used mainly for data binding, when the GUI has to know when the value of a property changes. The .NET framework provides the interfaces INotifyPropertyChanged
and INotifyPropertyChanging
(in .NET 3.5) for this purpose. These interfaces define events which must be fired when a property is changed / was changed.
Oxygene provides the notify
modifier, which can be used on properties. If this modifier is used, the compiler will add the interfaces to the class, implement them and create code to raise the events when the property changes / was changed.
propertyFoo:StringreadfFoowriteSetFoo;notify;propertyBar:String;notify'Blubb';//will notify that property "Blubb" was changed instead of "Bar"
The modifier can be used on properties which have a setter method. The code to raise the events will then be added to this method during compile time.
namespaceHelloWorld;interfacetypeHelloClass=classpublicclassmethodMain;end;implementationclassmethodHelloClass.Main;beginwriteLn('Hello World!');end;end.
namespaceGenericContainer;interfacetypeTestApp=classpublicclassmethodMain;end;Person=classpublicpropertyFirstName:String;propertyLastName:String;end;implementationusesSystem.Collections.Generic;classmethodTestApp.Main;beginvarmyList:=newList<Person>;//type inferencemyList.Add(newPerson(FirstName:='John',LastName:='Doe'));myList.Add(newPerson(FirstName:='Jane',LastName:='Doe'));myList.Add(newPerson(FirstName:='James',LastName:='Doe'));Console.WriteLine(myList[1].FirstName);//No casting neededConsole.ReadLine;end;end.
namespaceGenericMethodTest;interfacetypeGenericMethodTest=staticclasspublicclassmethodMain;privateclassmethodSwap<T>(varleft,right:T);classmethodDoSwap<T>(left,right:T);end;implementationclassmethodGenericMethodTest.DoSwap<T>(left,right:T);beginvara:=left;varb:=right;Console.WriteLine('Type: {0}',typeof(T));Console.WriteLine('-> a = {0}, b = {1}',a,b);Swap<T>(vara,varb);Console.WriteLine('-> a = {0}, b = {1}',a,b);end;classmethodGenericMethodTest.Main;beginvara:=23;// type inferencevarb:=15;DoSwap<Integer>(a,b);// no downcasting to Object in this method.varaa:='abc';// type inferencevarbb:='def';DoSwap<String>(aa,bb);// no downcasting to Object in this method.DoSwap(1.1,1.2);// type inference for generic parametersConsole.ReadLine();end;classmethodGenericMethodTest.Swap<T>(varleft,right:T);beginvartemp:=left;left:=right;right:=temp;end;end.
Program output:
Type: System.Int32 -> a = 23, b = 15 -> a = 15, b = 23 Type: System.String -> a = abc, b = def -> a = def, b = abc Type: System.Double -> a = 1,1, b = 1,2 -> a = 1,2, b = 1,1
unit
: Replaced with the namespace keyword. Since Oxygene doesn't compile per-file but per-project, it does not depend on the name of the file. Instead the unit or namespace keyword is used to denote the default namespace that all types are defined in for that fileprocedure
and function
: method
is the preferred keyword, though procedure
and function
still work.overload
: In Oxygene all methods are overloaded by default, so no special keyword is needed for this.Create()
: This constructor call has been replaced by the new
keyword. It can still be enabled in the project options
for legacy reasonsstring
: Characters in strings are zero-based and read-only. Strings can have nil values, so testing against empty string is not always sufficient.Some people[ who? ] would like to port their Win32 Delphi code to Oxygene without making major changes. This is not possible because while Oxygene looks like Delphi, there are enough changes so as to make it incompatible for a simple recompile. While the name gives it the appearance of another version of Delphi, that is not completely true. [7]
On top of the language difference, the Visual Component Library framework is not available in Oxygene. [8] This makes porting even more difficult because classic Delphi code relies heavily on the VCL.
Dylan is a multi-paradigm programming language that includes support for functional and object-oriented programming (OOP), and is dynamic and reflective while providing a programming model designed to support generating efficient machine code, including fine-grained control over dynamic and static behaviors. It was created in the early 1990s by a group led by Apple Computer.
Generic programming is a style of computer programming in which algorithms are written in terms of data types to-be-specified-later that are then instantiated when needed for specific types provided as parameters. This approach, pioneered in the programming language ML in 1973, permits writing common functions or data types that differ only in the set of types on which they operate when used, thus reducing duplicate code.
In object-oriented programming languages, a mixin is a class that contains methods for use by other classes without having to be the parent class of those other classes. How those other classes gain access to the mixin's methods depends on the language. Mixins are sometimes described as being "included" rather than "inherited".
Delphi is a general-purpose programming language and a software product that uses the Delphi dialect of the Object Pascal programming language and provides an integrated development environment (IDE) for rapid application development of desktop, mobile, web, and console software, currently developed and maintained by Embarcadero Technologies.
In computing, type introspection is the ability of a program to examine the type or properties of an object at runtime. Some programming languages possess this capability.
Object Pascal is an extension to the programming language Pascal that provides object-oriented programming (OOP) features such as classes and methods.
This article compares two programming languages: C# with Java. While the focus of this article is mainly the languages and their features, such a comparison will necessarily also consider some features of platforms and libraries.
C++/CLI is a variant of the C++ programming language, modified for Common Language Infrastructure. It has been part of Visual Studio 2005 and later, and provides interoperability with other .NET languages such as C#. Microsoft created C++/CLI to supersede Managed Extensions for C++. In December 2005, Ecma International published C++/CLI specifications as the ECMA-372 standard.
C# is a general-purpose high-level programming language supporting multiple paradigms. C# encompasses static typing, strong typing, lexically scoped, imperative, declarative, functional, generic, object-oriented (class-based), and component-oriented programming disciplines.
C# and Visual Basic (.NET) are the two main programming languages used to program on the .NET framework.
In object-oriented computer programming, an extension method is a method added to an object after the original object was compiled. The modified object is often a class, a prototype, or a type. Extension methods are features of some object-oriented programming languages. There is no syntactic difference between calling an extension method and calling a method declared in the type definition.
In object-oriented computer programming, a null object is an object with no referenced value or with defined neutral (null) behavior. The null object design pattern, which describes the uses of such objects and their behavior, was first published as "Void Value" and later in the Pattern Languages of Program Design book series as "Null Object".
This article describes the syntax of the C# programming language. The features described are compatible with .NET Framework and Mono.
Language Integrated Query is a Microsoft .NET Framework component that adds native data querying capabilities to .NET languages, originally released as a major part of .NET Framework 3.5 in 2007.
This comparison of programming languages compares how object-oriented programming languages such as C++, Java, Smalltalk, Object Pascal, Perl, Python, and others manipulate data structures.
C# 4.0 is a version of the C# programming language that was released on April 11, 2010. Microsoft released the 4.0 runtime and development environment Visual Studio 2010. The major focus of C# 4.0 is interoperability with partially or fully dynamically typed languages and frameworks, such as the Dynamic Language Runtime and COM.
Nemerle is a general-purpose, high-level, statically typed programming language designed for platforms using the Common Language Infrastructure (.NET/Mono). It offers functional, object-oriented, aspect-oriented, reflective and imperative features. It has a simple C#-like syntax and a powerful metaprogramming system.
Objective-C is a high-level general-purpose, object-oriented programming language that adds Smalltalk-style message passing (messaging) to the C programming language. Originally developed by Brad Cox and Tom Love in the early 1980s, it was selected by NeXT for its NeXTSTEP operating system. Due to Apple macOS’s direct lineage from NeXTSTEP, Objective-C was the standard language used, supported, and promoted by Apple for developing macOS and iOS applications from 1997, when Apple purchased NeXT until the introduction of the Swift language in 2014.
Smart Pascal is an Object Pascal programming language that is derived from Delphi Web Script and is adapted for Smart Mobile Studio for generating commercial JavaScript machine code. As a rapid application development (RAD) language, it contains a library of classes and components. The Smart Pascal compiler is a source-to-source compiler generating server-independent applications which are compliant with HTML5. Compiled Smart applications can be executed in a modern HTML5-capable browser. A compiled program is then typically embedded within a DIV container element or alternatively set to occupy the entire display.
PascalABC.NET is a high-level general-purpose programming language supporting multiple paradigms. PascalABC.NET is based on Delphi's Object Pascal, but also has influences from C#, Python, Kotlin, and Haskell. It is distributed both as a command-line tool for Windows, Linux and MacOS (Mono), and with an integrated development environment for Windows and Linux, including interactive debugger, IntelliSense system, form designer, code templates and code auto-formatting.