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