groovy, java, scala: Fix (first nil) and (rest nil)
authorDov Murik <dov.murik@gmail.com>
Wed, 3 Feb 2016 20:19:35 +0000 (15:19 -0500)
committerDov Murik <dov.murik@gmail.com>
Thu, 4 Feb 2016 02:23:49 +0000 (21:23 -0500)
groovy/core.groovy
java/src/main/java/mal/core.java
scala/core.scala

index d266fad..175e41d 100644 (file)
@@ -91,8 +91,8 @@ class core {
         "cons": { a -> [a[0]] + (a[1] as List) },
         "concat": core.&do_concat,
         "nth": core.&do_nth,
-        "first": { a -> a[0].size() == 0 ? null : a[0][0] },
-        "rest": { a -> a[0].drop(1) },
+        "first": { a -> a[0] == null || a[0].size() == 0 ? null : a[0][0] },
+        "rest": { a -> a[0] == null ? [] as List : a[0].drop(1) },
         "empty?": { a -> a[0] == null || a[0].size() == 0 },
         "count": { a -> a[0] == null ? 0 : a[0].size() },
         "apply": core.&do_apply,
index d93566d..5f76f64 100644 (file)
@@ -373,14 +373,22 @@ public class core {
 
     static MalFunction first = new MalFunction() {
         public MalVal apply(MalList a) throws MalThrowable {
-            MalList ml = ((MalList)a.nth(0));
+            MalVal exp = a.nth(0);
+            if (exp == Nil) {
+                return Nil;
+            }
+            MalList ml = ((MalList)exp);
             return ml.size() > 0 ? ml.nth(0) : Nil;
         }
     };
 
     static MalFunction rest = new MalFunction() {
         public MalVal apply(MalList a) throws MalThrowable {
-            MalList ml = ((MalList)a.nth(0));
+            MalVal exp = a.nth(0);
+            if (exp == Nil) {
+                return new MalList();
+            }
+            MalList ml = ((MalList)exp);
             return ml.rest();
         }
     };
index df6156b..210204b 100644 (file)
@@ -83,13 +83,18 @@ object core {
   }
 
   def first(a: List[Any]): Any = {
-    val lst = a(0).asInstanceOf[MalList].value
-    if (lst.length > 0) lst(0) else null
+    a(0) match {
+      case null => null
+      case ml: MalList => {
+        val lst = ml.value
+        if (lst.length > 0) lst(0) else null
+      }
+    }
   }
 
   def rest(a: List[Any]): Any = {
     a(0) match {
-      case null => true
+      case null => _list()
       case ml: MalList => _list(ml.drop(1).value:_*)
     }
   }