ELIXIR / CHAPTER 03
Binary text and Unicode boundaries
IntermediateChoose bytes, code points, or graphemes deliberately.
By the end of this chapter
- Distinguish byte_size from String.length
- Match binary fields explicitly
- Avoid atom creation from arbitrary input
The idea
Elixir strings are UTF-8 binaries, while charlists are lists of code points. Byte size measures storage and may differ from a text operation’s character count. String.length counts grapheme clusters, which can include more than one code point. Choose the unit from the task: network framing often uses bytes, while user-facing cursor or length behavior may require graphemes.
Binary patterns can extract fields with explicit sizes and types, making byte-oriented protocols readable. Text decoding still needs an encoding contract; slicing arbitrary bytes can split a UTF-8 sequence. Atoms serve as bounded program identifiers, not an unlimited storage format for untrusted strings. Avoid converting arbitrary external labels into newly created atoms when ordinary string keys meet the requirement.
text = "é"
IO.inspect(byte_size(text))
IO.inspect(String.length(text))
<<first::8, second::8>> = text
IO.inspect({first, second})2
1
{195, 169}The UTF-8 encoding contains two bytes while the displayed grapheme is one character for String.length.
Try it yourself
Validate a byte-framed message separately from its UTF-8 text payload.
Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.
CHECK YOUR UNDERSTANDING