<eljárásnév> = proc [<generic parms>] ( <formal parms> )
[returns (<type_spec>,...)] [signals (<exception>,...)] [where (<constaints>,...)]
<routine_body>
end <eljárásnév>
A CLU a függvényeket olyan eljárásoknak tekinti, amelyek adnak vissza
eredményt.
Példa:
s2ac = proc ( s:string ) returns ( array [char] ) indexC = proc ( c:char , s:string ) returns ( int ) new = proc ( ) returns (array [t] ) divide = proc ( num, denom : int ) returns ( int, int ) copy = proc [t:type] ( src:t ) returns ( t ) div = proc ( num, denom : int ) returns ( int ) mod = proc ( num, denom : int ) returns ( int )
divide = proc (num,denom : int ) returns ( int, int )
gcd = proc ( n, d : int ) returns ( int ) % legnagyobb közös osztó if d = 0 then return ( n ) else quotient, remainder : divide( n, d ) return ( gcd( d, remainder ) ) end %if end gcd
x : int := gcd( 10, 3 ) + 7
a : array[int] := array[int]$new( ) x, y : int := divide( 3, 4 )
Az iterációt általában egy adott (összetett) típusú változó elemeinek felsorolására használjuk. Ezeket az értékeket azonban nem egyszerre, hanem egyesével lehet kinyerni, s visszaadásukra nem a return, hanem a yield utasítás szolgál. Az előállított elemek használhatók más modulokban, ahol a következő séma szerint dolgozhatjuk fel őket:
Minden i elemre, amit az A iterátor előállított: hajtsunk végre egy műveletet az i-n. Valahányszor az iterátor visszaad egy elemet a yield utasítás segítségével, a visszaadott elem feldolgozódik a ciklus törzsében előírt módon, majd a vezérlés az iterátorban folytatódik, hogy egy újabb elemet adhasson vissza. Tehát az iterátor felelős az elemek generálásáért, míg a hívó modul adja meg, hogy az elemekre milyen műveletet kell végrehajtani.
Az iterátorok implementálására a CLU nyelvben az iter modul szolgál, melynek definiálása a következőképpen történik:
<iterátornév> = iter [<generic parms>] <formal parms> [yields (<type_spec>,...)] [signals (<exception>,...)] [where (<constaints>,...)] <routine_body> end <iterációnév>
Az iterátor és az eljárás fogalma nagyon hasonlít egymásra. Az egyetlen fő különbség, hogy az eljárás véget ér a return utasítás hatására, míg az iteráció a yield után még folytatódik, és csak akkor terminál, ha a törzs végére ért a vezérlés.
A CLU-ban a for utasítás segítségével használhatjuk az iterátorokat:
for <declaration list in <iteration call do <body endAmikor egy for utasításra kerül a vezérlés, létrejönnek a ciklusváltozók (csak akkor, ha szükséges), és az <iteration call végrehajtódik. Ha az iteráció ad vissza eleme(ke)t, a visszaadott elem(ek) a ciklusváltozó(k)hoz rendelődnek, és végrehajtódik a ciklus törzse. Amikor a ciklustörzs futása véget ér, a vezérlés visszaadódik az iterátorhoz.
Ha az iterátor terminál, akkor a for ciklus is terminál, és a vezérlés a ciklust követő utasítással folytatódik. Ha a ciklus törzse olyan utasítást tartalmaz, amely a cilust terminálja, az iterátor automatikusan terminál.
A CLU a beépített típusokhoz tartalmaz beépített iterátorokat. Például az egész típushoz tartozik egy int$from_to iterátor:
from_to = iter ( x, y : int ) yields ( int )Ez az iterátor felsorolja az x és az y közötti egész számokat (a határokat is beleértve). Az int típusnak van még egy int$from_to_by iterátora is, amelynek a lépésközt is meg lehet adni. A tömböknek (array) és a sorozatoknak ( sequence) két iterátora van: elements (az elemeket adja vissza) és indexes (a legális indexeket adja vissza). A string típusnak van egy chars iterátora, amely felsorolja a string elemeit az elsötöl az utolsóig.
A CLU-ban létezik az iterátor típus, amely alakjában és jelentésében is egyszerű analogonja az eljárástípusnak:
itertype ( ... ) returns ( ... ) signals ( ... )