A Pizza nyelv

Alprogramok, modulok

Névtelen függvények

Ez egy nagyon kényelmes kiterjesztése a Java-nak. Ahelyett, hogy egy függvényt definiálnánk az osztályhoz (amit úgyis csak egy helyen használnánk), lehetőségünk van függvények lokális definiálására.

A fun(argtype1 var1 , ..., argtypen varn) -> resulttype { statements } kifejezés egy (argtype1, ..., argtypen) -> resulttype típusú függvényt ad vissza (lásd: 'Függvény típusú változó' című fejezet). A névtelen függvények a definiálásuk környezetében lévő összes változót látják. Vizsgáljuk meg ezt két rövid példán:

class A { public static () -> int makeIncr() { int count = 0; return fun() -> int { return count++; } } public static void main( String[] args ) { () -> int incr1 = makeIncr(); () -> int incr2 = makeIncr(); System.out.println( incr1() + " " + incr1() + " " + incr2() + " " + incr1() ); } }

Mint láthatjuk, a makeIncr() minden hívásánál visszaad egy új inkrementer függvényt. Minden ilyen függvény rendelkezni fog egy "saját" count változóval, melynek kezdeti értéke a makeIncr függvényben lévő lokális count változó értékével fog megegyezni. Ez a példa a következőket fogja kiírni futtatáskor:

0 1 0 2

Igazi ereje a névtelen függvényeknek a következő példán mutatkozik meg. Van egy traverse függvényünk ami egy bináris fát jár be inorder bejárással és minden csúcsra alkalmazza a paraméterül adott függvényt. Egy egészeket tartalmazó fának a csúcsait így lehetne összeadni:

class Traverse { public void <A> traverse( Tree<A> t, (A) -> void proc ) { if ( t instanceof Branch ) { Branch b = (Branch)t; traverse( b.left, proc ); proc( b.elem ); traverse( b.right, proc ); } } public int sum( IntTree t ) { int n = 0; traverse( t, fun( int x ) -> void { n += x; } ); return n; } }