Why does string concatenation with + cause a compiler error in EK9?
← Common String Operations · Ref: Q309
EK9 enforces string interpolation over concatenation chains. If you concatenate 3 or more parts with the + operator where the result is a String, the compiler produces error E11068: PREFER_STRING_INTERPOLATION.
WHY IT IS AN ERROR
Each + on strings calls the _add operator, creating a new intermediate String. A chain of N concatenations creates N-1 temporary objects. String interpolation compiles to a bespoke STRING_INTERPOLATION IR instruction that backends optimise to one allocation:
JVM: invokedynamic StringConcatFactory.makeConcatWithConstants() LLVM: single allocation with pre-calculated length + memcpy
Beyond performance, interpolation shows the output shape directly. Concatenation requires mentally assembling fragments separated by + operators.
WHAT TRIGGERS E11068
A chain of 3+ parts where the result type is String:
result <- "Hello " + name + "!" 3 parts: error result <- a + " " + b + " " + c 5 parts: error result <- prefix() + text + "]" 3 parts: error
WHAT DOES NOT TRIGGER E11068
result <- first + second 2 parts: allowed total <- a + b + c numeric +: not String type combined <- list1 + list2 + list3 list +: not String type
HOW TO FIX
Convert the concatenation chain to string interpolation:
BAD: result <- "Hello " + name + "!" GOOD: result <- `Hello ${name}!`
BAD: result <- host + ":" + $port GOOD: result <- `${host}:${$port}`
BAD: result <- "(" + $x + ", " + $y + ")" GOOD: result <- `(${$x}, ${$y})`
Use the $ operator inside ${...} to convert non-String values.
See Q174 for all string combination methods. See Q37 for string basics. See Q43 for escape sequences and literal dollar signs in interpolation.
Example
defines module qa.stringops.preferinterpolation defines function // Two-part concatenation is allowed twoPartConcat() -> first as String second as String <- result as String: first + second // Interpolation for 3+ parts greetPerson() -> name as String <- result as String: `Hello ${name}!` // Mixed types with $ operator formatEndpoint() -> host as String port as Integer <- result as String: `${host}:${port}` // Complex interpolation formatCoordinate() -> x as Integer y as Integer <- result as String: `(${x}, ${y})` defines program InterpolationDemo() stdout <- Stdout() // Two-part concat is fine stdout.println(twoPartConcat("Hello", "World")) // Interpolation for everything else stdout.println(greetPerson("Steve")) stdout.println(formatEndpoint("localhost", 8080)) stdout.println(formatCoordinate(10, 20)) // Numeric addition is unaffected (not String type) a <- 1 b <- 2 c <- 3 total <- a + b + c stdout.println(`Total: ${total}`)
Common mistakes
E11068 — Concatenating 3 or more string parts with + triggers E11068. Use backtick interpolation which compiles to a single allocation. See ek9 -h E11068 for details.
Incorrect:
<- result as String: "Hello " + name + "!"
Correct:
<- result as String: `Hello ${name}!`
E11068 — Concatenating three or more String parts with '+' triggers E11068 — use backtick interpolation `${host}:${port}`, which compiles to a single allocation. See ek9 -h E11068 for details.
Incorrect:
<- result as String: host + ":" + $port
Correct:
<- result as String: `${host}:${port}`
Other ways to ask this
- What is error E11068 in EK9?
- Why can't I use + to build strings in EK9?
- How do I fix PREFER_STRING_INTERPOLATION error in EK9?
Coming from another language?
Java: no restriction on + chains (StringBuilder optimisation by javac since Java 9, invokedynamic since Java 11). Python: no restriction, but f-strings recommended by PEP 498. Rust: format!() macro preferred over + chains but not enforced. Go: no restriction, but fmt.Sprintf() recommended. JavaScript: template literals recommended over + chains by ESLint prefer-template rule but not a hard error. Kotlin: string templates recommended but + chains compile fine. Swift: string interpolation \\(expr) recommended but + chains compile fine, no enforcement. EK9: 3+ part + chains on String are a hard compiler error (E11068) because EK9 has a bespoke STRING_INTERPOLATION IR instruction that generates provably better code.
Keywords: compiler, debug, plus, text, swift, backtick, compile, PREFER_STRING_INTERPOLATION, E11068, performance, interpolation, concatenation, error, string