Skip to content

Instantly share code, notes, and snippets.

@SeanTAllen
Created May 18, 2016 17:01
Show Gist options
  • Save SeanTAllen/fea3e0427eb8e46ec143da55000694b8 to your computer and use it in GitHub Desktop.
Save SeanTAllen/fea3e0427eb8e46ec143da55000694b8 to your computer and use it in GitHub Desktop.
Pony Solution to the Expression Problem Using Object Algebras see http://i.cs.hku.hk/~bruno/oa/ for more info
interface ExpAlg[E]
fun lit(x: I32): E
fun add(e1: E, e2: E): E
interface Eval
fun eval(): I32
interface EvalExpAlg
fun lit(x: I32): Eval val =>
recover
object
let x: I32 = x
fun eval(): I32 => x
end
end
fun add(e1: Eval val, e2: Eval val): Eval val =>
recover
object
let e1: Eval val = e1
let e2: Eval val = e2
fun eval(): I32 => e1.eval() + e2.eval()
end
end
interface SubExpAlg[E] is ExpAlg[E]
fun sub(e1: E, e2: E): E
interface EvalSubExpAlg
fun sub(e1: Eval val, e2: Eval val): Eval val =>
recover
object
let e1: Eval val = e1
let e2: Eval val = e2
fun eval(): I32 => e1.eval() - e2.eval()
end
end
interface PPrint
fun print(): String
interface PrintExpAlg2
fun lit(x: I32): String =>
x.string()
fun add(e1: String, e2: String): String =>
e1 + " + " + e2
fun sub(e1: String, e2: String): String =>
e1 + " - " + e2
actor Main
new create(env: Env) =>
let ea = object is EvalExpAlg end
let esa = object is (EvalSubExpAlg & EvalExpAlg) end
let pa2 = object is PrintExpAlg2 end
let ev = exp1[Eval val](esa)
env.out.print("PRINTING\n" + exp1[String](pa2) + "\n" + exp2[String](pa2))
fun exp1[E: Any #read](alg: ExpAlg[E] box): E =>
alg.add(alg.lit(3), alg.lit(4))
fun exp2[E: Any #read](alg: SubExpAlg[E] box): E =>
alg.sub(exp1[E](alg), alg.lit(4))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment