A Factor egy alapvetően objektumelvű nyelv, dinamikus tipusozással. A változóknak és a stack effektben deklarált neveknek nem kell megadnunk a típusát, valamennyien az object osztály leszármazottai és a Forth-stílusú korai stack-alapú nyelvekkel ellentétben a vermen nem csak egyszerű (például 16 bites) adatok lehetnek, hanem tetszőleges osztályú/típusú adat, sőt mint azt látni fogjuk akár futtatható kód is.
Nincsenek igazán megkülönböztetett alaptípusok, pontosabban más értelemben vannak, ugyanis például a lebegőpontos és egész számok ugyanúgy elemei logikailag az objektumhierarchiának, de nem kell külön szótárat betölteni, ha használni szeretnénk a számokat. Bizonyos számliterálokat tehát például mindenfajta USE: nélkül használhatunk(ez alól a komplex számok és hasonlók se kivételek), más kérdés, hogy a rajtuk végzett műveletek nem feltétlen lesznek elérhetőek - például a + művelet a math szótárban található meg. Az itt említettek miatt érdemes tehát bizonyos értelemben elemi típusokról beszélni, de ezek a típusok is bele vannak foglaltatva az objektumhierarchiába. A fenti szép képből talán azért egy kicsit ki tudnak lógni a szavak, mert ott kicsit nehézkes és ködös eldönteni, hogy egyáltalán részei-e a hierarchiának és ha igen, akkor hogyan kapcsolódnak hozzá. A szavaknak lehetnek property-jei ugyanis és több szempontból viselnek bizonyos objektumelvű szemlélettel kialakított tulajdonságokat, mégis jobb inkább valamiféle két szinten működő objektumelvűségről beszélni és logikailag elkülöníteni őket az implementált típusrendszertől.
Factorban létezik egy f singleton false érték és a nyelv konvenciója szerint ez jelképezi a false-ot, minden más objektum pedig igaz logikai értéket képvisel. Az f, vagyis false értéke egy nagyon alacsonyszintű dolog, gyakorlatilag egy osztály és egy objektum is egyben. A logikai kifejezések használatát megkönnyítendő a Factorban defniáltak egy t szót is(szintén egyben osztály is), ami viszont magasabb szinten helyezkedik el a programozási nyelv felépítésében. Az f és a t osztályok unióosztálya képezi a boolean típust, tehát maga a boolean a factorban már nem igazán tekinthető alaptípusnak, helyette az a fura helyzet áll elő, hogy ezt a szerepet az f látja el.
A fent szavakkal leírt jelenséget érzékeltetni a legjobban talán néhány példával lehet:
USE: classes ! A class szóhoz kell f . ! Itt most az f objektumra hivatkozunk, eredmény: f \ f . ! Ezzel a módszerrel megkaphatjuk f osztályát, eredmény: POSTPONE: f f \ f eq? . ! Referenciaként azonos-e f és f osztálya? Eredmény: f (ez már az összehasonlítás miatti false tehát nem) f \ f = . ! f és az f osztálya két különböző objektum, ezért az eredmény: f (az összehasonlítás miatti false) { f } ! ez egy tömböt tesz a stack-re, amiben az f objektum van { POSTPONE: f } ! ez egy tömböt tesz a stack-re, amiben az f osztály van POSTPONE: f ! stack underflow: ez viszont már nem megy... f class . ! Kiírjuk az f osztályát, eredmény: POSTPONE f \ f class . ! Kiíratjuk az f osztályának az osztályát, eredmény: word t \ t eq? . ! Ugyanaz-e t és \ t ? Eredmény: t, vagyis referencia szerint igen! t \ t = . ! Nyilván ez is t eredményt ad
A Factor nyelv törekedni próbál arra, hogy lehetőleg a számok kezelésekor minél pontosabban tudja követni a matematikában megszokott szemantikát. Például két nagy szám szorzása sose csorduljon túl és két egész szám osztásakor keletkező eredmény ábrázolható racionális tört legyen. A nyelv a fentieken kívül támogat lebegőpontos és komplex számokat is. A számokon dolgozó szavak legtöbbje a math szótárban található. Factorban bizonyos számtípusokra igazak bizonyos implicit konverziós szabályok, ezeket a megfelelő szekcióban ismertetjük, a számliterálok alakja és fajtáu pedig az előző fejezetben már ismertetésre kerültek.
Általános szám-műveletek(alapműveletek)
Minden számra értelmezettek a +, -, *, / műveletek, a nem-kommutatívak ezek közül balról jobbra működnek, intuitív módon (20 4 / . 5-öt ad eredményül) és valós számokra értelmezettek a szokásos <, >, <=, >=, műveletek is, komplexekre természetesen csak az egyenlőség működik. Ezen felül van még egy number= szó is, mely kvésbé precíz eredményt ad, de a number únióosztály felett van definiálva, így alkalmas különböző típusú értékek közötti vizsgálatra is. Float értékek esetén előfordulhat, hogy a megvizsgálandó számok legalább egyike NaN(Not a Number). Ilyenkor a hagyományos relációműveletek és egyenlőségvizsgálat kivételt generál, ha ezt el szeretnénk kerülni, akkor egyenlőség helyett number=-t használjunk(ha NaN előfordul, mindig false-t ad vissza 'NaN NaN number= .' esetén is f!) illetve a relációs szavak u-s(unordered) változatait, például u<. Az itt leírtakat úgy is nevezik, hogy number protokoll, ugyanis a nyelv számaiból(racionális és komplex számaiból, ahol racionálisba tartozó a ratio a fixnum és a bignum is) képeztek egy number únióosztályt.
FONTOS: A nullával való osztás szemantikája platform és adattípusfüggő
Egyéb szám-műveletek és egyéb számok
A fenti egyszerű alapműveleteken kívül lehetőség van sok, típusspecifikus művelet elvégzésére is, például moduló-aritmetika, bitműveletek komplex műveletek stb. Ezeknek a nagy része szintén a math (esetleg math.akármi.akármimás stb.) szótárban található meg. Könyvtári kiterjesztésként a fentieken kívül dolgozhatunk egyébként még kvaterniókkal is.
Factorban kifejezetten sok előre definiált konkrét és absztrakt (osztályunió, vagy mixin class) kollekció osztály létezik, melyeket felhasználhatunk. A nyelv összes típuskonstrukciójának részletes bemutatása helyett mi most csupán átfogó képet szeretnénk nyújtani a lehetőségekről.
A típuskonstrukciók logikailag a következő módon szervezhetőek:
A szekvenciák véges, lineárisan rendezett gyűjteményei elemeknek. A szekvenciákkal dolgozó szavakat a sequences szótár tartalmazza.
A szekvenciatípusba tartozó típusok implementálnak egy protokollt, vagyis a következő műveleteket implementálnunk kell:
Szekvenciatípusok például:
Az egyszerű szekvencia protokollt megvalósító osztályok felett sok ismert művelet definiált, ezeket szekvenciakombinátoroknak nevezik és a sequences szótárban helyezkednek el. Minden szekvencia típusú objektumra értelmezett például a funkcionális nyelvekből jól ismert map függvény, a reduce (ami más nyelvek fold-jának felel meg), az accumutate (ami részeredményeket is gyűjtő fold), a filter és egyszerű lekérdezések, mint például az all? és az any? szavak. Ezek funkcionális szemléletű szavak, de van a legtöbbjüknek helyben dolgozó változata is, ami nem új értéket állít elő, hanem a már meglévőt változtatja (kivéve ha az mutable). Ez utóbbi szavak az előzőek felkiáltójellel ellátott változatai, például a map! szó.
Elemenkénti feldolgozáshoz is kapunk beépített eszközt, az each, 2each, 3each személyében (2-es és 3-as változata egyébként a map-nek is van).
Fontos megjegyezni, hogy a tömbök, vektorok, egyéb szekvenciák általában nem kell, hogy homogén, egyazon-típusú elemekből álljanak. A legtöbb nyelvben ez nem így van(sok dinamikus nyelven sem), de itt a fenti szabályra vonatkozó kivételek a ritkábbak a könyvtári gyűjteményeknél (például Byte-tömb, Byte-vektor kivételesek, mert csak byteokat tartalmazhatnak, de { 1 "abc" 2.5 } tömb teljesen lehetésges). A legtöbb különleges esetet a literáloknál említettük, illetve a fejlesztőkörnyezet help-rendszerében rákereshetünk az egyes típusok esetén lehetséges-e a különböző típusú elemek sorozata.
Az asszociáció típusok kulcs-érték párokat absztrahálnak. A felettük definiált szavak az assocs szótárban vannak.
Az asszociáció típusoknak is implementálniuk kell egy protokollt, amely a következő:
Asszociatív típusok:
Asszociatív típusokra is vannak predefinit kombinátorok, például assoc-map a map megfelelője.
A Factor nyelv sok egyéb ismert típuskonstrukciót nyújt számunkra, melyek halmaza folyamatosan bővül. Itt megemlítünk néhány ismertebbet közülük:
Általában adnak típuskonverziós szavakat a beépített szótári típusokhoz, ezek formája valami>másikvalami(esetleg az első valami elhagyásával), ha valami típusból, egy másikvalami típusra konvertál. A nyelvben ezeken kívül azonban vannak esetek, amikor implicit típuskonverzió történik. Ilyen történik például a számok esetében, ha különböző típusú elemekkel számolunk:
USE: classes 3 >fixnum 6 >bignum * class . ! Az eredmény: bignum, tehát a szorzat változtatta a típust, ha az egyik bignum volt ! 1/2 2.0 + . ! Az eredmény: 2.5, mert ha egy kifejezésben float szerepel, az eredmény float lesz ! C{ 1 2 } C{ 3 -2 } + . ! Eredmény: 4 (komplex számok "vissza-alakulhatnak" valóssá) C{ 0.0 2.0 } C{ 0.0 1.0 } * . ! Viszont nem minden esetben. Eredmény: C{ -2.0 0.0 }