Chapter 12 Outlook
12.1 A Taste Of MiniScala
A MiniScala function to compute x to the power of y:
def pow(x: Int, y: Int) =
if (y == 0) 1 // pow(x, 0) == 1
else if (even(y)) {
val t = pow(x, y /2) // pow(x, 2z) = pow(pow(x, z), 2)
t * t
} else {
x * pow(x, y - 1) // pow(x, z + 1) = x * pow(x, z)
}
Say ``Hello’’:
val arr = new Array[Int](5);
arr(0) = 'H'; arr(1) = 'e'; arr(2) = 'l'; arr(3) = 'l'; arr(4) = 'o';
var i = 0;
while (i < 5) {
putchar(arr(i));
i = i + 1
}
Our implementation of MiniScala is already quite powerful.
- We can do essentially everything we can do in C
- Missing features (structs, strings): can be implemented as arrays
Are we done yet?
- Higher level features: nested first-class functions, objects
- Code quality: optimizations
12.2 More Functions
12.2.1 Nested Functions
Lambda lifting: first-order nested function gets additional arguments.
Function passed first-class as argument: partially apply to free variables
NOTE: currying is not natively supported with stack-based 2nd-class values
Second-class vs first-class: stack-allocated vs heap-allocated closure
ALTERNATIVE: linked frames, display, …
12.2.2 Closures
See arrays
12.3 Intermediate Representations
The term intermediate representation (IR) or intermediate language designates the data-structure(s) used by the compiler to represent the program being compiled.
Choosing a good IR is crucial, as many analyses and transformations (e.g. optimizations) are substantially easier to perform on some IRs than on others.
Most non-trivial compilers actually use several IRs during the compilation process, and they tend to become more low-level as the code approaches its final form.
12.4 Optimization
Dataflow etc.