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