// compile: kotlinc error2.kt -include-runtime -d error2.jar // run: java -jar error2.jar // Kotlin has a rather unique feature: accessing a value that could be null // requires a check, using an if statement, that the value is not null first. // The check is enforced at compile time. Placing ? after a type makes it // nullable. Is this a good idea? // basic class for linked list: class Node(var car:Int, var cdr:Node?) // car, cdr are public properties { // function to find length of list fun length():Int { var i:Node? = this var ax = 0 // type inferred as Int while (i!=null) { ax++; i=i.cdr; } //clever compiler? return ax; }//length // function to add to end of list, with intensional error fun add(x:Int) { var len = length(); // type inferred var i:Node? = this // type declaration needed for nullable type while (0 < len-- && i!=null) { i = i.cdr } // won't compile without i!=null check above //i.cdr = Node(x,null); // compiler error, but are we saved? if (i!=null) i.cdr = Node(x,null); // it works, right??? }//add }//class Node // Function to return last value in a list. this function also // illustrates an error condition caused by type casting in C#/Java: // The line with val x:Any? out would compile but give a runtime error. // 'Any' is Kotlin's version of the Object supertype and 'as' downcasts. fun last(m:Node?):Int { var i:Node? = m; while (i!=null && i.cdr!=null) i=i.cdr; //val x:Any? = i; return x as Int //compiles with type casting //return i.car; compiler error! if (i!=null) return i.car; else throw RuntimeException("bad node"); } fun main(argv:Array) { val m:Node = Node(3,Node(4,Node(5,null))); println(m.car); // works //println(m.cdr.car); // compiler error, check neededfor nullable m.cdr if (m.cdr != null) println(m.cdr?.car); println(m.cdr?.car); // OK println( "last value: "+last(m) ); m.add(7); println( "last value after add(7): "+last(m) ); }//main /* What's wrong with the add function has nothing to do with not checking if i is null, but with the how the len variable is decremented. It is not the fault of the programming language if the programmer doesn't know the right algorithm. It's very unlikely, in most cases, that the compiler can figure out what the right algorithm should be. Without the if (i!=null) check, the program won't compile. An average programmer might be compelled by the compiler to add the check, but the result is a disaster: for it's still wrong, but won't give any error, either at compile time or at runtime. The C# (Java) version of this program will compile without the if statement, but will throw a null pointer exception any time that the method is called, and so the error is more easily detected. A Kotlin programmer trained to check for null for nullable types will be more likely to write a program with an error that is not as easily detected. This is my opinion, but I do believe that this example shows a flaw in the approach taken by Kotlin's designers. */