====== 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]]