While a function in the String module would be more discoverable, I think that rather points to a need for a really good way of discovering all you can do with bitstrings. They're underused exactly because folks don't think to read the Kernel.SpecialForms.<<>> docs when they have a problem they'd solve.
As for taking a hex value, <<0x
1F916::utf8>> does what you'd expect.
You can also `0x1F916 |> List.wrap |> to_string`, if you really care about pipelining. (That'd fall into "overusing pipelining" imho, though.)
I think it has limited use. When are we working with individual codepoints as opposed to a collection of them? And if we have a list of codepoints, we have a CharList. I wouldn't want to see this out there:
codepoints |> Enum.map(&String.from_codepoint) |> Enum.join
- Martin