// compile: kotlinc error.kt -include-runtime -d error.jar // run: java -jar error.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 (method) to add to end of list, with intensional error fun add(x:Int) { var i:Node? = this; while (i!=null) i = i.cdr;// gives compiler warnings while (x>0 && i!=null) i=i.cdr; // no compiler warnings with x>0 !!!! //i.cdr = Node(x,null); compiler error if (i!=null) i.cdr = Node(x,null); //note: error in code! } } /* What's wrong with the add function is not the lack of a check if i is null, but with the while loop. That is, the real problem is the programmer's lack of clear understanding of linked lists and pointers. It is not the fault of the programming language if the programmer doesn't know the algorithm. Trying to teach the programmer how to program is not the job of the compiler. 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. */ // function to return last value in list, with intentional error: // a pointer to a one-element list is returned, not the value itself. // this program, with the val x:Any? line uncommented, will compile but // give a runtime error. Any is Kotlin's version of the Object supertype. // So this problem with type casting and static type safet doesn't go away. 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(m) ); m.add(7); println( "after add(7): "+last(m) ); }//main