Scala
- def f(x:Int) : Int=>Unit =
- val g = (y:Int) => println(s"x=$x, y=$y")
- g
- end f
- val h1 = f(10)
- h1(2) // prints x=10, y=2
- val h2 = f(20)
- h1(3) // prints x=10, y=3
- h2(3) // prints x=20, y=3
- import java.util.function.Function;
- public static Function<Integer,Void> f(int x) {
- Function<Integer,Void> g = y -> {
- System.out.format ("x=%d, y=%d%n", x, y);
- return null;
- }
- return g;
- }
- public static void main (String[] args) {
- Function<Integer,Void> h1 = f(10);
- h1.accept(2); // prints x=10, y=2
- Function<Integer,Void> h2 = f(20);
- h1.accept(3); // prints x=10, y=3
- h2.accept(3); // prints x=20, y=3
- }
- def outer(x:A) : B=>C =
- def inner(y:B) : C =
- //...use x and y...
- end inner
- inner
- end outer
- val f = outer(...)
- f(...)
outer is called
xouter returns nested function inner
inner has free variable xx from outer's ARouter's AR and x endsinner is called through alias f
inner needs x from outer's AR- def outer(x:A) : B=>C =
- def inner(y:B) : C =
- // use x and y
- // free: x
- // bound: y
- end inner
- inner
- end outer
Closure contains
innerx- def outer(x:A) : B=>C =
- var u:A = x
- def inner(y:B) : C =
- // use x, u, and y:
- // free: x, u
- // bound: y
- end inner
- u = u + 1
- inner
- end outer
Closure contains
innerxu?
inner sees updated u?
u to be immutable?
inner has free x- def outer(x:Int) : Boolean=>Int =
- def inner(y:Boolean) : Int =
- x + (if y then 0 else 1)
- end inner
- inner
- end outer
Object-oriented implementation in Java
- public static Function1<Boolean, Integer> outer(int x) {
- return new Closure(x);
- }
- public final class Closure
- extends AbstractFunction1<Boolean, Integer> {
-
- private final int x;
-
- public final Integer apply(Boolean y) {
- return x + (y ? 0 : 1);
- }
-
- public Closure(int x) { this.x = x; }
- }
inner has free x,u- def outer (x:Int) : Boolean=>Int =
- var u:Int = x
- def inner (y:Boolean) : Int =
- x + u + (if y then 0 else 1)
- end inner
- u = u+1
- inner
- end outer
u on heap- public static Function1<Boolean, Integer> outer(int x) {
- IntRef u = new IntRef(x);
- var c = new Closure(x, u);
- u.elem = u.elem+1;
- return c;
- }
- public final class Closure
- extends AbstractFunction1<Boolean, Integer> {
- private final int x;
- private final IntRef u;
- public final Integer apply(Boolean y) {
- return x + u.elem + (y ? 0 : 1);
- }
- public Closure(int x, IntRef u) {
- this.x = x;
- this.u = u;
- }
- }
How to create a "container" for data and functions?
Object-oriented programming: classes
- public class Incrementor {
- private int i;
- public Incrementor(int i) {
- this.i = i;
- }
- public int increment(int x) {
- return x+i;
- }
- }
- // use object
- Incrementor inc = new Incrementor(2);
- inc.increment(4); // returns 6
- inc.increment(5); // returns 7
Functional programming
- def incrementor(i:Int) : Int=>Int =
- (x:Int) => x+i
- end incrementor
- // use closure
- val inc = incrementor(2)
- inc(4) // returns 6
- inc(5) // returns 7
- val f : ()=>Int =
- var x = -1
- def g() = { x = x + 1; x }
- g
- val f : ()=>Int =
- var x = -1
- () => { x = x + 1; x }
x to -1 when initializing variable fx on every call f()- scala> f()
- res0: Int = 0
- scala> f()
- res1: Int = 1
- def g(y: Int) : ()=>Int =
- var z = y
- def h() = { z = z + 1; z }
- h
- val g: Int=>()=>Int =
- y =>
- var z = y
- () => { z = z + 1; z }
g(i) returns:
functions ()=>Int, their own z set to i
- scala> val h1=g(10)
- h1: () => Int = $$Lambda$1098/39661414@54d8c20d
- scala> val h2=g(20)
- h2: () => Int = $$Lambda$1098/39661414@5bc7e78e
h1() and h2() return:
their own incremented z
- scala> h1()
- res3: Int = 11
- scala> h1()
- res4: Int = 12
- scala> h2()
- res5: Int = 21
- scala> h1()
- res6: Int = 13
Implement a function printer that adds an initializable string prefix; wanted use:
- val p = printer("> ")
- println(p("hello"))
- println(p("world!"))
- def printer(prefix: String) : String=>String =
- (s: String) => prefix + s
Implement a map data structure from arrays and index access; wanted use:
- val (get, put) = map(10)
- put(3, "Hello")
- put(6, "world!")
- println(get(3))
Return a tuple of functions that access a shared array
- def map(size: Int) : (Int=>String, (Int, String)=>Unit) =
- val elems: Array[String] = Array.ofDim(size)
- def get(key: Int) =
- if key < size then elems(key)
- else throw new NoSuchElementException("Unknown key " + key)
- def put(key: Int, value: String) =
- elems(key) = value
- (get, put)
- end map
# <span class="fa-stack"><i class="fa-solid fa-circle fa-stack-2x"></i><i class="fa-solid fa-book fa-stack-1x fa-inverse"></i></span> Nested Functions: GCC - Lifetime problems caused by nested functions <div class="grid grid-cols-2 gap-4"> <div> ```c typedef void (*funcptr) (int); funcptr f (int x) { void g (int y) { printf ("x = %d, y = %d\n", x, y); } g (1); return &g; } int main (void) { funcptr h = f (10); (*h) (2); f (20); (*h) (3); } ``` </div> <div> Unsafe calls may or may not work ```sh $ gcc -std=c99 nested-gcc.c $ ./a.out x = 10, y = 1 <- g(1): safe to call g, with x=10 x = 10, y = 2 <- (*h)(2): unsafe to call h, created with x=10 x = 20, y = 1 <- g(1): safe to call g x = 20, y = 3 <- (*h)(3): unsafe to call h, created with x=10 ``` </div> </div> ---
# <span class="fa-stack"><i class="fa-solid fa-circle fa-stack-2x"></i><i class="fa-solid fa-book fa-stack-1x fa-inverse"></i></span> Nested Function: Java With explicit object instantiation <div class="text-xl"> ```java import java.util.function.Function; static Function<Integer,Void> f (int x) { Function<Integer,Void> g = new Function<Integer,Void>() { public Void apply(Integer y) { System.out.format ("x = %d, y = %d%n", x, y); return null; } }; g.apply (1); return g; } public static void main (String[] args) { Function<Integer,Void> h = f (10); h.apply (2); f (20); h.apply (3); } ``` </div> ---