Defining Mapped Types
Although it done rarely as part of most software projects, the Elements compiler provides a syntax for declaring your own mapped types in all languages except Go. In Oxygene, the mapped
keyword is used, while both C# and Swift use __mapped
and Mercury uses MappedTo
Declaring Mapped Types in Oxygene
In Oxygene, the mapped
keyword is used in both the type declaration and the individual mapped members. In the type declaration, the phrase mapped to will indicate the underlying "real" class that is being mapped:
type
List<T> = public class mapped to ArrayList<T> ...;
Individual members can either be mapped via a shorthand syntax, right inside the type declaration, or they can provide a regular method or property body and within there use the mapped
keyword to refer to members of the underlying original type.
The inline shortcut syntax looks like the following snippet, which simply instructs the compiler to map any call to RemoveAt
to the remove
method on the real class:
method RemoveAt(index: Integer); mapped to remove(index);
An example for a regular method body that uses the mapped
keyword to call into the real class might look like this:
method List<T>.Remove(item: T);
begin
var n := mapped.IndexOf(item);
if n >= 0 then mapped.Remove(n);
end;
Declaring Mapped Types in C#, Swift, Java and Mercury
In C#, Swift and Java the __mapped
class modifier can be used in the type header to indicate that a class definition is mapped, alongside the =>
operator to indicate the concrete class that is being mapped to. Mercury uses the MappedTo
keyword, instead.
Similar to Oxygene above, the __mapped
keyword can also be used inside the member bodies to refer to members of the real type, for C#, Swift and Java. in Mercury, the MyMapped
keyword serves that role.
public __mapped class MyList<T> => List<T>
{
public void Remove(T o)
{
var n = __mapped.IndexOf(o);
if (n >= 0)
__mapped.Remove(n);
}
}
public __mapped class MyList<T> => List<T> {
func Remove(o: T) {
let n = __mapped.IndexOf(o)
if n >= 0 {
__mapped.Remove(n)
}
}
}
public __mapped class MyList<T> => List<T>
{
public void Remove(T o)
{
var n = __mapped.IndexOf(o);
if (n >= 0)
__mapped.Remove(n);
}
}
Public Class MyList<T>
MappedTo List<T>
Function Remove(o As T)
Dim n = MyMapped.IndexOf(o)
if n >= 0 Then
MyMapped.Remove(n)
End If
End Function
End Class
Note that unlike Oxygene, no shorthand syntax for mapping is provided, both because the inline nature of the C#, Swift and Mercury class structure makes that less necessary, and to keep changes/extensions to the C# standard and Swift syntax at a minimum.
Full Example
The code below shows a full example for the definition of a mapped class. More examples can be found by perusing the available Elements RTL source code.
namespace System.Collections;
interface
uses
java.util;
type
List<T> = public class mapped to ArrayList<T>
public
method Add(o: T); mapped to add(o);
method RemoveAt(i: Integer); mapped to remove(i);
method Remove(o: T);
begin
var n := mapped.IndexOf(o);
if n >= 0 then mapped.Remove(n);
end;
property Length: Integer read mapped.size;
property Item[i: Integer]: T read mapped[i] write mapped[i]; default;
end;
method List<T>.Remove(o: T);
namespace System.Collections
{
using java.util;
public __mapped class List<T> => ArrayList<T>
{
public void Add(T o) { __mapped.add(o); }
public void RemoveAt(int i) { __mapped.remove(i); }
public void Remove(T o)
{
var n = __mapped.IndexOf(o);
if (n >= 0)
__mapped.Remove(n);
}
public int Length
{
get
{
return __mapped.size;
}
}
public T this(int i)
{
get
{
return __mapped[i];
}
set
{
__mapped[i] = value;
}
}
}
}
import java.util
public __mapped class List<T> => ArrayList<T> {
public func Add(o: T) {
__mapped.add(o)
}
public func RemoveAt(i: Int) {
__mapped.remove(i)
}
public void Remove(T o) {
et n = __mapped.IndexOf(o)
if (n >= 0) {
__mapped.Remove(n)
}
}
public var Length: Int {
eturn __mapped.size
}
public subscript(i: Int) -> T {
get {
return __mapped[i]
}
set {
__mapped[i] = newValue
}
}
}
package System.Collections;
import java.util.*;
public __mapped class List<T> => ArrayList<T>
{
public void Add(T o) { __mapped.add(o); }
public void RemoveAt(int i) { __mapped.remove(i); }
public void Remove(T o)
{
var n = __mapped.IndexOf(o);
if (n >= 0)
__mapped.Remove(n);
}
public int Length { get { return __mapped.size } }
public T this(int i) { get { return __mapped[i]; } set { __mapped[i] = value; } }
}
Imports java.util
Public Cass List<T>
MappedTo ArrayList<T>
Public Funcion Add(o As T)
MyMapped.add(o)
End Function
Public Funcion RemoveAt(i: Int) {
MyMapped.remove(i)
End Function
Public Sub Remove(T o) {
Dim n = MyMapped.IndexOf(o)
If n >= 0 Then
MyMapped.Remove(n)
End If
End Sub
Public Property Length: Int {
return MyMapped.size
End Property
Public Property(i: Int) -> T {
Get
Return MyMapped[i]
End Get
Set
MyMapped[i] = Value
End Set
End Property
End Class