Main | About | Tags

First Order Functions

We are defining F1VAE, arithmetic expressions with first order functions. We are explicitly definig the functions using def keywords, and store the definition in another storage, FEnv.

The following code is for defining the function.

enum FunDef {
    case FD(String, String, Expr)
}

FEnv, the new storage for function definitions is a map from function name to its definition.

typealias FEnv = [String : FunDef]

The new definition of Expr includes function call, designated by its name and an expression for a single parameter.

enum Expr: prevExpr {
    // includes all the former definition
    case Call(String, Expr)         //fof
}

Interpretation implementation.

func interp(_ e: Expr, _ env: Env, _ fenv: FEnv) -> Value
{
    switch e {
    case .Num(let n):
        return .NumV(n)
    case .Add(let l, let r):
        return NumVOperation(ADD, interp(l, env, fenv), interp(r, env, fenv))
    case .Sub(let l, let r):
        return NumVOperation(SUB, interp(l, env, fenv), interp(r, env, fenv))
    case .Val(let x, let i, let b):
        return interp(b, env + [x : interp(i, env, fenv)], fenv)
    case .Id(let x):
        return env[x]!
    case .Call(let f, let a):
        switch fenv[f]! {   // lookup(f, fenv)]
        case .FD(_, let pname, let body):
            let v = interp(a, env, fenv)
            return interp(body, [pname : v], fenv)              // static scoping
            return interp(body, env + [pname : v], fenv)        // dynamic scoping
        }
    }
}

All the materials are from CS320 class held on 2021 spring, KAIST.