====== is ======
is beschreibt eine Ableitung. Es entsteht ein gleichwertiger Typ mit gleichnamiger Variable.
intdi is implicit int; // intd-erived implicit
intdi : construct(4); // Variable intdi wird ein Objekt zugewiesen, dass mit intdi::construct( int ) erstellt wird.
intdi : intdi\(4); // " " "
intdi : 5 as inetdi\; // " " "
intdi : 4; // ok, ist implicit.
func1 is code( intdi ) = intd; // Es kommt eine Variable, die den Typ intdi\ haben muss und die lokal intdi genant wird.
func2 is code( val as intdi ) = val; // Das gleiche in Grün.
print func1( intdi )$; // okay
print func1( 4 )$; // okay, ist implicit
intde is int; // intd-erived explicit
intde : construct(4); // Variable intde wird ein Objekt zugewiesen, dass mit intde::construct( int ) erstellt wird.
intde : intde\(4); // " " "
intde : 5 as inetde\; // " " "
intde : 4; // nopes
print func1( intde )$; // okay
print func1( 4 )$; // nopes
print func1( 4 to intde )$; // nopes
print func1( 4 as intde )$; // ok
derived is intde\; // derived ist von intde abgeleitet
delete derived::operator +( lhs is derived, rhs is derived );
new derived::operator = ( val as int )
{
.int.value = val; // this.int.value (entspricht this->Int::Value), ohne Mehrfachableitung geht auch .value, da .value im Namensraum von "derived" liegt.
}
====== as ======
as versucht aus einem Objekt ein anderes Objekt zu erzeugen. Entweder durch Rufen des operator , anschließend durch expliten Rufen des Konstruktors( ).
====== Ideen ======
Man könnte "is implicit" zum Standard machen und "is" zu "wraps" und via construct vorgeben, welche Operatoren/Methoden vom übergeordneten Typ übernommen werden
index wraps int construct { ++, --, :, copy, move, default(0) };
====== decl ======
decl deklariert einen Identifier nur.
add decl code( int, int ) as int;
...
add( int a, int b ) = a+b;
====== is, has, contains ======
is/has regelt die Beschreibbarkeit durch den Basistyp, implicit/explicit die konvertiertbarkeit zur Basis.
===== is =====
...leitet einen Typen 1:1 ab, alle Methoden, operatoren werden geforwarded.
x is implicit int;
x ist damit ein Typ, der einen construct( int ), operator = hat und damit initialisiert werden kann.
x kann an Funktionen übergeben werden, die ein int verlangen. x enthält einen operator as int.
x is [explicit] int;
x ist ein Typ, der keinen impliziten construct( int ), operator =(int) hat muss explizit initialisiert werden: x is int(5); oder x : 5 as x;
x kann nicht an Funktionen übergeben werden, die ein int verlangen. x enthält keinen operator as int.
===== has =====
...leitet einen Typen 1:1 ab, alle Methoden, operatoren werden geforwarded.
x has implicit int;
x ist damit ein gewrappter Typ, der einen construct( int ), operator = hat und damit initialisiert werden kann.
x kann an Funktionen übergeben werden, die ein int verlangen. x enthält einen operator as int.
x has [explicit] int;
x ist damit ein gewrappter Typ, der keinen construct( int ), operator = hat und damit mit Hilfe eines Casts (oder gleichen Typens) initialisiert und beschrieben werden muss: x : x(5);
x ist ein Typ, der ein construct( int ) hat und damit initialisiert werden kann. explicit int wird nicht automatisch auf int gecastet. operator as int fehlt.
Um x an Funktionen zu übergeben, die ein int erwarten, muss x explizit gecastet werden: func( x as int ).
Übergabe von zwei per has abgeleiteten Typen:
Source has Point;
Target has Point;
other is Point;
another is implicit Point;
Target : Source; // geht nicht Target erwartet nur Target
Target : Point( Source ); // geht nicht, Target lässt sich nicht mit Point beschreiben.
Target : Target( Source ); // Ok, Es wird ein temporäres Target erzeugt, welches auf Target geschrieben werden kann.
Target : cast Source; // Ok, Target erlaubt Point. Source wird erlaubt, sich auf Point abzubilden.
Target : other; // Nopes
Target : cast other; // Nopes: Kein Target::operator : (other), über cast nur ein operator : (Point). other ist nicht implicit Point;
Target : cast another; // Okay, Point als eingabe erlaubt, another ist implicit Point.
Target : cast other as Point; // other wird zum Point, cast erlaubt Target einen Point zuzuweisen.
other : another; // ok, another ist implicit Point;
another : other; // Nopes, other muss explicit zum Point gemacht werden
another : other as Point; // ok
another : cast Point; // ok
Eine Variable die "implicit is" von einem "explicit has" abgeleitet ist, kann ohne Konvertierung mit der "explicit has" Variable verwandt werden.
===== constant value =====
Eine Konstante erhält den gleichen Typen wie die Zuweisung. Das entspricht einem "implicit is".
===== contains =====
baut ein Record auf.
Point contains
{
x, y, z has double;
};
===== Kombinationen =====
Segmentation has uint;
Length has double;
Pi is implicit Length( 3.1415 );
Angle has Length;
/// Definition mit globalen Typen x, y, z;
// x, y, z has double;
// Point has x, y, z;
Vector has
{
x, y, z is double;
+ in (Vector) := forward x, y, z; // Entspricht construct( .x+Vector.x, .y+Vector.y, .z+Vector.z );
};
Point has
{
x, y, z is double; // Definiert Point::x, Point::y, Point::z;
+ in( Vector ) commutable :=
{
return Point( .x + Vector.x as x // .x + .x kann den Typ Point::x halten. Point::x + Vector::x ruft aber +(double, double) auf, es kommt ein double zurück. Das as x ist nicht nötig, da x ja per is abgeleitet ist, so wird aber eindeutig zugeordnet.
, .y + Vector.y as y
, .z + Vector.z as z );
};
+ in( Point ) = delete;
};
Circle
has Point
contains
{
Radius has implicit Length;
position is method( Length ) as Point
{
circumference = .Radius * Pi;
angle = ( Length % circumference ) / .Radius) as Radial;
vector = angle as Direction * Radius;
return this as Point + vector;
}
};
====== siehe auch ======
[[to]]