String interpolation

Last updated

In computer programming, string interpolation (or variable interpolation, variable substitution, or variable expansion) is the process of evaluating a string literal containing one or more placeholders, yielding a result in which the placeholders are replaced with their corresponding values. It is a form of simple template processing [1] or, in formal terms, a form of quasi-quotation (or logic substitution interpretation). The placeholder may be a variable name, or in some languages an arbitrary expression, in either case evaluated in the current context.

Contents

String interpolation is an alternative to building string via concatenation, which requires repeat quoting and unquoting; [2] or substituting into a printf format string, where the variable is far from where it is used. Compare:

apples=4puts"I have #{apples} apples."# string interpolationputs"I have "+String(apples)+" apples."# string concatenationputs"I have %d apples."%apples# format string

Two types of literal expression are usually offered: one with interpolation enabled, the other without. Non-interpolated strings may also escape sequences, in which case they are termed a raw string, though in other cases this is separate, yielding three classes of raw string, non-interpolated (but escaped) string, interpolated (and escaped) string. For example, in Unix shells, single-quoted strings are raw, while double-quoted strings are interpolated. Placeholders are usually represented by a bare or a named sigil (typically $ or %), e.g. $apples or %apples, or with braces, e.g. {apples}, sometimes both, e.g. ${apples}. In some cases additional formatting specifiers can be used (as in printf), e.g. {apples:3}, and in some cases the formatting specifiers themselves can be interpolated, e.g. {apples:width}. Expansion of the string usually occurs at run time.

Language support for string interpolation varies widely. Some languages do not offer string interpolation, instead using concatenation, simple formatting functions, or template libraries. String interpolation is common in many programming languages which make heavy use of string representations of data, such as Apache Groovy, Julia, Kotlin, Perl, PHP, Python, Ruby, Scala, Swift, Tcl and most Unix shells.

Algorithms

There are two main types of variable-expanding algorithms for variable interpolation: [3]

  1. Replace and expand placeholders: creating a new string from the original one, by find–replace operations. Find variable reference (placeholder), replace it by its variable value. This algorithm offers no cache strategy.
  2. Split and join string: splitting the string into an array, merging it with the corresponding array of values, then joining items by concatenation. The split string can be cached for reuse.

Security issues

String interpolation, like string concatenation, may lead to security problems. If user input data is improperly escaped or filtered, the system will be exposed to SQL injection, script injection, XML external entity (XXE) injection, and cross-site scripting (XSS) attacks. [4]

An SQL injection example:

query = "SELECTx,y,zFROMTableWHEREid='$id' "

If $id is replaced with "'; DELETEFROMTable;SELECT*FROMTableWHEREid='", executing this query will wipe out all the data in Table.

Examples

ABAP

DATA(apples)=4.WRITE|I have {apples} apples|.

The output will be:

I have 4 apples

Bash

apples=4echo"I have $apples apples"# orecho"I have ${apples} apples"

The output will be:

I have 4 apples

Boo

apples=4print("I have $(apples) apples")# orprint("I have {0} apples"%apples)

The output will be:

I have 4 apples

C#

varapples=4;varbananas=3;Console.WriteLine($"I have {apples} apples");Console.WriteLine($"I have {apples + bananas} fruits");

[5]

The output will be:

I have 4 applesI have 7 fruits

ColdFusion Markup Language

ColdFusion Markup Language (CFML) script syntax:

apples=4;writeOutput("I have #apples# apples");

Tag syntax:

<cfsetapples=4><cfoutput>I have #apples# apples</cfoutput>

The output will be:

I have 4 apples

CoffeeScript

apples=4console.log"I have #{apples} apples"

The output will be:

I have 4 apples

Dart

intapples=4,bananas=3;print('I have $apples apples.');print('I have ${apples+bananas} fruits.');

The output will be:

I have 4 apples.I have 7 fruits.

Go

As of 2022, Go does not have string interpolation. There have been some proposals for string interpolation in the next version of the language, Go 2. [6] [7] Instead, Go uses printf format strings in the fmt.Sprintf function, string concatenation, or template libraries like text/template.

Groovy

In groovy, interpolated strings are known as GStrings: [8]

defquality="superhero"finalage=52defsentence="A developer is a $quality if he is ${age <= 42 ? 'young' : 'seasoned'}"printlnsentence

The output will be:

A developer is a superhero if he is seasoned

Haxe

varapples=4;varbananas=3;trace('I have $apples apples.');trace('I have ${apples+bananas} fruits.');

