Oxygene Is A Powerful General Purpose Programming Language
Oxygene Is A Powerful General Purpose Programming Language
Language Features
Take a closer look at the features that make up the Oxygene language:
T H E B A S I C S
This section covers some of the basic constructs that
make up the Oxygene language. If you are familiar with Object Oriented
software development, you won't find a lot of mind-blowing things here,
but you will get a basic introduction to the Object Pascal syntax. Even if you
are familiar with Pascal already, you might find some interesting syntax
variations and details.
Classes & Interfaces | Types | Methods, Statements &
Expressions | Namespaces
T H E M O D E R N
This section covers more modern OOP constructs as
available in Oxygene. Most of these might be familiar to you from other
modern languages, such as C# or Java, and this section will show you how
these concepts apply to Oxygene specifically.
Generics | Sequences & Queries | Tuples
T H E S P E C I A L
This section dives into some of the less mainstream
features of the Oxygene language. Many of these are inspired by features
from other academic or more specialized languages, and you will learn how
Oxygene brings these features into Pascal and makes them accessible for
modern application development.
Class Contracts | Duck Typing | Mapped Types | Cirrus
T H E A W E S O M E
Last, but certainly not least, this section takes a
look at some of the awesome features that make Oxygene unique. Many of
these features exist only in the Oxygene language, or are uniquely applied
to Oxygene in ways beyond what other languages offer.
Nullable Types & Expressions | Futures & Parallelism
T H E L I T T L E T H I N G S
Oxygene contains a myriad of small little
details that make writing code a joy. Individually, none of these constitute
major features, but they give the language the finishing touches. After all,
it's the little things that count.
What is Oxygene?
Oxygene is a commercial programming language developed
by RemObjects Software for the Microsoft .NET Framework. In 2008,
RemObjects licensed its Oxygene compiler and IDE technology
to Embarcadero to be used in its Delphi Prism product. You may
recall that in 2008 Embarcadero purchased CodeGear, the software
development tools division of Borland.
Oxygene Design
The Oxygene programming language originated from Delphi and Object Pascal, but was
designed to reflect the .NET programming paradigm and produce CLR-compliant
assemblies. Thus, Oxygene does not support all the language features from Object
Pascal and Delphi, but it does leverage all the features and technologies provided by
the .NET runtime.
New language features in Oxygene 3.0 include support for parallel programming,
property notifications for the Model/View/Controller design pattern, nullable
expressions, and improved QA analysis tools.
Oxygene History
RemObjects software came from a Delphi background. In 2002, RemObjects sought to
expand its developer libraries into the Microsoft .NET Framework, so naturally they
considered Delphi for .NET for the job. According to the RemObjects Chief Architect, it
seemed like “Borland had developed Delphi for .NET with one main goal in mind: to
hide the transition from Win32 to .NET from the developers.” As a result, Delphi
for .NET “introduced many Delphi-isms and Win32-isms that felt out of place and
awkward in the .NET world.” (source)
As a result, RemObjects chose to use C# for its .NET projects instead of Delphi. But its
engineers really missed the Pascal syntax, so eventually RemObjects decided to invent
a language for .NET with the Pascal syntax, and Oxygene was born. Its code name was
Adrenochrome, which was later shortened to Chrome, and eventually renamed to
Oxygene.
end.
Oxygene (programming language)
From Bauman National Library
This page was last modified on 1 June 2016, at 17:00.
Oxygene
Website www.elementscompiler.com
Influenced by
Object Pascal, C#
Contents
[hide]
1 History
2 Design
3 Features
History
RemObjects software came from a Delphi background[2]. In 2002, RemObjects sought to expand its
developer libraries into the Microsoft .NET Framework, so naturally they considered Delphi for .NET for
the job. According to the RemObjects Chief Architect, it seemed like “Borland had developed Delphi
for .NET with one main goal in mind: to hide the transition from Win32 to .NET from the developers.” As a
result, Delphi for .NET “introduced many Delphi-isms and Win32-isms that felt out of place and awkward
in the .NET world.”
As a result, RemObjects chose to use C# for its .NET projects instead of Delphi. But its engineers really
missed the Pascal syntax, so eventually RemObjects decided to invent a language for .NET with the
Pascal syntax, and Oxygene was born. Its code name was Adrenochrome, which was later shortened to
Chrome, and eventually renamed to Oxygene.
Design
The Oxygene programming language originated from Delphi and Object Pascal, but was designed to
reflect the .NET programming paradigm and produce CLR-compliant assemblies. Thus, Oxygene does
not support all the language features from Object Pascal and Delphi, but it does leverage all the features
and technologies provided by the .NET runtime[2].
New language features in Oxygene 3.0 include support for parallel programming, property notifications for
the Model/View/Controller design pattern, nullable expressions, and improved QA analysis tools.
Features
Oxygene is a fully object oriented language that lets developers write code that runs on the .NET/Mono,
Java/Android or Objective-C Runtime Environments, respectively. It is based around and builds on the
language structures of Pascal and Object Pascal[3].
Oxygene generates code that uses Garbage Collection (GC) on the .NET and Java runtimes and
Automatic Reference Counting (ARC) on the Objective-C runtime. This means that regardless of platform,
the management of object life times is taken care of without explicit code needed from the developer,
although the exact underlying semantics may differ slightly.
Program structure
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:
uses
System.Linq;
Imported namespaces have to 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:
interface
type
ConsoleApp = class
public
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:
implementation
begin
Console.WriteLine('Hello World.');
end;
end.
Classes
As an object oriented language, most code written in Oxygene lives in "Classes". Classes are an
amalgamation of data and related functionality, and can consist of fields, methods, properties and —
on .NET — multicast events.
Oxygene classes support all features familiar from other modern development languages: inheritance
allows classes to descend from one another, extend each other, and be used polymorphically. This is
extended by support for interfaces, which allow unrelated classes to implement common well-defined sets
of APIs to be used in a consistent manner. Of course, classes can be abstract (i.e. need to be inherited
from to become useful) and sealed (i.e. prohibited from being extended further).
type
MyBetterButton = class(Button)
end;
Class members, such as methods, properties and events, can have different visibility scopes, controlling
how they can be accessed from within the class or externally from other classes. Properties can have
different visibility scopes for read and write access, respectively. Members can be marked virtual so they
can be overridden in descendant classes — one of the cornerstones of polymorphism.
In addition to members, classes can also define invariants that will help with proving the consistency of
the class during runtime. Invariants are boolean statements that describe the valid state of each object,
and if present, the compiler will automatically ensure that invariants will be validated whenever necessary,
detecting invalid object state and programing errors that cause it early on. Invariants are one half of
Oxygene's implementation of Class Contracts.
Individual instances of classes are referred to as "Objects".
Methods
The bulk of code in a project exists within the bodies of a class's methods. A method body is surrounded
with the "begin" and "end" keywords, and can contain a list of statements, separated by semicolons, that
will be executed in sequence when the method is called.
In addition to simple statements, such as calls to other methods, assignments or arithmetic expressions,
Oxygene of course provides a wide range of code flow statements to express application logic, such as
for/to, for/each, while, repeat/until and infinite loops, "if" and "case" statements, assignments and of
course method calls.
Expressions are a certain subset of statements that are considered to have a value that can be reused or
built upon. For example, in the following to statements:
var x := 5 + 9;
(5 + 9).ToString;
the "5 + 9" statement is an expression that applies the "+" operator to the values "5" and "9". The result of
that expression can be used further, for example to be assigned to the variable "x", or to have the
"ToString" method called upon.
Not all statements are expressions, so the following code is not valid:
var y := Console.WriteLine("Hello");
Other Types
Oxygene also supports a range of intrinsic types that are not classes in the strictest sense — although
instances of them can be treated as objects. These include "Enums" to define a group of distinct related
values, "Arrays" that contain a numbered list of elements accessible by index, and "Sequences" which
similarly contain a list of elements that can be accessed sequentially but not by index.
Oxygene is a strongly-typed language by design, meaning that type safety is enforced and method calls
are validated as compile-time. At the same time, it provides powerful features that let code break out of
the confines of the safe type system, if needed. These include duck typing and soft interfaces which allow
compatible objects to be used polymorphically without having a common ancestor, and the dynamic type,
which allows arbitrary (checked at runtime) method and property calls on objects whose type is not known
at compile time.
Namespaces
Oxygene identifies types by a unique combination of their name, and an (optional) namespace prefix. By
default, a type's namespace is defined by the global namespace name declared for the file that the type is
defined in, but individual type declaration can override the namespace by providing what is referred to as
a "fully qualified type name":
type
When referring to (i.e. using) types, their names can be specified using the full name, or the short name
can be used if the type exists in the "current" namespace or a namespace referenced in the "uses"
clause:
namespace Foo;
uses Bar;
Generics
Generics are a core feature of modern languages today, and Oxygene provides full support for them on
both .NET and Java.Simply put, generics allow the developer to declare classes that make strongly-typed
use of other types, without knowing the exact type at the time of implementation.
A common example is a List class, which can be used in different incarnations to hold different types —
for example a list of Integers, a list of strings or a list of custom types called Foo.
Rather than implementing IntegerList, StringList and FooList separately (duplicating a lot of code) or
falling back to a plain list of untyped "Objects" (which loses type safety and requires unnecessary casts
when accessing elements) a generic List can be defined, where T is a placeholder for any given
type.Throughout the implementation of List, the name "T" can be used to refer to "the type that this list
works on", without ever having to become concrete. (But of course generics can impose limitations on
their types, for example an OrderedList would specify that its members need to implement an interface
that makes them sortable.)
Users of the class can instantiate concrete versions of a generic simply by specifying an actual type
name, e.g.:
and when working with these lists in "x" and "y", they can be accessed with the safe knowledge that all
members of the list are Int32s or Strings, respectively.
Sequences & Queries
Sequences are a special type in the language and can be thought of as a collection of elements, similar to
an array.
In contrast to arrays, sequences do not imply a specific form of data storage, but can represent any
collection of elements that is accessible in a specific order. This could be an array (and as a matter of
fact, all arrays can be treated as a sequence) or a different data store, such as a linked list, a binary tree
or a custom collection implementation.
Sequences can also represent non-static data that is retrieved or generated on the fly, as the sequence is
enumerated. For example, one could implement a sequence that calculates all digits of Pi, or retrieves
RSS headlines downloaded from a server.In Oxygene, sequences are represented by the "sequence of"
keyword (analogous to the "array of" syntax), so a variable holding a sequence of strings would be
defined as follows:
A variable defined like this would then be capable of referring to any kind of sequence — be it an array, a
standard generic List collection class or a custom sequence implementation.The main power of
sequences arises when used in combination with Query Expressions, also known as LINQ.Query
Expressions provide an SQL-like syntax to perform actions or apply filters to sequence types — for
example to narrow down a sequence to all elements with a particular property value, or to sort a
sequence using a property:
Tuples
Oxygene 5.2 also extends the Oxygene language with support for native tuple types for both .NET and
Java. Tuples are a new core type in the language, like arrays or sequences, and are designed to hold a
set of specific typed objects.
Tuples make it easy to pass around groups of values (for example a String and an Integer), store them in
arrays or collections, even return multiple values from function calls.
You can define a tuple variable such as:
and you can access individual members of the tuple using the strongly typed [] indexer:
var s := t[0];
var i := t[1];
where each index is strongly typed, i.e. the compiler knows that t[1] is an Int32 type. You can also
declare tuple literals using the new () syntax:
<syntaxhighligh tlang="oxygene"> t := ('Holla', 23, false); </syntaxhighlight>
and even assign tuples back to individual values:
var s: String;
var i: Int32;
(s, i) := MyTupleMethod();