Multiple pattern-matching concatenations for the single string

Article autor
September 9, 2025
Multiple pattern-matching concatenations for the single string
Elixir Newsletter
Join Elixir newsletter

Subscribe to receive Elixir news to your inbox every two weeks.

Oops! Something went wrong while submitting the form.
Elixir Newsletter
Expand your skills

Download free e-books, watch expert tech talks, and explore open-source projects. Everything you need to grow as a developer - completely free.

Table of contents

Pattern-matching is one of the finest elixir-lang features. Whoever knows the power of this tool once, will want to use it forever.

It's pretty easy to split and compare the string literal that way. Just like below:

iex(1)> "r" <> _ = "run"
"run"

The problem, though, appears as soon as you try to assign parts of the string twice in the single pattern-match clause. Just like here:

iex(2)> "f" <> _a <> "rre" <> _b <> "t" = "forrest"
** (ArgumentError) the left argument of <> operator inside a match should always be a literal binary because its size cant be verified.

Why? Because, simply, at that complexity level, you might imagine a case with more than one assignment problem solution. Just take a look at the beekeeper's problem example:

iex(3)> "a" <> hive1 <> "b" <> hive2 <> "c" = "abbbbbc"

How do you (and compiler/interpreter) know how many b's are assigned either to the hive1 and hive2? There is more than one possibility. Like

  • hive2 = "bbb" + hive2 = "b"
  • hive2 = "bb" + hive2 = "bb"
  • hive2 = "b" + hive2 = "bbb"

So, what to do? Bitstrings! Or, actually - binaries, which are just bitstrings having divisible by 8 number of bits. Using the power of bytes counting, you can now just use them inside the pattern-match clause.

iex(4)> "f" <> <<_o>> <> "rre" <> <<_s>> <> "t" = "forrest"
"forrest"

iex(5)> "f" <> <<_o, _r, _r>> <> "est" = "forrest"
"forrest"

In most of the cases, it will work well as above. Sometimes, though, you might encounter multi-byte characters. Just like e.g. ü, which fills two of them.

iex(6)> "f" <> <<_>> <> "rrest" = "forrest"
"forrest"

iex(7)> "f" <> <<_>> <> "rrest" = "fürrest"
** (MatchError) no match of right hand side value: "fürrest"

iex(7)> "f" <> <<_, _>> <> "rrest" = "fürrest"
"fürrest"

An easy workaround for that is just to use the ::utf8 modifier.

iex(8)> "f" <> <<_::utf8>> <> "rrest" = "forrest"
"forrest"
iex(9)> "f" <> <<_::utf8>> <> "rrest" = "fürrest"
"fürrest"

Happy hacking!

Work with a team that keeps learning and building better software every day.

Related posts

Dive deeper into this topic with these related posts

No items found.

You might also like

Discover more content from this category

How to install local npm package in a project

In some cases, like for testing purposes, you might want to use an npm package stored on a local machine. Here is how you can do that with one simple command.

How to group and count occurrences of values in Elixir's list

If you ever had to count occurrences of values in Elixir's list, this short post might be helpful for you!

Style spacing between repeated elements in CSS using flex gap

It's a pretty common scenario - you have to place a few elements in equal distances. E.g. unordered list items.