Whats ++ and <>

So <> basically connects two items right?
Hello <> world => Hello world

But whats ++? can anyone give me an example

Helpful resources:

  1. Kernel list concatenation (++) operator
  2. Kernel binary concatenation (<>) operator
2 Likes

they join text in different quotes :smiley:

iex(4)> 'hello' ++ 'world'
'helloworld'
iex(5)> "hello" <> "world" 
"helloworld"
2 Likes

<> joins two strings (binaries)

++ joins two lists (including charlists)

Have in mind that there’s a performance penalty for using ++ because it has to fully traverse the first list, from start to end, before doing concatenation. This technique can accumulate surprising amount of slowness in your app if you use it liberally.

Usually it’s preferable to iteratively prepend items to the final desired list (which is an O(1) operation) and Enum.reverse the list when done.

3 Likes

a <> b has even worse complexity than a ++ b as it needs to do a full copy of both sides of the operator for each append. Unless you make sure to trigger the non-copying append optimization. Fortunately copying binary memory is heavily optimized by using memcpy so it is not noticeable as quickly as when using ++.

Anyway, when wanting to append binaries, I always try to append them into a list and flatten them when needed (or not at all if they can be passed to the socket unflattened). Example:

## Don't do this
:gen_tcp.send(socket, bin1 <> bin2)
## When you can do this
:gen_tcp.send(socket, [bin1, bin2])
17 Likes

Oh yeah, I always use iolists when the API allows it. Thanks for the extra details. :+1:

so <> is better than ++?

Nah, it just depends on the data types you are using.

  • if you’re handling lists, use ++
  • if you’re handling strings, use <>

The subtlety in Elixir is that String come in two flavors:

  • charlist, which is a list of chars, and is written with simple quotes can be concatenated with ++: 'hello ' ++ 'world' == 'hello world'. It’s mainly inherited from Erlang and not used that much in Elixir apps
  • binaries which use double-quotes and can be concatenated with <> : "hello " <> "world" == "hello world"
2 Likes

According to @garazdawi it seems that <> is potentially worse than ++. I think both he and @dimitarvp are suggesting that you should try to avoid concatenation calls (especially if it’s a recursive or iterative process). Concatenation and appending to a list is slower than PREpending because of the nature of the data structure. Lists in Elixir are linked lists, which means that to append to the end you have to iterate over the whole list.
See this definition from the Erlang documentation for append (which is what Elixir’s ++ is using under the hood:

append([H|T], Tail) ->
    [H|append(T, Tail)];
append([], Tail) ->
    Tail.

So the function appending the two lists will have time complexity proportional to the length of the first list argument.

4 Likes