The output will be: [9]

I have 4 apples.I have 7 fruits.

Java

Java 21 does have interpolated strings thanks to JEP 430. In jshell you could use the constant STR of java.lang.StringTemplate directly.

enumStage{test,qa,prod}recordDeploy(UUIDimage,Stagestage){}vardeploy=newDeploy(UUID.randomUUID(),Stage.test)STR."Installing \{deploy.image()} on Stage \{deploy.stage()} ..."vardeploy=newDeploy(UUID.randomUUID(),Stage.prod)STR."Installing \{deploy.image()} on Stage \{deploy.stage()} ..."

https://openjdk.org/jeps/430

JavaScript, as of the ECMAScript 2015 (ES6) standard, supports string interpolation using backticks ``. This feature is called template literals. [10] Here is an example:

constapples=4;constbananas=3;console.log(`I have ${apples} apples`);console.log(`I have ${apples+bananas} fruits`);

The output will be:

I have 4 applesI have 7 fruits

Template literals can also be used for multi-line strings:

console.log(`This is the first line of text.This is the second line of text.`);

The output will be:

This is the first line of text.This is the second line of text.

Julia

apples=4bananas=3print("I have $apples apples and $bananas bananas, making $(apples+bananas) pieces of fruit in total.")

The output will be:

I have 4 apples and 3 bananas, making 7 pieces of fruit in total.

Kotlin

valquality="superhero"valapples=4valbananas=3valsentence="A developer is a $quality. I have ${apples+bananas} fruits"println(sentence)

The output will be:

A developer is a superhero. I have 7 fruits

Nemerle

defapples=4;defbananas=3;Console.WriteLine($"I have $apples apples.");Console.WriteLine($"I have $(apples + bananas) fruit.");

It also supports advanced formatting features, such as:

