diff --git a/src/function/builtin/cons/LENGTH.java b/src/function/builtin/cons/LENGTH.java
index 00bbbae..b32d5d1 100644
--- a/src/function/builtin/cons/LENGTH.java
+++ b/src/function/builtin/cons/LENGTH.java
@@ -2,62 +2,49 @@ package function.builtin.cons;
 
 import java.math.BigInteger;
 
-import function.LispFunction;
+import function.*;
 import sexpression.*;
 
-/**
- * LENGTH represents the LENGTH function in Lisp.
- */
 public class LENGTH extends LispFunction {
 
-    /**
-     * Returns the length of the given list.
-     *
-     * @param list
-     *            the list to determine the length of
-     * @return the length of list
-     */
     public static int getLength(Cons list) {
         LENGTH lengthFunction = new LENGTH();
-        LispNumber length = lengthFunction.call(LIST.makeList(list));
+        LispNumber length = lengthFunction.callWithoutArgumentValidation(LIST.makeList(list));
 
         return length.getValue().intValue(); // TODO - return BigInteger when all built-ins use
                                              // ArgumentValidator
     }
 
-    public LispNumber call(Cons argList) {
-        // make sure we have received at least one argument
-        if (argList.nullp()) {
-            Cons originalSExpr = new Cons(new Symbol("LENGTH"), argList);
+    private ArgumentValidator argumentValidator;
 
-            throw new RuntimeException("too few arguments given to LENGTH: " + originalSExpr);
-        }
+    public LENGTH() {
+        this.argumentValidator = new ArgumentValidator("LENGTH");
+        this.argumentValidator.setExactNumberOfArguments(1);
+        this.argumentValidator.setEveryArgumentExpectedType(Cons.class);
+    }
 
-        SExpression argCar = argList.getCar();
-        SExpression argCdr = argList.getCdr();
+    public LispNumber call(Cons argumentList) {
+        argumentValidator.validate(argumentList);
 
-        // make sure we have received only one argument
-        if (!argCdr.nullp()) {
-            Cons originalSExpr = new Cons(new Symbol("LENGTH"), argList);
+        return callTailRecursive(BigInteger.ZERO, argumentList);
+    }
 
-            throw new RuntimeException("too many arguments given to LENGTH: " + originalSExpr);
-        }
+    private LispNumber callWithoutArgumentValidation(Cons argumentList) {
+        return callTailRecursive(BigInteger.ZERO, argumentList);
+    }
 
-        // make sure that the argument is a list
-        if (argCar.listp()) {
-            Cons arg = (Cons) argCar;
+    private LispNumber callTailRecursive(BigInteger accumulatedLength, Cons argumentList) {
+        Cons list = (Cons) argumentList.getCar();
+        Cons restOfList = LIST.makeList(list.getCdr());
 
-            if (arg.nullp()) {
-                return new LispNumber(BigInteger.ZERO);
-            }
+        if (list.nullp())
+            return new LispNumber(accumulatedLength);
 
-            Cons cdr = LIST.makeList(arg.getCdr());
-            LispNumber cdrLength = call(cdr);
+        return callTailRecursive(increment(accumulatedLength), restOfList);
+    }
 
-            return new LispNumber(BigInteger.ONE.add(cdrLength.getValue()));
-        }
-
-        throw new RuntimeException("LENGTH: a proper list must not end with " + argCar);
+    private BigInteger increment(BigInteger number) {
+        return number.add(BigInteger.ONE);
     }
 
 }
diff --git a/src/function/builtin/math/DIVIDE.java b/src/function/builtin/math/DIVIDE.java
index 394dfa7..e2bd744 100644
--- a/src/function/builtin/math/DIVIDE.java
+++ b/src/function/builtin/math/DIVIDE.java
@@ -17,7 +17,7 @@ public class DIVIDE extends LispFunction {
         this.mathFunction = new MathFunction(this::getReciprocal, this::divide);
     }
 
-    public SExpression call(Cons argumentList) {
+    public LispNumber call(Cons argumentList) {
         argumentValidator.validate(argumentList);
 
         return mathFunction.callTailRecursive(argumentList);
diff --git a/src/function/builtin/math/MINUS.java b/src/function/builtin/math/MINUS.java
index 807e5a6..a84f101 100644
--- a/src/function/builtin/math/MINUS.java
+++ b/src/function/builtin/math/MINUS.java
@@ -17,7 +17,7 @@ public class MINUS extends LispFunction {
         this.mathFunction = new MathFunction(this::additiveInverse, this::subtract);
     }
 
-    public SExpression call(Cons argumentList) {
+    public LispNumber call(Cons argumentList) {
         argumentValidator.validate(argumentList);
 
         return mathFunction.callTailRecursive(argumentList);
diff --git a/src/function/builtin/math/MULTIPLY.java b/src/function/builtin/math/MULTIPLY.java
index c48981d..75de4d6 100644
--- a/src/function/builtin/math/MULTIPLY.java
+++ b/src/function/builtin/math/MULTIPLY.java
@@ -14,7 +14,7 @@ public class MULTIPLY extends LispFunction {
         this.mathFunction = new MathFunction(number -> number, this::multiply);
     }
 
-    public SExpression call(Cons argumentList) {
+    public LispNumber call(Cons argumentList) {
         argumentValidator.validate(argumentList);
 
         return mathFunction.callTailRecursive(new Cons(LispNumber.ONE, argumentList));
diff --git a/src/function/builtin/math/MathFunction.java b/src/function/builtin/math/MathFunction.java
index e211e5a..5a5d443 100644
--- a/src/function/builtin/math/MathFunction.java
+++ b/src/function/builtin/math/MathFunction.java
@@ -15,7 +15,7 @@ class MathFunction {
         this.multipleValueOperation = multipleValueOperation;
     }
 
-    public SExpression callTailRecursive(Cons argumentList) {
+    public LispNumber callTailRecursive(Cons argumentList) {
         Cons remainingArguments = (Cons) argumentList.getCdr();
         SExpression firstArgument = argumentList.getCar();
         LispNumber number1 = (LispNumber) firstArgument;
diff --git a/src/function/builtin/math/PLUS.java b/src/function/builtin/math/PLUS.java
index a96a450..3efb2a5 100644
--- a/src/function/builtin/math/PLUS.java
+++ b/src/function/builtin/math/PLUS.java
@@ -14,7 +14,7 @@ public class PLUS extends LispFunction {
         this.mathFunction = new MathFunction(number -> number, this::add);
     }
 
-    public SExpression call(Cons argumentList) {
+    public LispNumber call(Cons argumentList) {
         argumentValidator.validate(argumentList);
 
         return mathFunction.callTailRecursive(new Cons(LispNumber.ZERO, argumentList));
diff --git a/test/function/builtin/cons/LENGTHTester.java b/test/function/builtin/cons/LENGTHTester.java
new file mode 100644
index 0000000..5786680
--- /dev/null
+++ b/test/function/builtin/cons/LENGTHTester.java
@@ -0,0 +1,47 @@
+package function.builtin.cons;
+
+import static testutil.TestUtilities.*;
+
+import org.junit.Test;
+
+import function.ArgumentValidator.*;
+
+public class LENGTHTester {
+
+    @Test
+    public void testLengthOfNil() {
+        String input = "(length '())";
+
+        assertSExpressionsMatch(evaluateString(input), parseString("0"));
+    }
+
+    @Test
+    public void testLengthOfListOfOneElement() {
+        String input = "(length '(1))";
+
+        assertSExpressionsMatch(evaluateString(input), parseString("1"));
+    }
+
+    @Test
+    public void testLengthOfListOfManyElements() {
+        String input = "(length '(1 2 3 4 5))";
+
+        assertSExpressionsMatch(evaluateString(input), parseString("5"));
+    }
+
+    @Test(expected = BadArgumentTypeException.class)
+    public void testLengthWithNonList() {
+        evaluateString("(length 'x)");
+    }
+
+    @Test(expected = TooManyArgumentsException.class)
+    public void testLengthWithTooManyArguments() {
+        evaluateString("(length '(1 2) '(1 2))");
+    }
+
+    @Test(expected = TooFewArgumentsException.class)
+    public void testLengthWithTooFewArguments() {
+        evaluateString("(length)");
+    }
+
+}