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 four languages. In Oxygene, the mapped keyword is used, while both C# and Swift use __mapped.

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# and Swift

Both C# and Swift use the __mapped class modifier 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.

Similar to Oxygene above, the __mapped keyword can also be used inside the member bodies to refer to members of the real type.

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)
    }
  }
}

Note that unlike Oxygene, no shorthand syntax for mapping is provided, both because the inline nature of the C# and Swift 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 Sugar 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);
    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);
begin
  var n := mapped.IndexOf(o);
  if n >= 0 then mapped.Remove(n);
end;
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) {
      let n = __mapped.IndexOf(o)
      if (n >= 0) {
        __mapped.Remove(n);
      }
    }
    public var Length: Int {
      return __mapped.size
    }
    public subscript(i: Int) -> T {
      get {
        return mapped[i]
      }
      set {
        mapped[i] = newValue
      }
    }
}