Previous Next |

To make the new language Fun-MiniJava, we add *function types* to MiniJava:

ClassDecl→ typeid=TypeExp;TypeExp→TypeExp->TypeExp→ ( TypeList ) ->TypeExp→ ( TypeExp ) →Type TypeList→TypeExp TypeRest* →TypeRest→,TypeExp

The type `int->String` is the type of functions that take a single integer argument and return a string result (assuming a class `String` is declared). The type `(int,String)->int[]` describes functions that take two arguments (one integer, one string) and return an array-of-integers result. Any variable can have a functional type; functions can be passed as arguments and returned as results. Thus, the type `(int->int)->(int)->int` is perfectly legal; the `->` operator is right-associative, so this is the type of functions that take an `int->int` argument and return an `int->int` result. We also modify the format of a CALL expression, so that the function being called is an arbitrary expression, without the `.`*methodname* component, and so that a method itself can be the result of an expression:

Exp→Exp(ExpList)Exp→Exp.id

If `v` is an object of a class with a method `int m(int[])`, then the expression `v.m` evaluates to a function value of type `(int[])->int`. Evaluating `v.m` does not call the method. We permit variable declarations and function (method) declarations at the beginning of a compound statement (i.e., functions are nested). We remove the `if` statement and add an `if` expression: That is, `(if (`*E*`)` *B* `else` *C*`)` evaluates *E*, and then evaluates *B* if *E* is true, otherwise evaluates *C*. The value of the entire `if` expression is the value of *B* or *C*.

MethodDecl→publicType id(FormalList)Compound Compound→ {VarDecl^{*}MethodDecl^{*}Statement^{*}returnExp;}Exp→Compound→if(Exp)ExpelseExp

Finally, we interpret the meaning of `return` differently: Instead of producing the result for an entire function body, it produces the result of its own compound statement. Thus, the expression `{return 3;}+{return 4;}` evaluates to 7. Program 15.1 illustrates the use of function types. The function `add` takes an integer argument `n` and returns a function `h`. Thus, `addFive` is a version of `h` whose `n` variable is 5, but `addSeven` is a function `h`(*x*) = 7 + *x*. The need for each different instance of `h` to "remember" the appropriate value for a *nonlocal* variable `n` motivates the implementation technique of *closures*, which is described later.

```
type intfun = int -> int;
class C {
public intfun add(n: int) {
public int h(int m) { return n+m;}
return h;
}
public intfun twice(f: intfun) {
public int g(int x) {return f(f(x));}
return g;
}
public int test() {
intfun addFive = add(5);
intfun addSeven = add(7);
int twenty = addFive(15);
int twentyTwo = addSeven(15);
intfun addTen = twice(addFive);
int seventeen = twice(add(5))(7);
intfun addTwentyFour = twice(twice(add(6)));
return addTwentyFour(seventeen);
}
}
```

The function `twice` takes an argument `f` that is a function from `int` to `int`, and the result of `twice(f)` is a function `g` that applies `f` twice. Thus, `addTen` is a function `g`(*x*) = `addFive`(`addFive`(*x*)). Each instance of `g`(*x*) needs to remember the right `f` value, just as each instance of `h` needs to remember `n`.

JaVa |
Previous Next |