A q programozási nyelv

Utasítások, vezérlési szerkezetek

Értékadás

Változónak értéket adni a kettőspont (:) operátorral lehet:

n:42

Szekvencia

Szekvenciát a pontosvessző (;) jellel képezhetünk. Ez csak egy elválasztójel, tehát ha egy utasítássorozat végére is pontosvesszőt rakunk, akkor a végére kerül egy skip utasítás, amely üres eredményt ad vissza (bár az utasításaink mellékhatásai végrehajtódnak).

n:42;m:80

Elágazás

Az if utasítás feltételesen végrehajt egy kifejezéssorozatot. Az alakja a következő:

if[expr_cond;expr_1;...;expr_n]

Az expr_cond kifejezés kiértékelődik, és ha nem nulla az értéke, akkor az expr_i kifejezések kiértekelődnek balról jobbra haladva. Például:

a:42 b:98 z:"" if[a=42;z:"Life the universe and everything"] z "Life the universe and everything"
if[b<>42;x:6;y:7;z:x*y] z 42

Else ág ebben az if-utasításban nem létezik.

Feltételes kiértékelés

A C-hagyatékú nyelvekben általában található egy olyan dolog amit úgy hívnak, hogy feltételes kiértékelés. Ennek alakja a következő:

expr_cond ? expr_true : expr_false

ahol expr_cond egy kifejezés, ami boolean típusú értékre értékelődik ki (vagy C-ben például int-re). Amikor expr_cond értéke igaz, akkor kiértékelődik az expr_true kifejezés, ellenkező esetben az expr_false kifejezés értékelődik ki.

A feltételes kiértékelés q-ban is jelen van, formája pedig a következő:

$[expr_cond;expr_true;expr_false]

ahol expr_cond egy kifejezés aminek boolean vagy int típusú értéke van. A feltételes kiértékelés eredménye végül expr_true lesz, ha expr_cond nem nulla, különben expr_false lesz:

a:42 b:98 $[a>60;`Pass;`Fail] `Fail
$[b>60;`Pass;`Fail] `Pass

Megjegyzés: a null-érték nem megfelelő az expr_cond számára:

d:0N $[d;`NonNull;`Null] 'type

Megjegyzés: bár az if utasításból hiányzik az else ág, a feltételes kiértékelés kiterjesztett változatával elérhetjük a kívánt hatást. Ennek formája a következő:

$[expr_cond;[expr_true_1;...];[expr_false_1;...]]

amint látható, ennek az alakja hasonló a feltételes kiértékeléshez, a különbség csupán a szögletes zárójelek megjelenése. Így expr_cond értékétől függően nem csupán egy másik kifejezést értékelünk ki, hanem kifejezések szekvenciáját, amiket szögletes zárójelekben adtunk meg. Az egész, kiterjesztett feltételes kiértékelés végeredménye a legutolsó kiértékelt kifejezés eredménye lesz:

a1:42 a2:24 $[a1<>42;[a:6;b:7;a*b];[a:`Life;b:`the;c:`Universe;a,b,c]] `Life`the`Universe
$[a2<>42;[a:6;b:7;a*b];[a:`Life;b:`the;c:`Universe;a,b,c]] 42

Ciklus

do

Bár a q-ban van ciklus, nem ajánlott a használata. Számos más lehetőség van a nyelvben, amellyel többször megismételhetünk egy műveletet. Csak akkor nyúljunk az explicit ciklushoz, ha nincs más lehetőség, pl. inputra várakozás esetén.

A do utasítással egy számlálós ciklust hozhatunk létre, melynek alakja a következő:

do[expr_count; expr_1; ...; expr_n]

ahol expr_count egy int értékű kifejezés. Expr_1-től expr_n-ig a kifejezések pedig kiértékelődnek expr_count-szor, méghozzá balról jobbra haladva.

Például, a következő kifejezés kiszámolja egy n szám faktoriálisát:

n:5 do[-1+f:r:n;r*:f-:1] r 120

while

A while utasítás egy feltételes ciklust hoz létre, alakja pedig a következő:

while[expr_cond;expr_1;...;expr_n]

ahol expr_cond kiértékelődik, és expr_1-től expr_n-ig lévő kifejezések pedig annyiszor értékelődnek ki (balról jobbra), ameddig nem nulla az expr_cond kifejezés.

Vezérlésátadó utasítások

Egy normál függvény végrehajtása addig tart, amíg a függvényben szereplő összes kifejezés ki nem értékelődik. Van azonban két mód arra, hogy egy függvény végrehajtása hamarabb érjen véget: az egyiket sikeres visszatérésnek (return) hívjuk, a másik az abortálás

Return

Ahhoz, hogy egy függvényből sikeresen visszatérjünk és visszaadjunk egy értéket, használjunk egy üres értékadást (:). Ez úgy néz ki, hogy a kettőspont jobboldalán valamilyen érték van, viszont a baloldalán nem változó szerepel. A következő példában a végrehajtás leáll a harmadik kifejezésnél, és ennek értéke adódik is vissza. Az utolsó kifejezés soha sem értékelődik ki:

c:0 f:{a:6;b:7;:a*b;c::98} f 0 42 c 0

Abort

Ahhoz, hogy abortáljunk egy függvény, szignált kell használnunk, ami egy egyes-idézőjel ('), egy értékkel a jobb oldalán. Például a következő függvényben a végrehajtás abortálódik a harmadik kifejezésnél. Az utolsó kifejezésre, azaz c értékadására sosem kerül sor:

c:0 g:{a:6;b:7;'`TheEnd;c::98} g 0 'TheEnd
c 0

Fontos: a szignál operátor argumentuma egy szimbólum vagy string. Kezdő q programozók tévesen azt hihetik, hogy egyszerűen egy azonosító kell az idézőjel mögé, és ez kísérletezéskor működik is. Valójában az történik, hogy a q az azonosítót változónévnek fogja fel, és keresi a változót, de nem találja (ki adna egy változónak ugyanolyan nevet, mint amit hibaüzenetként akar használni?). Tehát amit látunk, az a "változó nem található" hiba, amely megegyezik a nem talált változó nevével. Ha létezik a változó, de rossz típusú (vagy épp egy nem szimbólum vagy string literált írtunk az operátor mögé), az stype hibát kapjuk.