deffruit=["apple","banana"];Console.WriteLine($<#I have ..$(fruit; "\n"; f => f + "s")#>);

The output will be:

applesbananas

Nim

Nim provides string interpolation via the strutils module. Formatted string literals inspired by Python F-string are provided via the strformat module, the strformat macro verifies that the format string is well-formed and well-typed, and then are expanded into Nim source code at compile-time.

importstrutils,strformatvarapples=4varbananas=3echo"I have $1 apples".format(apples)echofmt"I have {apples} apples"echofmt"I have {apples + bananas} fruits"# Multi-lineechofmt"""Ihave{apples}apples"""# Debug the formattingechofmt"I have {apples=} apples"# Custom openChar and closeChar charactersechofmt("I have (apples) {apples}",'(',')')# Backslash inside the formatted string literalechofmt"""{ "yep\nope" }"""

The output will be:

I have 4 applesI have 4 applesI have 7 fruitsI have4 applesI have apples=4 applesI have 4 {apples}yepope

Nix

letnumberOfApples="4";in"I have ${numberOfApples} apples"

The output will be:

I have 4 apples

ParaSail

constApples:=4constBananas:=3Println("I have `(Apples) apples.\n")Println("I have `(Apples+Bananas) fruits.\n")

The output will be:

I have 4 apples.I have 7 fruits.

Perl

my$apples=4;my$bananas=3;print"I have $apples apples.\n";print"I have @{[$apples+$bananas]} fruit.\n";# Uses the Perl array (@) interpolation.

The output will be:

I have 4 apples.I have 7 fruit.

PHP

<?php$apples=5;$bananas=3;echo"There are $apples apples and $bananas bananas.\n";echo"I have {$apples} apples and {$bananas} bananas.";

The output will be:

There are 5 apples and 3 bananas.I have 5 apples and 3 bananas.

Python

Python supports string interpolation as of version 3.6, referred to as "formatted string literals". [11] [12] [13] Such a literal begins with an f or F before the opening quote, and uses braces for placeholders:

apples=4bananas=3print(f'I have {apples} apples and {bananas} bananas')

The output will be:

I have 4 apples and 3 bananas

Ruby / Crystal

apples=4puts"I have #{apples} apples"# Format string applications for comparison:puts"I have %s apples"%applesputs"I have %{a} apples"%{a:apples}

The output will be:

I have 4 apples

Rust

Rust does not have general string interpolation, but provides similar functionality via macros, referred to as "Captured identifiers in format strings", introduced in version 1.58.0, released 2022-01-13. [14]

Rust provides formatting via the std::fmt module, which is interfaced with through various macros such as format!, write!, and print!. These macros are converted into Rust source code at compile-time, whereby each argument interacts with a formatter. The formatter supports positional parameters, named parameters, argument types, defining various formatting traits, and capturing identifiers from the environment.

let(apples,bananas)=(4,3);// println! captures the identifiers when formatting: the string itself isn't interpolated by Rust.println!("There are {apples} apples and {bananas} bananas.");

The output will be:

There are 4 apples and 3 bananas.

Scala

Scala 2.10+ provides a general facility to allow arbitrary processing of a string literal, and supports string interpolation using the included s and f string interpolators. It is also possible to write custom ones or override the standard ones.

The f interpolator is a compiler macro that rewrites a format string with embedded expressions as an invocation of String.format. It verifies that the format string is well-formed and well-typed.

The standard interpolators

Scala 2.10+'s string interpolation allows embedding variable references directly in processed string literals. Here is an example:

valapples=4valbananas=3//before Scala 2.10printf("I have %d apples\n",apples)println("I have %d apples"formatapples)//Scala 2.10+println(s"I have $apples apples")println(s"I have ${apples+bananas} fruits")println(f"I have $apples%d apples")

The output will be:

I have 4 apples

Sciter (tiscript)

In Sciter any function with name starting from $ is considered as interpolating function and so interpolation is customizable and context sensitive:

varapples=4varbananas=3vardomElement=...;domElement.$content(<p>Ihave{apples}apples</p>);domElement.$append(<p>Ihave{apples+bananas}fruits</p>);

Where

domElement.$content(<p>Ihave{apples}apples</p>);

gets compiled to this:

domElement.html="<p>I have "+apples.toHtmlString()+" apples</p>";

Snobol

apples=4;bananas=3Output="I have "apples" apples."Output="I have "(apples+bananas)" fruits."

The output will be:

I have 4 apples.I have 7 fruits.

Swift

In Swift, a new String value can be created from a mix of constants, variables, literals, and expressions by including their values inside a string literal. [15] Each item inserted into the string literal is wrapped in a pair of parentheses, prefixed by a backslash.

letapples=4print("I have \(apples) apples")

The output will be:

I have 4 apples

Tcl

The Tool Command Language has always supported string interpolation in all quote-delimited strings.

setapples4puts"I have $apples apples."

The output will be:

I have 4 apples.

In order to actually format - and not simply replace - the values, there is a formatting function.

setapples4puts[format"I have %d apples."$apples]

TypeScript

As of version 1.4, TypeScript supports string interpolation using backticks ``. Here is an example:

varapples:number=4;console.log(`I have ${apples} apples`);

The output will be:

I have 4 apples

The console.log function can be used as a printf function. The above example can be rewritten, thusly:

varapples:number=4;console.log("I have %d apples",apples);

The output remains the same.

Visual Basic

As of Visual Basic 14, string interpolation is supported in Visual Basic. [16]

name="Tom"Console.WriteLine($"Hello, {name}")

The output will be:

Hello, Tom

See also

Notes

  1. "Enforcing Strict Model-View Separation in Template Engines", T. Parr (2004), WWW2004 conference.
  2. "Interpolation in Perl". This is much tidier than repeat uses of the '.' concatenation operator.
  3. "smallest-template-system/Simplest algorithms", an online tutorial for placeholder-template-systems.
  4. "Secure String Interpolation". google-caja.googlecode.com. Archived from the original on 2012-10-19.
  5. "Strings - C# Programming Guide".
  6. "proposal: Go 2: string interpolation #34174". GitHub .
  7. "proposal: Go 2: string interpolation evaluating to string and list of expressions #50554". GitHub .
  8. "The Apache Groovy programming language - Syntax". groovy-lang.org. Retrieved 2021-06-20.
  9. "Haxe - Manual - String interpolation". Haxe - The Cross-platform Toolkit. Retrieved 2017-09-12.
  10. "Template literals (Template strings) - JavaScript | MDN".
  11. "The Python Tutorial: 7.1.1. Formatted String Literals".
  12. "The Python Language Reference: 2.4.3. Formatted string literals".
  13. "PEP 498 -- Literal String Interpolation".
  14. "Announcing Rust 1.58.0: Captured identifiers in format strings". 2022-01-13.
  15. "Strings and Characters — The Swift Programming Language (Swift 5.5)". docs.swift.org. Retrieved 2021-06-20.
  16. KathleenDollard. "Interpolated Strings - Visual Basic". docs.microsoft.com. Retrieved 2021-06-20.

Related Research Articles

In software engineering, the adapter pattern is a software design pattern that allows the interface of an existing class to be used as another interface. It is often used to make existing classes work with others without modifying their source code.

In computer programming, lazy initialization is the tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed. It is a kind of lazy evaluation that refers specifically to the instantiation of objects or other resources.

A string literal or anonymous string is a literal for a string value in the source code of a computer program. Modern programming languages commonly use a quoted sequence of characters, formally "bracketed delimiters", as in x = "foo", where "foo" is a string literal with value foo. Methods such as escape sequences can be used to avoid the problem of delimiter collision and allow the delimiters to be embedded in a string. There are many alternate notations for specifying string literals especially in complicated cases. The exact notation depends on the programming language in question. Nevertheless, there are general guidelines that most modern programming languages follow.

In mathematics and computer science, a higher-order function (HOF) is a function that does at least one of the following:

The printf family of functions in the C programming language are a set of functions that take a format string as input among a variable sized list of other values and produce as output a string that corresponds to the format specifier and given input values. The string is written in a simple template language: characters are usually copied literally into the function's output, but format specifiers, which start with a % character, indicate the location and method to translate a piece of data to characters. The design has been copied to expose similar functionality in other programming languages.

The backtick` is a typographical mark used mainly in computing. It is also known as backquote, grave, or grave accent.

<span class="mw-page-title-main">Foreach loop</span> Control flow statement for traversing items in a collection

In computer programming, foreach loop is a control flow statement for traversing items in a collection. foreach is usually used in place of a standard for loop statement. Unlike other for loop constructs, however, foreach loops usually maintain no explicit counter: they essentially say "do this to everything in this set", rather than "do this x times". This avoids potential off-by-one errors and makes code simpler to read. In object-oriented languages, an iterator, even if implicit, is often used as the means of traversal.

Placeholder may refer to:

In computing, a here document is a file literal or input stream literal: it is a section of a source code file that is treated as if it were a separate file. The term is also used for a form of multiline string literals that use similar syntax, preserving line breaks and other whitespace in the text.

In mathematics and in computer programming, a variadic function is a function of indefinite arity, i.e., one which accepts a variable number of arguments. Support for variadic functions differs widely among programming languages.

Format is a function in Common Lisp that can produce formatted text using a format string similar to the printf format string. It provides more functionality than printf, allowing the user to output numbers in various formats, apply certain format specifiers only under certain conditions, iterate over data structures, output data tabularly, and even recurse, calling format internally to handle data structures that include their own preferred formatting strings. This functionally originates in MIT's Lisp Machine Lisp, where it was based on Multics ioa_.

<span class="mw-page-title-main">JavaScript syntax</span> Set of rules defining correctly structured programs

The syntax of JavaScript is the set of rules that define a correctly structured JavaScript program.

A scanf format string is a control parameter used in various functions to specify the layout of an input string. The functions can then divide the string and translate into values of appropriate data types. String scanning functions are often supplied in standard libraries. Scanf is a function that reads formatted data from the standard input string, which is usually the keyboard and writes the results whenever called in the specified arguments.

In several programming languages, such as Perl, brace notation is a faster way to extract bytes from a string variable.

In computer programming, an anonymous function is a function definition that is not bound to an identifier. Anonymous functions are often arguments being passed to higher-order functions or used for constructing the result of a higher-order function that needs to return a function. If the function is only used once, or a limited number of times, an anonymous function may be syntactically lighter than using a named function. Anonymous functions are ubiquitous in functional programming languages and other languages with first-class functions, where they fulfil the same role for the function type as literals do for other data types.

This comparison of programming languages (strings) compares the features of string data structures or text-string processing for over 52 various computer programming languages.

The syntax and semantics of PHP, a programming language, form a set of rules that define how a PHP program can be written and interpreted.

In computer programming, ellipsis notation is used to denote ranges, an unspecified number of arguments, or a parent directory. Most programming languages require the ellipsis to be written as a series of periods; a single (Unicode) ellipsis character cannot be used.

printk is a C function from the Linux kernel interface that prints messages to the kernel log. It accepts a string parameter called the format string, which specifies a method for rendering an arbitrary number of varied data type parameter(s) into a string. The string is then printed to the kernel log.

In software engineering, the module pattern is a design pattern used to implement the concept of software modules, defined by modular programming, in a programming language with incomplete direct support for the concept.