// C# version of same error (last value of linked list) using System; public class cell { public int car; public cell cdr; public cell(int h, cell t) {car=h; cdr=t;} public int length() { int cx = 0; for(cell i=this;i!=null;i=i.cdr) cx++; return cx; } // method to destructively add new int at end of list, // with an intentional error .. how will it be handled by the // programming language? public void add(int x) { cell i = this; int n = length(); while (n-- >= 0) i = i.cdr; i.cdr = new cell(x,null); } // in Kotlin, this will not compile unless we write the last line with // if (i!=null) i.cdr = new cell(x,null); // This is required even if we fixed the real mistake (--n). So is this // feature of Kotlin really an improvement? In other words, what kind of // errors should be compiler errors? } public class error { public static int lastval(cell M) // program with error { while (M.cdr !=null) M = M.cdr; return (int)(object)M; // compiler error, even with (int)M, but... } public static void Main() { cell M = new cell(2, new cell(4, new cell(6,null))); M.add(8); System.Console.WriteLine(lastval(M) + 2); } } /* C# (and Java) appears to behave better with respect to this kind of error: it will not allow a type cast of M to int or any numerical type. But it's still possible to get this program to compile with more clever type casting. This illustrates an essential problem with any language that relies on subtyping (inheritance) and dynamic dispatch. Type safety is only provided at runtime. This makes C#/Java only slightly better than languages like Python and Ruby (but significantly better than Perl and C/C++) when it comes to type safety. */