   def parse(<<hundreds::utf8, tens::utf8, ones::utf8>>, _), do: parse(<<hundreds::utf8, tens::utf8, ones::utf8>>)
 
   # thousands and up here... recursive call... this is most of the magic
-  def parse(<<long_binary::binary>>, [next | rest]) do
+  def parse(<<long_binary::binary>>, [illion | rest]) do
     { further_digits, these_digits } = String.split_at(long_binary, -3)
     if String.match?(further_digits, ~r/0{3}$/) do
-      # we have to skip the trio join word if the next trio of parseable digits to the left is all zeroes basically
+      # we have to skip the trio join word if the next trio of parseable digits to the left is all zeroes, basically
+      # Otherwise you'd get stuff like "six trillion billion million thousand"
       parse(<<further_digits::binary>>, rest) <> parse(<<these_digits::binary>>)
     else
-      parse(<<further_digits::binary>>, rest) <> " #{next} " <> parse(<<these_digits::binary>>)
+      parse(<<further_digits::binary>>, rest) <> " #{illion} " <> parse(<<these_digits::binary>>)
     end
+  end
+
+  # numeric string validation
+  defp validate?(str) do
+    String.match?(str, ~r/^-?[0-9]+$/)
   end
 
 end

  def parse("8"), do: "eight"
  def parse("9"), do: "nine"

  # fallthrough case for any binary strings that haven't matched yet
  def parse(<<unknown::utf8>>) when is_binary(unknown) do
    IO.puts "parsing #{unknown}"
    raise ArgumentError, message: "Unknown digit(s): #{unknown}"
  end

  # tens
  def parse("00"), do: ""
  def parse("10"), do: "ten"

    else
      raise ArgumentError, message: "Unknown digit(s): #{long_binary}"
    end
  end

  # End case where we run out of words. Oops.
