A típus (type) objektumok (object) halmazából áll, az objektumhoz tartozó metódusokkal együtt. A metódus hozzáférhet és megváltoztathatja az objektum állapotát. Ha egy objektumnak nincsen olyan metódusa, ami megváltoztathatja az objektum absztrakt állapotát (abstract state), azt mondjuk, hogy az objektum immutable (változtathatatlan), egyébként mutable (változtatható). Egy típus immutable/mutable ha az objektumai immutable-k/mutable-k.
A paraméterezett típus egymással kapcsolatban lévő típusok családját definiálja. Például az "array" (tömb) paraméterezhető típus definiálja az "array[int]", "array[char]", "array[array[int]]" stb. típusokat. A család minden típusához hozzájuthatunk a paraméterezett típus példányosítása során, új típus ily módon való létrehozását példányosításnak nevezzük.
A Theta-ban számos beépített és paraméterezett típus található. Ráadásul a felhasználók is definiálhatnak új absztrakt típusokat és paraméterezett típusokat.
A Theta-ban erős statikus típusellenőrzés van. A típusok típus hierarchiába vannak szervezve: egy típus különböző típusok altípusa lehet. A beépített típusok hierarchiája elég lapos, kivéve a rutin típusok bő hierarchiáját. A felhasználók definiálják a felhasználó által definiált típusok hierarchiáját. A típus hierarchia meghatározza az értékadások és a rutinhívások helyességét.
A típusleíró egy típust jelöl. Például, egy típusleíró lehet egy felsorolási típus ("int", "color"), vagy egy paraméterezett típus egy előfordulása ("array[int]", "maybe[employee]").
A beépített típusok a következők: "null", "any", "bool", "char", "int", "real", "string" és minden rutin típus. A beépített paraméterezhető típusok pedig: "array", "sequence", "vector", "record", "struct", "oneof", and "maybe".
Az "any" típusnak nincsenek metódusai, ez áll a típus-hierarchia csúcsán. Minden típus (a beépítettek és a felhasználó által definiáltak is) ennek altípusa.
A "null" típusnak egy literálja van a "nil". A "bool" típus a szokásos logikai típus, két literállal "true" és "false". Az "int" típus az egész számok, míg a "real" típus a fixpontos valós számok reprezentációja. A "char" típus a karakterek tárolására használható (általában ASCII), míg a "string" típus segítségével reprezentálhatunk karaktersorozatokat (ez is általában ASCII sztringek).
A paraméterezhető típusok "array", "vector" és "sequence", homogén gyűjtemények, melyek egymást követő egész számokkal indexeltek. Az "array" és a "vector" mutable típusok, a "vector" fix méretű, míg az "array" típusnak dinamikusan nőhet vagy csökkenhet a mérete. A "sequence" egy immutable típus. A "record" és a "struct" speciális heterogén típusok mezőnevekkel, és hozzájuk tartozó szelektorokkal. A "record" mutable típus, míg a "struct" immutable. A "oneof" egy speciális megnevezett, immutable unió típus. A "maybe" a "oneof" egy másik típusa, mely a paraméter-típus objektumait, illetve a "nil" értéket tartalmazhatja.
A rutin típusok szintén a Theta beépített típusai. A rutinok (azaz ezen típusok objektumai) a rutin specifikációk és rutin implementációk. A rutinok is objektumok, így tárolhatók adatstruktúrákban, átadhatók paraméterként, vagy visszatérési értékként.
A típusoknak 4 különböző fajtája van a Theta-ban, és mindegyiknek sajátos jelölési formája van. Ezeket a formákat magyarázzuk meg a következő részekben. Típus jelöléseket szintén definiálhatunk egyenlőségekkel is.
Sima típusokat nem paraméterezett típus specifikációval definiálhatunk. Ide tartozik az összes felhasználó által definiált nem paraméteres típus, és néhány beépített típus. A egyszerű típusokat a nevükkel nevezzük meg:
<simple_type_desig> -> <idn> | 'null' | 'bool' | 'char' | 'int' | 'real' | 'string' | 'any'
A paraméterezett típus egy vagy több típus-paraméterrel rendelkezik.
A típus-jelölés az ilyen típusnál azt jelenti, hogy a
mindegyik típus-paraméterbe aktuális típusokat helyettesítünk be:
<parm_type_desig> -> <parm_type> "[" <type_list> "]"
ahol
<parm_type> -> <idn> | array | sequence | vector | maybe
<type_list> -> <type_designator> ["," <type_designator>]*
A paraméterezett típus specifikációja ott használható, ahol a
megkövetelt kikötések azok, hogy az aktuális paramétereknek
meghatározott (bizonyos) metódusokkal rendelkezniük kell. A
paraméterezett típus egy szemléltetése (egy bemutatása) megengedett, ha
helyes számú aktuális paraméterrel rendelkezik, és az aktuális
paraméterek teljesítik az ottani kikötések megszorításait. Például.
nézzünk meg egy felhasználó által definiált paraméterezett típust a
"set[T]"-t. Mivelhogy a halmaz nem tartalmazhat kétszeresen egy elemet,
ezért a "set" specifikációját
akkor engedélyezi, ha az argumentum típus rendelkezik egy egyenlőség
(egyenlőséget vizsgáló) metódussal (amivel az ilyen kettősség
felismerhető):
set = type [T] where T has equal: proc (T) returns (bool)
Itt van néhány példával való szemléltetése a "set"-nek:
A harmadik példa nem megengedett, mert nem megfelelő számú paramétert helyettesítettünk be. Az utolsó példa csak akkor megengedett, ha az "employee" típus rendelkezik egy "equal" (egyenlőséget vizsgáló) metódussal. Ha nem rendelkezik, akkor fordítás hibával áll le.
Egy paraméterezett típus néhány metódusa esetleg elhelyezhet kiegészítő megszorításokat egy paraméterre, ahol ezeket saját kikötésiként birtokolja. Az ilyen metódus tetszés szerinti (nem kötelező): ha egy példa (szemléltetés) teljesíti ezt a megkötést, akkor a (következő) eredő típusnak rendelkeznie kell a metódussal egyébként nem. Ha egy ilyen paraméterezett típust nevezünk meg, akkor a metódusainak teljesíteniük kell az opcionális metódusok megszorításait ha ez lehetséges. A következmény (a származtatott típus) egy típus lesz az összes nem opcionális metódussal, plusz néhánnyal az opcionális metódusokkal, amelyek megszorításai teljesülnek. például. az "array"-nak van egy opcionális "copy" metódusa, ami akkor létezik (akkor tételezzük fel), ha az aktuális paraméter rendelkezik "copy" metódussal. Itt van pár példa.
array[int] % van copy metódusa
array[employee] % lehet hogy nincs copy metódusa
Ha az "employee" nem rendelkezik "copy" metódussal, akkor a származtatottaknak az "array" típusban nincs "copy" metódusuk.
A rutinoknak két fajtája van, eljárások és iterátorok. A rutin típus megvalósítása a következő speciális formát követi.
<routine_type_desig> -> proc <nonparam_proc_sig> | iter <nonparam_iter_sig>
<nonparam_proc_sig> -> "(" [<type_list>] ")" [<returns>] [<signals>]
<nonparam_iter_sig> -> "(" [<type_list>] ")" <yields> [<signals>]
<type_list> -> <type_designator> ["," <type_designator>]*
Ezek a típus-megvalósítások jelzik a rutinok fajtait, az argumentumok számat és típusát, a visszatérési érteket, és a megszakításokat. Például.
proc(int, int) returns (bool) signals (negative)
iter(stree[int]) yields (int)
A megjelölt típusok közé tartoznak a "record", "struct" és a "oneof" típusok. Ezek speciális paraméterezhető típusok, amelyek tartalmaznak névvel jelölt mezőket, és a következő speciális formát követik:
<tagged_type_desig> -> <tagged_type> "[" <field> ["," <field>]* "]"
<tagged_type> -> 'record' | 'struct' | 'oneof'
<field> -> <idn_list> ":" <type_designator>
Ezek a típus leírások gondoskodnak minden egyes mező nevet, és adnak nekik típust. Például.
record[x, y: int, s: string]
definiál egy rekord típust. ennek a típusnak a rekordjainak három mezőjük van: két "int" mező, amit "x"-nek, és "y"-nak hívnak, és egy "string" típusú mező, amit "s"-nek nevezünk.
A típus-ellenőrzés a Theta-ban fordítási időben történik, és a típus leírások elemzésen alapul, azaz meghatározza vajon azonos típust jelölnek-e. Két típus-meghatározása azonos, ha ugyanazt a típust jelölik, egybekent különbözőek.
A típus-azonosság a következőképp van definiálva:
A típusok a Theta-ban típus-hierarchiában csoportosulnak. minden egyes típus rendelkezik néhány szupertípussal. A hierarchia csúcsán az "any" típus áll, aminek nincsenek metódusai, és szupertípusa minden típusnak.
A típus hierarchia a típus-azonosság fogalmán alapszik. Egy típus
mindig altípus, és szupertípusa is önmagának. Az altípus, és
szupertípus reláció is tranzitív:
ha T altípusa az S-nek, és S altípusa R-nek, akkor T altípusa R-nek.
Az "any" az egyetlen szupertípusa a beépített típusoknak, kivéve a gazdag hierarchiával rendelkező rutin típusok. Nevezetesen, semmilyen altípus relációkkal a record és struct típusok nem lettek ellátva.
nem altípusa a
A felhasználó által definiált típusok, és a felhasználó által definiált paraméterezett típusok világosan mutatják a közvetlen szupertípusokat. Minden szupertípusnak felhasználó által definiáltnak kell lennie, kivéve ha miden felhasználó által definiált típus egy altípusa lesz automatikusan az "any"-nek.
Minden típus generál egy felhasználó által definiált típust, amely éppúgy altípusa az "any"-nek. A Theta fordító garantálja, hogy az altípusok rendelkeznek a szupertípusaik összes metódusával kompatibilis szignatúrával.
R1 rutin típus altípusa az R2 rutin típusnak, ha az összes most következő feltételek teljesulnek:
Ezek a szabályok biztosítják, hogy egy R1 típusú rutin hívása mindig megengedett akárhol, ahol az R2 típusú rutin hívása előre látott (engedélyezett). nevezetesen, a rutin nem fog okozni váratlan kivételeket.