Skip to content

Instantly share code, notes, and snippets.

@cluno
Last active March 7, 2021 14:32
Show Gist options
  • Save cluno/b8d49b9de848025aed20 to your computer and use it in GitHub Desktop.
Save cluno/b8d49b9de848025aed20 to your computer and use it in GitHub Desktop.
Erik Meijer's Denotational Semantics Code Example in ScalaDay 2014
import Denotational._
/**
* Video: http://www.parleys.com/play/53a7d2c9e4b0543940d9e553
* Slide: https://dl.dropboxusercontent.com/u/7083182/scaladays-slides/DenotationalSemantics.compressed.pdf
*
* For being a better Functional Programmer
* "Fold and unfold for program semantics" by Graham Hutton
* - http://eprints.nottingham.ac.uk/230/1/semantics.pdf
*
* "Denotational Semantics" by David A.Schmit
* - https://www.scss.tcd.ie/Andrew.Butterfield/Teaching/CS4003/DenSem-full-book.pdf
*/
object Main {
def main(args: Array[String]): Unit = {
// def a(): Int = { try{ 1 } finally { 2 } }
// println(a())
val a = TryFinally(Expression(1), Expression(2))
a(n => println(s"return $n"))(s => println(s))
// def b(): Int = { try{ return 1 } finally { 2 } }
// println(b())
val b = TryFinally(Return(1), Expression(2))
b(n => println(s"return $n"))(s => println(s))
// def c(): Int = { try{ 1 } finally { return 2 } }
// println(c())
val c = TryFinally(Expression(1), Return(2))
c(n => println(s"return $n"))(s => println(s))
// def d(): Int = { try{ return 1 } finally { return 2 } }
// println(d())
val d = TryFinally(Return(1), Return(2))
d(n => println(s"return $n"))(s => println(s))
}
}
package object Denotational {
type Success = Any=>Unit
type Returns = Int=>Unit
abstract class Statement() {
def apply(r: Returns)(s: Success): Unit
}
case class Print(n: String) extends Statement {
override def apply(r: Returns)(s: Success): Unit = {
println(n)
s()
}
}
case class Return(n: Int) extends Statement {
override def apply(r: Returns)(s: Success): Unit = {
r(n)
}
}
case class Expression(n: Int) extends Statement {
override def apply(r: Returns)(s: Success): Unit = {
s(n)
}
}
// [s1, s2, s3] r s (() => (s1 r () => (s2 r () => s3 r s))))()
case class Block(body: Statement*) extends Statement {
override def apply(r: Returns)(s: Success): Unit = {
body.foldRight(s)((si, s)=>(q)=>si(r)(s))()
}
}
case class TryFinally(s1: Statement, s2: Statement) extends Statement {
override def apply(r: Returns)(s: Success): Unit = {
s1(x => s2(r)(_ => r(x)))((x) => s2(r)(_ => s(x)))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment