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