Skip to content

Instantly share code, notes, and snippets.

@MiloXia
Last active October 24, 2018 21:36
Show Gist options
  • Save MiloXia/e12de140f8a5e31b87a443f9b78171a5 to your computer and use it in GitHub Desktop.
Save MiloXia/e12de140f8a5e31b87a443f9b78171a5 to your computer and use it in GitHub Desktop.
Scala Conditional Compilation
import scala.language.higherKinds
object Conditions {
//based on: An Introduction to Functional Programming Through Lambda Calculus
trait BOOL {
type body[e1 <: E, e2 <: E, E] <: E //select: (E, E) => E
}
trait TRUE extends BOOL {
type body[e1 <: E, e2 <: E, E] = e1 //true = select_first
}
trait FALSE extends BOOL {
type body[e1 <: E, e2 <: E, E] = e2 //false = select_second
}
trait COND[e1 <: E, e2 <: E, E, c <: BOOL] {
type r = c#body[e1, e2, E] //cond = λe1.λe2.λc.((c e1) e2)
}
//let E = BOOL, IF[c, e1, e2] just return TRUE or FALSE
//type IF[c <: BOOL, e1 <: BOOL, e2 <: BOOL] = COND[e1, e2, BOOL, TRUE]#r
//implicitly[IF[TRUE, FALSE, TRUE] =:= TRUE]
//not = λx.(((cond false) true) x)
type NOT[x <: BOOL] = COND[FALSE, TRUE, BOOL, x]#r
//and = λx.λy.(((cond y) false) x)
type AND[x <: BOOL, y <: BOOL] = COND[y, FALSE, BOOL, x]#r
//or = λx.λy.(((cond true) y) x)
type OR[x <: BOOL, y <: BOOL] = COND[TRUE, y, BOOL, x]#r
type ![x <: BOOL] = NOT[x]
type ||[x <: BOOL, y <: BOOL] = OR[x, y]
type &&[x <: BOOL, y <: BOOL] = AND[x, y]
//test
implicitly[ TRUE && FALSE || NOT[FALSE] =:= TRUE]
}
object CondCompilation {
//based on blog: https://michid.wordpress.com/2008/10/29/meta-programming-with-scala-conditional-compilation-and-loop-unrolling/
import Conditions._
def _IF[B] = null.asInstanceOf[B]
//TRUE => Include
object Include {
def apply(block: => Unit) {
block
}
}
//FALSE => Exclude
object Exclude {
def apply(block: => Unit) { }
}
implicit def include(t: TRUE) = Include
implicit def exclude(f: FALSE) = Exclude
}
object IfDefTest {
import Conditions._
import CondCompilation._
type LOG = TRUE
type ERR = TRUE
type WARN = FALSE
type DEV = TRUE
def errTest() {
_IF[LOG && ERR] {
println("err")
}
}
def warnTest() {
_IF[LOG && WARN] {
println("warn")
}
}
def main(args: Array[String]) {
errTest()
warnTest()
_IF[DEV] {
println("dev")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment