// Experimenting with Kotlin // compile: kotlinc first.kt -include-runtime -d first.jar // run: java -jar first.jar val pi = 3.1415927; // globals allowed? yes, type inferred var x = 0; // global mutable var named x. My favorite. fun area(radius:Double): Double { return pi*radius*radius; } // Static or dynamic scoping? // Lambda terms? // K combinator lambda x.lambda y.x // fun K(x:A): (B -> A) { return y->x; } // type inference failure val I = {x:Int -> x}; // but val I = {x -> x} won't compile val K = {x:Int -> {_:Int -> x}}; var f = {x:Int -> x+1}; // lambdas are also mutable, good. // Closures? fun makeaccumulator(x:Int): (Int) -> Int { var a = x; // note var, not val, which is immutable //return {y:Int -> {x = y+x; return x;}}; // won't compile, like Python return fun(y:Int):Int { a =y+a ; return a;}; } fun main(argv: Array) { val pi:Double = 0.0; // must use 0.0 for Double println("area of circle with radius 10 is "+area(10.0)); // Static scoping println("but my pi is "+pi) println(I(1)); println(K(1)(2)); val a1:(Int)->Int = makeaccumulator(0); val a2:(Int)->Int = makeaccumulator(0); println(a1(2)); //2 println(a1(2)); //4 println(a2(2)); //2 closures are no problem, as expected fun iseven(x:Int):Boolean {return x%2==0; } var x = 4; when (x) { // is this the same as pattern matching? 1 -> println("is 1") 4, 5 -> println("is 4 or 5") else -> println("huh?") } // unfortunately, this is very limited println(iseven(x)); // local functions ok //// testing the oop code below val t:Expr = Plusexp(Constexp(8),Negexp(Constexp(4))); // 8 + -4 fun eval(e:Expr):Int { when (e) { is Constexp -> return e.intval; // no need to typecast again is Plusexp -> return eval(e.left) + eval(e.right); is Multexp -> return eval(e.left) * eval(e.right); is Negexp -> return -1 * eval(e.sub); //is Plusexp(x,Negexp(y)) -> return eval(x) - eval(y); //NO WAY! //is Negexp(Constexp) -> return -1 * e.sub.intval; //NO CHANCE else -> return 0; } // Not bad, but it can't go deeper. } println("value of expr tree is "+eval(t)); // prints 4 println("depth of expr tree is "+t.depth()); // prints 3 }//main ////// Classes and objects ... for Expression trees interface Expr { fun depth():Int } class Constexp(v:Int) : Expr { val intval = v; override fun depth():Int { return 1; } } class Plusexp(val left:Expr, val right:Expr) : Expr { override fun depth():Int { val dl = left.depth(); val dr = right.depth(); if (dl>dr) return dl+1; else return dr+1; } } class Multexp(val left:Expr, val right:Expr) : Expr { override fun depth():Int { val dl = left.depth(); val dr = right.depth(); if (dl>dr) return dl+1; else return dr+1; } } class Negexp(val sub:Expr) : Expr { override fun depth():Int { return 1+sub.depth(); } }