Gleam Strings
Strings store text in Gleam. Every name, message, URL, and label in your program is a string. Gleam strings are immutable, UTF-8 encoded, and backed by an efficient binary representation inherited from Erlang.
Creating Strings
Wrap text in double quotes to create a string:
let city = "Bengaluru"
let greeting = "Hello, World!"
let empty = ""
let number_as_text = "42"Note that "42" is a String, not an Int. The quotes make it text. You cannot perform arithmetic on it without converting it first.
String Concatenation
Join two strings together with the <> operator:
let first_name = "Ananya"
let last_name = "Sharma"
let full_name = first_name <> " " <> last_name
// full_name = "Ananya Sharma"
Concatenation Diagram
──────────────────────────────────────────────
"Ananya" <> " " <> "Sharma"
│ │ │
└─────┬─────┘ │
"Ananya " <> "Sharma"
└────┬────┘
"Ananya Sharma"
String Length
Use the gleam/string module to measure a string's length in characters:
import gleam/string
let name = "Gleam"
let len = string.length(name) // 5Gleam counts Unicode characters, not raw bytes. The emoji "🎉" has a byte length of 4 but a character length of 1. string.length gives you the character count — what users actually see.
Common String Functions
string Module — Frequently Used Functions
──────────────────────────────────────────────────────────────
Function │ What It Does │ Example
────────────────────────┼──────────────────────────┼──────────────────────
string.length(s) │ Count characters │ length("hi") → 2
string.uppercase(s) │ Convert to uppercase │ uppercase("hi") → "HI"
string.lowercase(s) │ Convert to lowercase │ lowercase("HI") → "hi"
string.trim(s) │ Remove leading/trailing │ trim(" hi ") → "hi"
│ whitespace │
string.trim_start(s) │ Remove leading spaces │ trim_start(" hi") → "hi"
string.trim_end(s) │ Remove trailing spaces │ trim_end("hi ") → "hi"
string.contains(s, sub) │ Check if substring exists│ contains("gleam","lea") → True
string.starts_with(s,p) │ Check prefix │ starts_with("gleam","gl") → True
string.ends_with(s, p) │ Check suffix │ ends_with("gleam","am") → True
string.split(s, sep) │ Split into a list │ split("a,b,c", ",") → ["a","b","c"]
string.join(list, sep) │ Join list into string │ join(["a","b"], "-") → "a-b"
string.replace(s,f,r) │ Replace occurrences │ replace("cat","c","b") → "bat"
string.reverse(s) │ Reverse characters │ reverse("gleam") → "maelg"
string.slice(s, i, len) │ Extract substring │ slice("gleam",0,3) → "gle"
Examples in Code
import gleam/string
import gleam/io
pub fn main() {
let raw = " Hello, Gleam! "
raw
|> string.trim
|> string.uppercase
|> io.println
// Output: HELLO, GLEAM!
let csv = "apple,banana,cherry"
let fruits = string.split(csv, ",")
io.debug(fruits)
// Output: ["apple", "banana", "cherry"]
}
String Interpolation with string.concat
Gleam does not support template literals like JavaScript's backtick syntax. Build dynamic strings by concatenating or using string.concat:
import gleam/string
import gleam/int
let name = "Dev"
let score = 95
let message = string.concat(["Player ", name, " scored ", int.to_string(score), " points!"])
// "Player Dev scored 95 points!"string.concat takes a list of strings and joins them all — no separator between parts.
Checking String Contents
import gleam/string
let email = "user@example.com"
let has_at = string.contains(email, "@") // True
let is_empty = string.is_empty(email) // False
let starts = string.starts_with(email, "user") // True
Visualizing contains()
──────────────────────────────────────────────
email = "user@example.com"
↑
Looking for "@" inside the string...
Found it at position 4 → returns True
Slicing Strings
Extract a portion of a string with string.slice:
import gleam/string
let word = "programming"
// 0123456789...
let first_four = string.slice(word, 0, 4) // "prog"
let middle = string.slice(word, 4, 3) // "ram"
Slice Diagram: string.slice("programming", 0, 4)
──────────────────────────────────────────────────
p r o g r a m m i n g
0 1 2 3 4 5 6 7 8 9 10
└─────────┘
start=0, length=4 → "prog"
Splitting and Joining
import gleam/string
// Split a sentence into words
let sentence = "the quick brown fox"
let words = string.split(sentence, " ")
// ["the", "quick", "brown", "fox"]
// Join them back with a dash
let dashed = string.join(words, "-")
// "the-quick-brown-fox"
Split → Transform → Join Pattern
──────────────────────────────────────────────────
"the quick brown fox"
↓ split(" ")
["the", "quick", "brown", "fox"]
↓ join("-")
"the-quick-brown-fox"
Converting to and from String
import gleam/int
import gleam/float
// Number to String
let n = int.to_string(42) // "42"
let f = float.to_string(3.14) // "3.14"
// String to Number (returns Result type)
let parsed_int = int.parse("123") // Ok(123)
let bad_parse = int.parse("hello") // Error(Nil)
int.parse returns a Result because parsing can fail — the string might not be a valid number. The Result type forces you to handle both cases. You learn about Result in detail in a later topic.
String Comparison
Use == and != to compare strings:
let a = "gleam"
let b = "gleam"
let c = "elixir"
let same = a == b // True
let different = a != c // True
Gleam compares strings by their content, character by character. Case matters: "Gleam" == "gleam" is False. Use string.lowercase on both strings before comparing if you want case-insensitive equality.
Practical Example — Name Formatter
import gleam/string
import gleam/io
pub fn format_name(first: String, last: String) -> String {
let clean_first = first |> string.trim |> string.lowercase
let clean_last = last |> string.trim |> string.lowercase
let cap_first = string.uppercase(string.slice(clean_first, 0, 1))
<> string.slice(clean_first, 1, string.length(clean_first) - 1)
let cap_last = string.uppercase(string.slice(clean_last, 0, 1))
<> string.slice(clean_last, 1, string.length(clean_last) - 1)
cap_first <> " " <> cap_last
}
pub fn main() {
io.println(format_name(" priya ", "SHARMA"))
// Output: Priya Sharma
}Key Points
String Essentials
──────────────────────────────────────────────────
1. Always wrapped in double quotes
2. UTF-8 encoded — supports all languages + emoji
3. Immutable — string functions return new strings
4. Join with <> operator
5. Use gleam/string module for all operations
6. No built-in template literals — use string.concat
7. Parsing numbers from strings returns a Result type
Gleam's string functions are pure — they return new strings instead of modifying existing ones. This makes your code predictable: a string you pass into a function never changes, no matter what happens inside that function.
