# Binary (or String) interpolation

**URL:** <https://erlangforums.com/t/binary-or-string-interpolation/2940>\
**Category:** Questions / Help\
**Tags:** binary\
**Created:** [October 10, 2023, 7:20am UTC](https://erlangforums.com/t/binary-or-string-interpolation/2940 "2023-10-10T07:20:21Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![carlotm](https://erlangforums.com/user_avatar/erlangforums.com/carlotm/32/1870_2.png) [@carlotm](https://erlangforums.com/u/carlotm)\
**Post date:** [October 10, 2023, 7:20am UTC](https://erlangforums.com/t/binary-or-string-interpolation/2940/1 "2023-10-10T07:20:21Z")

</div>

Hi all,

I would like to interpolate a string or a binary.  
I’d like to get: `"Some Foo text"` or `<<"Some Foo text">>`  
Given `X = "Foo"` or `X = <<"Foo">>`

This snippet is working:

```erlang
X = "Foo",
Result = lists:flatten(io_lib:format("Some ~s text", [X])),

```

I am wondering if there are more concise way to achieve the same result.

I read about the bit syntax, but can’t make it work.  
This is what I tried (which is not working):

```erlang
X = <<"Foo">>,
Title = <<"Some ",X/utf8," text">>,

```

Thanks a lot  
Cheers!

---

<div class="post-metadata">

**Author:** ![TD5](https://erlangforums.com/user_avatar/erlangforums.com/td5/32/1590_2.png) [@TD5](https://erlangforums.com/u/TD5)\
**Post date:** [October 10, 2023, 8:49am UTC](https://erlangforums.com/t/binary-or-string-interpolation/2940/2 "2023-10-10T08:49:08Z")

</div>

Try:

```erlang
X = <<"Foo"/utf8>>,
Title = <<"Some ",X/binary," text">>,

```

In the future, [there may be more convenient ways to do a similar thing](https://github.com/erlang/otp/pull/7343).

---

<div class="post-metadata">

**Author:** ![dgud](https://erlangforums.com/user_avatar/erlangforums.com/dgud/32/191_2.png) [@dgud](https://erlangforums.com/u/dgud)\
**Post date:** [October 10, 2023, 9:09am UTC](https://erlangforums.com/t/binary-or-string-interpolation/2940/3 "2023-10-10T09:09:53Z")

</div>

Though it might be cheaper to keep them as iolists,  
["Some “, X, " text”]  
or  
[\<\<“Some “\>\>, X, \<\<” text”\>\>]

Most io functions take iolists as input, so the lists:flatten/1 can/should be avoided.

---

<div class="post-metadata">

**Author:** ![carlotm](https://erlangforums.com/user_avatar/erlangforums.com/carlotm/32/1870_2.png) [@carlotm](https://erlangforums.com/u/carlotm)\
**Post date:** [October 10, 2023, 9:18am UTC](https://erlangforums.com/t/binary-or-string-interpolation/2940/4 "2023-10-10T09:18:58Z")

</div>

In this context the formatting with placeholders is preferred, as the word order may change in different languages.

I tried removing the `flatten` and it is indeed working the same 🙂  
I tried searching for `iolist` in the documentation but I cannot find any useful info,  
can someone point me where `iolist` is documented?

Thank you

---

<div class="post-metadata">

**Author:** ![dgud](https://erlangforums.com/user_avatar/erlangforums.com/dgud/32/191_2.png) [@dgud](https://erlangforums.com/u/dgud)\
**Post date:** [October 10, 2023, 9:36am UTC](https://erlangforums.com/t/binary-or-string-interpolation/2940/5 "2023-10-10T09:36:21Z")

</div>

See the iodata and iolists in table 7.1  
[https://www.erlang.org/doc/reference\_manual/typespec#types-and-their-syntax](https://www.erlang.org/doc/reference_manual/typespec#types-and-their-syntax)

Even better is to look at [Unicode chardata or charlist](https://www.erlang.org/doc/man/unicode#type-chardata)

---

<div class="post-metadata">

**Author:** ![carlotm](https://erlangforums.com/user_avatar/erlangforums.com/carlotm/32/1870_2.png) [@carlotm](https://erlangforums.com/u/carlotm)\
**Post date:** [October 10, 2023, 9:39am UTC](https://erlangforums.com/t/binary-or-string-interpolation/2940/6 "2023-10-10T09:39:11Z")

</div>

Thank you, will do.

---

<div class="post-metadata">

**Author:** ![eproxus](https://erlangforums.com/user_avatar/erlangforums.com/eproxus/32/452_2.png) [@eproxus](https://erlangforums.com/u/eproxus)\
**Post date:** [October 11, 2023, 1:27pm UTC](https://erlangforums.com/t/binary-or-string-interpolation/2940/7 "2023-10-11T13:27:46Z")

</div>

> [@carlotm](#):
>
> In this context the formatting with placeholders is preferred, as the word order may change in different languages.

I/O lists are the preferred way to concatenate data like this in Erlang. You can easily do dynamic stuff, e.g. `["foo", dynamic(Input), "bar"]` which will get rendered properly and efficiently when it leaves the system through a socket, file, standard out etc.

---

<div class="post-metadata">

**Author:** ![fancycade](https://erlangforums.com/user_avatar/erlangforums.com/fancycade/32/1187_2.png) [@fancycade](https://erlangforums.com/u/fancycade)\
**Post date:** [October 12, 2023, 3:50am UTC](https://erlangforums.com/t/binary-or-string-interpolation/2940/8 "2023-10-12T03:50:57Z")

</div>

This is the real answer. Nice way to take advantage of iolist behavior.

---

<div class="post-metadata">

**Author:** ![carlotm](https://erlangforums.com/user_avatar/erlangforums.com/carlotm/32/1870_2.png) [@carlotm](https://erlangforums.com/u/carlotm)\
**Post date:** [October 12, 2023, 4:51am UTC](https://erlangforums.com/t/binary-or-string-interpolation/2940/9 "2023-10-12T04:51:44Z")

</div>

> [@eproxus](#):
>
> I/O lists are the preferred way to concatenate data like this in Erlang. You can easily do dynamic stuff, e.g. `["foo", dynamic(Input), "bar"]` which will get rendered properly and efficiently when it leaves the system through a socket, file, standard out etc.

Ok.

I suppose I will ignore translations for now.  
I know they will come though, (will search for a gettext library that day, and hopefully one that supports interpolation)

Cheers!

---

<div class="post-metadata">

**Author:** ![eproxus](https://erlangforums.com/user_avatar/erlangforums.com/eproxus/32/452_2.png) [@eproxus](https://erlangforums.com/u/eproxus)\
**Post date:** [October 12, 2023, 7:33am UTC](https://erlangforums.com/t/binary-or-string-interpolation/2940/10 "2023-10-12T07:33:41Z")

</div>

> [@carlotm](#):
>
> I suppose I will ignore translations for now.

If you use IO lists you get both performance and dynamic content, such as translations. Example:

```erlang
[?TXT2("Hello", LangCode), $\s, UserName, $!]

```

Which would generate for e.g. Swedish `["Hej", $\s, "Carlo", $!]` which when outputted would be concatenated by the Erlang VM to `"Hej Carlo!"`.

---

<div class="post-metadata">

**Author:** ![carlotm](https://erlangforums.com/user_avatar/erlangforums.com/carlotm/32/1870_2.png) [@carlotm](https://erlangforums.com/u/carlotm)\
**Post date:** [October 12, 2023, 7:45am UTC](https://erlangforums.com/t/binary-or-string-interpolation/2940/11 "2023-10-12T07:45:37Z")

</div>

> [@eproxus](#):
>
> If you use IO lists you get both performance and dynamic content

But I am stuck with the order of the list.  
In many cases the order of the dynamic and static content changes based on the language.

Example:

English → `The user "UUU" has finished the task "TTT".`  
Deutsch → `Der Benutzer "UUU" hat die Aufgabe "TTT" abgeschlossen.`

Where `UUU` and `TTT` are the dynamic parts.

Or am I missing something here?

Cheers!

---

<div class="post-metadata">

**Author:** ![eproxus](https://erlangforums.com/user_avatar/erlangforums.com/eproxus/32/452_2.png) [@eproxus](https://erlangforums.com/u/eproxus)\
**Post date:** [October 12, 2023, 8:11am UTC](https://erlangforums.com/t/binary-or-string-interpolation/2940/12 "2023-10-12T08:11:40Z")

</div>

I haven’t used gettext at all, but I would think a good translation libraries should have some templating functionality.

English → `The user "${USER}" has finished the task "${TASK}"`  
Deutsch → `Der Benutzer "${USER}" hat die Aufgabe "${TASK}" abgeschlossen.`

```erlang

```

---

<div class="post-metadata">

**Author:** ![carlotm](https://erlangforums.com/user_avatar/erlangforums.com/carlotm/32/1870_2.png) [@carlotm](https://erlangforums.com/u/carlotm)\
**Post date:** [October 12, 2023, 8:14am UTC](https://erlangforums.com/t/binary-or-string-interpolation/2940/13 "2023-10-12T08:14:23Z")

</div>

Yeah yeah, pretty sure as well.

This one looks sick:

> **[GitHub - ergenius/t\_\_: Erlang gettext](https://github.com/ergenius/t__#singular-terms-with-interpolation)**
>
> Erlang gettext. Contribute to ergenius/t\_\_ development by creating an account on GitHub.

I’ll stick with iolists for now and see when I’ll need some more advanced stuff

Cheers!

---

<div class="post-metadata">

**Author:** ![williamthome](https://erlangforums.com/user_avatar/erlangforums.com/williamthome/32/471_2.png) [@williamthome](https://erlangforums.com/u/williamthome)\
**Post date:** [October 12, 2023, 12:08pm UTC](https://erlangforums.com/t/binary-or-string-interpolation/2940/14 "2023-10-12T12:08:54Z")

</div>

FWIW, I created just for fun a lib that does string interpolation:

> **[GitHub - williamthome/interpolate: An Erlang library to interpolate strings.](https://github.com/williamthome/interpolate)**
>
> An Erlang library to interpolate strings. Contribute to williamthome/interpolate development by creating an account on GitHub.

> **[Erlang Interpolate - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=williamthome.erlang-interpolate)**
>
> Extension for Visual Studio Code - Syntax highlighter to the Erlang Interpolate lib.

BTW, I recommend the use of [IO lists](https://github.com/gar1t/erlang-patterns/blob/master/patterns/iolist.md).

---

<div class="post-metadata">

**Author:** ![eproxus](https://erlangforums.com/user_avatar/erlangforums.com/eproxus/32/452_2.png) [@eproxus](https://erlangforums.com/u/eproxus)\
**Post date:** [October 12, 2023, 12:52pm UTC](https://erlangforums.com/t/binary-or-string-interpolation/2940/15 "2023-10-12T12:52:25Z")

</div>

> [@williamthome](#):
>
> BTW, I recommend the use of [IO lists](https://github.com/gar1t/erlang-patterns/blob/master/patterns/iolist.md).

Yeah, it is often I see superfluous `iolist_to_binary/1` or `lists:flatten/1` calls when they are not necessary in Erlang. It’s a common beginner anti-pattern.

---

<div class="post-metadata">

**Author:** ![nzok](https://erlangforums.com/letter_avatar_proxy/v4/letter/n/4af34b/32.png) [@nzok](https://erlangforums.com/u/nzok)\
**Post date:** [October 13, 2023, 4:44am UTC](https://erlangforums.com/t/binary-or-string-interpolation/2940/16 "2023-10-13T04:44:33Z")

</div>

Is the word order the only thing that may change  
with language? I used to teach students about  
internationalisation, and there’s a long long list  
of things.

- Dates and times are a big one.  
It’s not just that months and days have different  
names in different languages, the whole structure  
of the calendar may be different. What if your  
customer wants dates displayed on the Hindu  
traditional calendar? (In this country there are  
the Gregorian calendar with English words, the  
Gregorian calendar with Maori words, and N versions  
of “the” traditional Maori calendar, with different  
ideas about when to start a new year. You are NOT  
going to be able to format dates on any of the  
traditional calendars with C’s strftime() or its  
analogues in other languages.)
- Numbers. Different rules for which characters are  
grouping characters and where they go. And of  
course there are different digits. Unicode 13 had  
64 honest-to-goodness sets of digits, not counting  
21 oddballs.
- Currency. It’s not just formatting, it’s conversion.  
I have free account with [OpenExchangeRates.com](http://OpenExchangeRates.com), but  
that limits how often I can access it. Speaking of  
formatting, there is a fundamental problem with  
relying on C’s locale support. If you want guidance  
for how to display Yuan in Australia, you’re out of  
luck. The C locale model says “if you’re in Australia  
you only deal with Australian dollars, so XXXX you.”  
This really is not the kind of stuff that you can  
reasonably encode in a string.
- Weights and measures. Obvious. But there are formatting  
differences as well as differences in what the units are.
- Place names. The same place may have different names  
even in the same country (Wellington vs Pōneke, for  
example). We really need a decent multilingual gazeteer.

---

<div class="post-metadata">

**Author:** ![carlotm](https://erlangforums.com/user_avatar/erlangforums.com/carlotm/32/1870_2.png) [@carlotm](https://erlangforums.com/u/carlotm)\
**Post date:** [October 13, 2023, 6:30am UTC](https://erlangforums.com/t/binary-or-string-interpolation/2940/17 "2023-10-13T06:30:31Z")

</div>

Yeah.  
Indeed making an application truly “international” involves much more than just translate messages.

BTW in Elixir I am using this library [GitHub - elixir-cldr/cldr: Elixir implementation of CLDR/ICU](https://github.com/elixir-cldr/cldr)  
which does a very good job.

---

<div class="post-metadata">

**Author:** ![carlotm](https://erlangforums.com/user_avatar/erlangforums.com/carlotm/32/1870_2.png) [@carlotm](https://erlangforums.com/u/carlotm)\
**Post date:** [October 13, 2023, 6:30am UTC](https://erlangforums.com/t/binary-or-string-interpolation/2940/18 "2023-10-13T06:30:53Z")

</div>

Nice one!  
Thanks
