A Sather programozási nyelv

Generic



Satherben a generic nem különálló nyelvi elem, hanem a típus (osztály) általánosításának eredménye (paraméteres osztály, illetve típus). Minden osztálynak lehetnek különféle típusú paraméterei, melyek tulajdonképpen később megadott osztály paramétereknek foglalnak helyet, azáltal írhatunk általános (generic) kódot, melyet majd több típussal példányosítva is felhasználhatunk.

A Sather típuskövetkeztetési mechanizmusának köszönhetően generic osztály implicit is példányosítható, nem kell feltétlenül új osztályt létrehozni. Tekintsünk például egy generikusan megvalósított pair osztályt:

class PAIR{T1,T2} is   readonly attr first:T1;   readonly attr second:T2;   create(a_first:T1, a_second:T2):SAME is     res ::= new;     res.first := a_first;     res.second := a_second;     return res;   end; end;   -- ezután konkrét paraméterekkel létrehozhatjuk az osztály egy példányát: t ::= #PAIR{INT,STR}(5,"this");

Tömbök: Satherben a tömbök és minden más befoglaló típus paraméteres típus. Tömbelem elérésre a más ismert operátor megfeleltetés eszközével lehetséges. Azaz a ‘[]’ operátor az ’aset’ függvényre képződik le. Tömböt legegyszerűbben az ARRAY{T} könyvtári osztályból való példányosítással hozhatunk létre.

Nincs külön lehetőség többdimenziós tömbök készítésére, hiszen ugyanaz a hatás elérhető tömböket tartalmazó tömbökkel. Például:

a:ARRAY{ARRAY{INT}} := ||1,2,3|,|3,4,5|,|5,6,7||;

Típusparaméterek megszorításai

Összetett paraméteres osztályoknál lehetőség van a paraméter lehetséges értékeit korlátozni.

Például készítsünk nyilvántartásokat külön a dolgozók csoportjairól:

abstract class $EMPLOYEE is   name:STR;   id:INT; end;   class EMPLOYEE_REGISTER{ETP > $EMPLOYEE} is   private attr emps:LIST{ETP};             -- dolgozók listája   create:SAME is                           -- konstruktor     res ::= new;     res.emps := #;     return res;   end;   add_employee(e:ETP) is                   -- dolgozó hozzávétele     emps.append(e);   end;   n_employees:INT is                       -- dolgozók száma     return emps.size   end;   longest_name:INT is                      -- a leghosszabb név hosszát adja     i:INT := 0;     cur_longest:INT := 0;     loop until!(i = n_employees);       employee:ETP := emps[i];       name:STR := employee.name;           -- a $EMPLOYEE típusban van ".name" rutin       if name.size < cur_longest then         cur_longest := name.size;       end;     end;     return cur_longest;   end; end;

Paraméteres absztrakt osztályok

Az osztályokhoz hasonlón az absztrakt típusok is tetszőlegesen paraméterezhetők, valamint nyilván szintén lehet paraméter megkötéseket is használni. Például:

abstract $BAR is end; abstract class $A{T > $BAR} is   foo(b:T):T; end;   class BAR > $BAR is end; a:$A(BAR);