       "nil?" => fn [type] -> type == nil end,
       "true?" => fn [type] -> type == true end,
       "false?" => fn [type] -> type == false end,
+      "string?" => fn [obj] -> String.valid?(obj) end,
       "symbol" => fn [name] -> {:symbol, name} end,
       "read-string" => fn [input] -> Mal.Reader.read_str(input) end,
       "throw" => fn [arg] -> throw({:error, arg}) end,

  defp conj([{:vector, ast, meta} | args]) do
    {:vector, ast ++ args, meta}
  end
end

      "reset!" => &reset!/1,
      "swap!" => &swap!/1,
      "conj" => &conj/1,
      "seq" => &seq/1,
      "time-ms" => fn _ -> :erlang.system_time(:milli_seconds) end,
      "readline" => fn [prompt] -> readline(prompt) end,
      "sequential?" => fn arg -> vector?(arg) or list?(arg) end,
