A deklarációt a "FUN" kulcsszó vezeti be. Ezt követi a deklarálandó függvény neve, majd a paraméterek felsorolása. A deklaráció utolsó eleme, pedig a függvény visszatérési típusa.
Létezik viszont olyan függvény amelynek sem paraméterei, sem visszatérési típusa sincs.
Azt mondják, hogy a "main" nem vesz át semmilyen értéket, azaz a "main" egy konstans a com (command-ok) között.
A nyelv támogatja a párhuzamos értékadást, tehát megengedett függvénydeklaráció a következő:
De a függvény visszatérési értéke, maximum 16 mezőből állhat, platformtól függően. Ha ennél véletlenül több kellene, akkor új adattípus bevezetését javasolják az Opal készítői.
Lehetőség van egy függvény paraméterként való átadására is, ezt nevezik higher-order függvényeknek.
Például a határozott integrál kiszámítására egy függvény:
Ismeretes a matematikában, hogy minden egynél több paraméterrel rendelkező függvényre létezik egy transzformáció, amely egy paramétert vár, és egy másik függvény az értéke, (amelynek szintén egy paramétere van), úgy, hogy a szemantika megmarad. Azaz:
A fenti átírás létezik, de mind a két függvény ugyanazt jelenti. A legtöbb funkcionális nyelven ez az átírás bele van építve a nyelvbe, és nem kell külön átírni. Az Opal fejlesztői azonban amellett döntöttek, hogy az első eset az infix jelölésmód esetén használható, a második eset a postfix jelölés esetén, és külön kell deklarálni, és definiálni őket. Ezt a módszert a funkcionális nyelvek esetén carrying-nek hívják.
Ez az eljárás optimalizálásra is használható, mivel ha egy add(3) (.)-at lát a fordító, akkor neki egy olyan függvényt kell csak generálni, amelyik a paraméteréhez 3-at hozzáad. Így hatékonyabb lesz a kész program, másrészt, egy már megírt függvény segítségével definiáltuk annak egy speciálisabb esetét, anélkül, hogy a nat struktúra add függvényéről bármit is tudnánk.
A függvények deklarálásánál megadtuk, hogy milyen adatokkal működjenek a függvények, itt a definiálásban kell rögzíteni, hogy miként tegyék ezt.
A definíciót a "DEF" kulcsszó vezeti be, ezt követi a függvény neve, majd kerek zárójelek között a paraméterek felsorolása. Ez a felsorolás már nem tartalmaz típusokat, mivel az már a deklarációnál megtörtént, csak a neveket, amelyeken keresztül az adatokat a függvény törzsében látni lehet. Ezt követi az "==" kulcsszó, majd a függvénytörzs.
Ahogy az egy ilyen szintű nyelvtől elvárható, támogatja a nevek túlterhelését.
A függvényekre való hivatkozás lehet infix, vagy postfix. Ezért a következő írásmódok egy függvényre való hivatkozás esetén megegyeznek:
Mivel a formulák átírhatók olyan alakra, hogy függvényt kelljen visszaadniuk, ezért akár dinamikusan is dönthet egy függvény arról, hogy mit fog csinálni a változóival.
Előfordulhat olyan eset, hogy az általunk írt struktúra egy függvénye megegyezik egy már megírt függvénnyel. Ekkor, ha a paraméterek sorrendje megegyezik, akkor a definícióban nem kell kiírni.
Ha késleltetni szeretnénk egy függvény kiértékelését, akkor azt a következő formában tehetjük meg:
Ekkor az f függvény csak akkor fog kiértékelődni, amikor a g -t számolnánk ki a kifejezésben.
Maga a függvény törzse egy kifejezés. A kifejezésre erős megkötés vonatkozik. Klasszikusan négyféle dolog lehet kifejezés: az atomi kifejezés, a zárójelezett kifejezés, a függvény használat és az elágazás. Ezen kívül, hogy a funkcionális programozás kifejezőerejét megnöveljék bevezették a lambda absztrakció, a szekció és a lokális deklaráció fogalmát. Atomi kifejezés:
A legtöbb egyszerű kifejezés atomi. Tulajdonképpen két fél atomi kifejezés van: az azonosító és a megjelölés.
Az azonosító mindennek lehet a neve (függvény, globális, vagy lokális változó). A programszövegbe ágyazott fix karaktersorozatok (pl. “Hello Wrold”), pedig a megjelölés, vagy eredetiben denotation típusba tartozik.
Egy függvényen belül lehetőséget biztosít lokális struktúrák használatára. Kétféleképpen írható:
vagy:
Érdekesség, hogy a lokális változók transzformálhatók lambda absztrakcióvá. A fenti példa első transzformációja így néz ki: