What is different in Erlang is that strings are a bit messed up in that they are linked lists of numbers. What you are suggesting (constructing the actual string in-place) works fine in Erlang, too, but has a bit of a funky syntax:
welcome_user(Username) ->
<< <<"Welcome ">>/binary, Username/binary, <<"!">>/binary >>.
However, the main advantage of using io_lists instead is that `["Welcome", Username, "!"]` has constant complexity with regard to the length of `Username`.