====== template-Funktionen ====== Grundsätzlich: Eine Funktiondeklaration mit unbekannten Identifiern ist eine Template-Funktion, sofern keine Values übergeben werden. i = 4711 as int; f(x) = 2*x; // template f(x,y) = x+y; // template; f(x,i) = x+i; // template von code(int, x) f(x,1) = x+1; // fehler: x ist nicht bekannt, 1 ruft eine Funktion f(x+y) = x+y; // Fehler: x, y nicht bekannt, um x+y auszurechnen f(i) = 2*i; // Ambivalent: Funktionsaufruf, falls f(int) existiert da i bekannt ist. Entweder variable ändern oder // f(i as template) Falls f(int) nicht existiert, ist i int und daher wird hier nur f(i as int) generiert. Wozu ist das gut? twice(x) = 2*x; // ist ein Template. add(x,y) = x+y; mul(x,y) = x*y; Nun kann man sich allerdings noch festlegen, diese Beschreibung nur für Double gilt. x,y=double; twice(x) = 2*x; // ist ein Template. add(x,y) = x+y; mul(x,y) = x*y; Diese Definitionen brauchen also keine Typdeklarationen in den einzelnen Methoden mehr, sind aber keine Templates. Sollen es Templates werden, so kann man sie aus einer Menge bestimmen: x,y in { size, string }; mul(x,y) = x*y; // erzeugt bei Bedarf mul(size,size), mul(size,string), mul(string,size), mul(string,string); Da string,string nicht funktioniert, könnte man die Liste kürzen: (x,y) in { (size,string), (string,size), (size,size) }; mul(x,y) = x*y; // erzeugt bei Bedarf mul(size,size), mul(size,string), mul(string,size), mul(string,string); Eine Formulierung ''{string,str} (variationsoperator) \ {string,string}'' wäre schön. ''(x,y) = { x,y in (string, size) } \ {string, string};'' Permutation (ohne Zurücklegen ist n!) [[https://www.youtube.com/watch?v=aHeqPnTyMI0}} ====== Hidden-Skope-Blöcke ====== Ein Hidden-Scope-Block definiert einen Bereich, in dem Variablen versteckt definiert werden, ein nachfolgender Block greift damit zuerst auf den Hidden-Scope-Block zu, erst danach auf Variablen darüber. Der Hidden-Scope-Block ist nur innerhalb des nachfolgenden, in runden Klammern geschriebenen Codeblocks greifbar, während Variablen, die innerhalb des Codeblocks erzeugt werden im Scope oberhalb des Hiddenscope-Blocks angelegt werden. func is code := { // func-Scope x = 4711 as double; { // Hidden-Scope a,b = template; // unterschiedliche Typen, können aber gleich sein c is 4711; x = template \ a; // beliebiger Typ, darf aber nicht dem Typ von a entsprechen y = x; // y hat den gleichen Typ wie x }( // Außerhalb des Skopes, greift aber erst auf das Skope zu. f(x,y) as a = x+y; // impliziter Cast nach a, falls erlaubt g(x) = c++; // c wird modifziert, wandert damit aus diesem Scope heraus in func-Scope. Dort // wird aber kein Idref angelegt, so dass eine vorhandene Variable c oder eine // später definierte Variable hier keinen Konfliket auslösen. ) // Lebensende von a,b,c,x und y, die innerhalb des Hiddenscopes angelegt wurden. f ist weiterhin bekannt, die Identifier a,b,c,x,y sind wieder wie zuvor, also x ist int(4711). } // Lebensende von x und f und (hidden c) y = "Hallo Welt"; kurz: Einem Template darf direkt ein Codeblock in () folgen, die jeweilige Deklaration gilt dann als Hidden. x,y=template ( f2(x,y) = x+y; )