Last active
March 7, 2021 14:32
-
-
Save cluno/b8d49b9de848025aed20 to your computer and use it in GitHub Desktop.
Erik Meijer's Denotational Semantics Code Example in ScalaDay 2014
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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