Also, about constructing the module itself. We have macros exactly not to use string concatenation for manipulating code:
types = ~w[function nil integer binary bitstring list map float atom tuple pid port reference]
code = for type <- types, fun = :"is_#{type}" do
quote do: def typeof(x) when unquote(fun)(x), do: unquote(type)
end
Module.create(Util, code, Macro.Env.location(__ENV__))
Also binary should be checked before bitstring, since every binary is a bitstring, so otherwise you’d only get bitstrings.