String interpolation (included)

From Rosetta Code
Task
String interpolation (included)
You are encouraged to solve this task according to the task description, using any language you may know.

Basic Data Operation
This is a basic data operation. It represents a fundamental action on a basic data type.

You may see other such operations in the Basic Data Operations category, or:

Integer Operations
Arithmetic | Comparison

Boolean Operations
Bitwise | Logical

String Operations
Concatenation | Interpolation | Comparison | Matching

Memory Operations
Pointers & references | Addresses

Given a string and defined variables or values, string interpolation is the replacement of defined character sequences in the string by values or variable values.

For example, given an original string of "Mary had a X lamb.", a value of "big", and if the language replaces X in its interpolation routine, then the result of its interpolation would be the string "Mary had a big lamb".
(Languages usually include an infrequently used character or sequence of characters to indicate what is to be replaced such as "%", or "#" rather than "X").


Task
  1. Use your languages inbuilt string interpolation abilities to interpolate a string missing the text "little" which is held in a variable, to produce the output string "Mary had a little lamb".
  2. If possible, give links to further documentation on your languages string interpolation features.


Note: The task is not to create a string interpolation routine, but to show a language's built-in capability.


Other tasks related to string operations:
Metrics
Counting
Remove/replace
Anagrams/Derangements/shuffling
Find/Search/Determine
Formatting
Song lyrics/poems/Mad Libs/phrases
Tokenize
Sequences



11l

V extra = ‘little’
print(‘Mary had a ’extra‘ lamb.’)
print(‘Mary had a #. lamb.’.format(extra))
print(f:‘Mary had a {extra} lamb.’)
Output:
Mary had a little lamb.
Mary had a little lamb.
Mary had a little lamb.

AArch64 Assembly

Works with: as version Raspberry Pi 3B version Buster 64 bits
/* ARM assembly AARCH64 Raspberry PI 3B */
/*  program insertString64.s   */
/* In assembler, there is no function to insert a chain */
/* so this program offers two functions to insert    */
/*******************************************/
/* Constantes file                         */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"

.equ CHARPOS,       '@'

/*******************************************/
/* Initialized data                        */
/*******************************************/
.data
szString:           .asciz " string "
szString1:          .asciz "insert"
szString2:          .asciz "abcd@efg"
szString3:          .asciz "abcdef @"
szString4:          .asciz "@ abcdef"
szCarriageReturn:   .asciz "\n"
/*******************************************/
/* UnInitialized data                      */
/*******************************************/
.bss 
/*******************************************/
/*  code section                           */
/*******************************************/
.text
.global main 
main:                            // entry of program

    ldr x0,qAdrszString          // string address
    ldr x1,qAdrszString1         // string address
    mov x2,#0
    bl strInsert                 // 
                                 // return new pointer
    bl affichageMess             // display result string
    ldr x0,qAdrszCarriageReturn
    bl affichageMess

    ldr x0,qAdrszString          // string address
    ldr x1,qAdrszString1         // string address
    mov x2,#3
    bl strInsert                 // 
                                 // return new pointer
    bl affichageMess             // display result string
    ldr x0,qAdrszCarriageReturn
    bl affichageMess

    ldr x0,qAdrszString          // string address
    ldr x1,qAdrszString1         // string address
    mov x2,#40
    bl strInsert                 // 
                                 // return new pointer
    bl affichageMess             // display result string
    ldr x0,qAdrszCarriageReturn
    bl affichageMess

    ldr x0,qAdrszString2         // string address
    ldr x1,qAdrszString1         // string address
    bl strInsertAtChar           // 
                                 // return new pointer
    bl affichageMess             // display result string
    ldr x0,qAdrszCarriageReturn
    bl affichageMess

    ldr x0,qAdrszString3         // string address
    ldr x1,qAdrszString1         // string address
    bl strInsertAtChar           // 
                                 // return new pointer
    bl affichageMess             // display result string
    ldr x0,qAdrszCarriageReturn
    bl affichageMess

    ldr x0,qAdrszString4         // string address
    ldr x1,qAdrszString1         // string address
    bl strInsertAtChar           // 
                                 // return new pointer
    bl affichageMess             // display result string
    ldr x0,qAdrszCarriageReturn
    bl affichageMess
100:                             // standard end of the program
    mov x0, #0                   // return code
    mov x8, #EXIT                // request to exit program
    svc 0                        // perform the system call
qAdrszString:          .quad szString
qAdrszString1:         .quad szString1
qAdrszString2:         .quad szString2
qAdrszString3:         .quad szString3
qAdrszString4:         .quad szString4
qAdrszCarriageReturn:  .quad szCarriageReturn
/******************************************************************/
/*   insertion of a sub-chain in a chain in the desired position  */ 
/******************************************************************/
/* x0 contains the address of string 1 */
/* x1 contains the address of string to insert */
/* x2 contains the position of insertion : 
      0 start string 
      if x2 > lenght string 1 insert at end of string*/
/* x0 return the address of new string  on the heap */
strInsert:
    stp x1,lr,[sp,-16]!                      // save  registers
    stp x2,x3,[sp,-16]!                      // save  registers
    mov x3,#0                                // length counter 
1:                                           // compute length of string 1
    ldrb w4,[x0,x3]
    cmp w4,#0
    cinc  x3,x3,ne                           // increment to one if not equal
    bne 1b                                   // loop if not equal
    mov x5,#0                                // length counter insertion string
2:                                           // compute length of insertion string
    ldrb w4,[x1,x5]
    cmp x4,#0
    cinc  x5,x5,ne                           // increment to one if not equal
    bne 2b
    cmp x5,#0
    beq 99f                                  // string empty -> error
    add x3,x3,x5                             // add 2 length
    add x3,x3,#1                             // +1 for final zero
    mov x6,x0                                // save address string 1
    mov x0,#0                                // allocation place heap
    mov x8,BRK                               // call system 'brk'
    svc #0
    mov x5,x0                                // save address heap for output string
    add x0,x0,x3                             // reservation place x3 length
    mov x8,BRK                               // call system 'brk'
    svc #0
    cmp x0,#-1                               // allocation error
    beq 99f
    //
    mov x8,#0                                // index load characters string 1
    cmp x2,#0                                // index insertion = 0
    beq 5f                                   // insertion at string 1 begin
3:                                           // loop copy characters string 1
    ldrb w0,[x6,x8]                          // load character
    cmp w0,#0                                // end string ?
    beq 5f                                   // insertion at end
    strb w0,[x5,x8]                          // store character in output string
    add x8,x8,#1                             // increment index
    cmp x8,x2                                // < insertion index ?
    blt 3b                                   // yes -> loop
5:
    mov x4,x8                                // init index character output string
    mov x3,#0                                // index load characters insertion string
6:
    ldrb w0,[x1,x3]                          // load characters insertion string
    cmp w0,#0                                // end string ?
    beq 7f
    strb w0,[x5,x4]                          // store in output string
    add x3,x3,#1                             // increment index
    add x4,x4,#1                             // increment output index
    b 6b                                     // and loop
7:
    ldrb w0,[x6,x8]                          // load other character string 1
    strb w0,[x5,x4]                          // store in output string
    cmp x0,#0                                // end string 1 ?
    beq 8f                                   // yes -> end
    add x4,x4,#1                             // increment output index
    add x8,x8,#1                             // increment index
    b 7b                                     // and loop
8:
    mov x0,x5                                // return output string address 
    b 100f
99:                                          // error
    mov x0,#-1
100:
    ldp x2,x3,[sp],16                        // restaur  2 registers
    ldp x1,lr,[sp],16                        // restaur  2 registers
    ret
/******************************************************************/
/*   insert string at character insertion                         */ 
/******************************************************************/
/* x0 contains the address of string 1 */
/* x1 contains the address of insertion string   */
/* x0 return the address of new string  on the heap */
/* or -1 if error   */
strInsertAtChar:
    stp x1,lr,[sp,-16]!                      // save  registers
    stp x2,x3,[sp,-16]!                      // save  registers
    mov x3,#0                                // length counter 
1:                                           // compute length of string 1
    ldrb w4,[x0,x3]
    cmp w4,#0
    cinc  x3,x3,ne                           // increment to one if not equal
    bne 1b                                   // loop if not equal
    mov x5,#0                                // length counter insertion string
2:                                           // compute length to insertion string
    ldrb w4,[x1,x5]
    cmp x4,#0
    cinc  x5,x5,ne                           // increment to one if not equal
    bne 2b                                   // and loop
    cmp x5,#0
    beq 99f                                  // string empty -> error
    add x3,x3,x5                             // add 2 length
    add x3,x3,#1                             // +1 for final zero
    mov x6,x0                                // save address string 1
    mov x0,#0                                // allocation place heap
    mov x8,BRK                               // call system 'brk' 
    svc #0
    mov x5,x0                                // save address heap for output string
    add x0,x0,x3                             // reservation place x3 length
    mov x8,BRK                               // call system 'brk'
    svc #0
    cmp x0,#-1                               // allocation error
    beq 99f
    
    mov x2,0
    mov x4,0               
3:                                           // loop copy string begin 
    ldrb w3,[x6,x2]
    cmp w3,0
    beq 99f
    cmp w3,CHARPOS                           // insertion character ?
    beq 5f                                   // yes
    strb w3,[x5,x4]                          // no store character in output string
    add x2,x2,1
    add x4,x4,1
    b 3b                                     // and loop
5:                                           // x4 contains position insertion
    add x8,x4,1                              // init index character output string
                                             // at position insertion + one
    mov x3,#0                                // index load characters insertion string
6:
    ldrb w0,[x1,x3]                          // load characters insertion string
    cmp w0,#0                                // end string ?
    beq 7f                                   // yes 
    strb w0,[x5,x4]                          // store in output string
    add x3,x3,#1                             // increment index
    add x4,x4,#1                             // increment output index
    b 6b                                     // and loop
7:                                           // loop copy end string 
    ldrb w0,[x6,x8]                          // load other character string 1
    strb w0,[x5,x4]                          // store in output string
    cmp x0,#0                                // end string 1 ?
    beq 8f                                   // yes -> end
    add x4,x4,#1                             // increment output index
    add x8,x8,#1                             // increment index
    b 7b                                     // and loop
8:
    mov x0,x5                                // return output string address 
    b 100f
99:                                          // error
    mov x0,#-1
100:
    ldp x2,x3,[sp],16                        // restaur  2 registers
    ldp x1,lr,[sp],16                        // restaur  2 registers
    ret

/********************************************************/
/*        File Include fonctions                        */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"

Action!

PROC Main()
  CHAR ARRAY extra="little"

  PrintF("Mary had a %S lamb.%E",extra)
RETURN
Output:

Screenshot from Atari 8-bit computer

Mary had a little lamb.

Ada

with Ada.Strings.Fixed, Ada.Text_IO;
use  Ada.Strings, Ada.Text_IO;
procedure String_Replace is
   Original : constant String := "Mary had a @__@ lamb.";
   Tbr : constant String := "@__@";
   New_Str : constant String := "little";
   Index : Natural := Fixed.Index (Original, Tbr);
begin
   Put_Line (Fixed.Replace_Slice (
     Original, Index, Index + Tbr'Length - 1, New_Str));
end String_Replace;

Alternatively

Put_Line ("Mary had a " & New_Str & " lamb.");

Aikido

const little = "little"
printf ("Mary had a %s lamb\n", little)

// alternatively
println ("Mary had a " + little + " lamb")

ALGOL 68

Translation of: C
Works with: ALGOL 68 version Revision 1 - no extensions to language used
Works with: ALGOL 68G version Any - tested with release 1.18.0-9h.tiny

strings are simply flex arrays of char. formats on the other hand take on some of the properties of procedures including the scoping rules.

main:(
# as a STRING #
  STRING extra = "little";
  printf(($"Mary had a "g" lamb."l$, extra));

# as a FORMAT #
  FORMAT extraf = $"little"$;
  printf($"Mary had a "f(extraf)" lamb."l$);

# or: use simply use STRING concatenation #
  print(("Mary had a "+extra+" lamb.", new line))
)
Output:
Mary had a little lamb.
Mary had a little lamb.
Mary had a little lamb.

Algol 68 allows a string to be used as a file, the following (based on the above) uses this to construct the string which can then be further processed. In this sample, variable strings and formats are used though in general it would be hard to construct the extraf format at run-time as Algol 68 has no facilities to construct formats on the fly.

BEGIN
    FILE str file;
    STRING mhl;
    associate( str file, mhl );

    STRING extra := "little";
    TO 2 DO
        putf( str file, ( $"Mary had a "g" lamb."$, extra ) );
        print( ( "1 result is: {{", mhl, "}}", newline ) );
        mhl := "";
        "supposedlly-" +=: extra
    OD;

    FORMAT extraf := $"little"$;
    TO 2 DO
        putf( str file, ( $"Mary had a "f(extraf)" lamb."$ ) );
        print( ( "2 result is: {{", mhl, "}}", newline ) );
        mhl := "";
        extraf := $"medium-sized"$
    OD
END
Output:
1 result is: {{Mary had a little lamb.}}
1 result is: {{Mary had a supposedlly-little lamb.}}
2 result is: {{Mary had a little lamb.}}
2 result is: {{Mary had a medium-sized lamb.}}

ARM Assembly

Works with: as version Raspberry Pi
/* ARM assembly Raspberry PI  */
/*  program insertString.s   */

/* REMARK 1 : this program use routines in a include file 
   see task Include a file language arm assembly 
   for the routine affichageMess conversion10 
   see at end of this program the instruction include */
/*******************************************/
/* Constantes                              */
/*******************************************/
.equ STDOUT, 1           @ Linux output console
.equ EXIT,   1           @ Linux syscall
.equ WRITE,  4           @ Linux syscall
.equ BRK,    0x2d        @ Linux syscall
.equ CHARPOS,       '@'
 
/*******************************************/
/* Initialized data                        */
/*******************************************/
.data
szString:           .asciz " string "
szString1:          .asciz "insert"
szString2:          .asciz "abcd@efg"
szString3:          .asciz "abcdef @"
szString4:          .asciz "@ abcdef"
szCarriageReturn:   .asciz "\n"
/*******************************************/
/* UnInitialized data                      */
/*******************************************/
.bss 
/*******************************************/
/*  code section                           */
/*******************************************/
.text
.global main 
main:                            // entry of program
 
    ldr r0,iAdrszString          // string address
    ldr r1,iAdrszString1         // string address
    mov r2,#0
    bl strInsert                 // 
                                 // return new pointer
    bl affichageMess             // display result string
    ldr r0,iAdrszCarriageReturn
    bl affichageMess
 
    ldr r0,iAdrszString          // string address
    ldr r1,iAdrszString1         // string address
    mov r2,#3
    bl strInsert                 // 
                                 // return new pointer
    bl affichageMess             // display result string
    ldr r0,iAdrszCarriageReturn
    bl affichageMess
 
    ldr r0,iAdrszString          // string address
    ldr r1,iAdrszString1         // string address
    mov r2,#40
    bl strInsert                 // 
                                 // return new pointer
    bl affichageMess             // display result string
    ldr r0,iAdrszCarriageReturn
    bl affichageMess
 
    ldr r0,iAdrszString2         // string address
    ldr r1,iAdrszString1         // string address
    bl strInsertAtChar           // 
                                 // return new pointer
    bl affichageMess             // display result string
    ldr r0,iAdrszCarriageReturn
    bl affichageMess
 
    ldr r0,iAdrszString3         // string address
    ldr r1,iAdrszString1         // string address
    bl strInsertAtChar           // 
                                 // return new pointer
    bl affichageMess             // display result string
    ldr r0,iAdrszCarriageReturn
    bl affichageMess
 
    ldr r0,iAdrszString4         // string address
    ldr r1,iAdrszString1         // string address
    bl strInsertAtChar           // 
                                 // return new pointer
    bl affichageMess             // display result string
    ldr r0,iAdrszCarriageReturn
    bl affichageMess
100:                             // standard end of the program
    mov r0, #0                   // return code
    mov r7, #EXIT                // request to exit program
    svc 0                        // perform the system call
iAdrszString:          .int szString
iAdrszString1:         .int szString1
iAdrszString2:         .int szString2
iAdrszString3:         .int szString3
iAdrszString4:         .int szString4
iAdrszCarriageReturn:  .int szCarriageReturn
/******************************************************************/
/*   insertion of a sub-chain in a chain in the desired position  */ 
/******************************************************************/
/* r0 contains the address of string 1 */
/* r1 contains the address of string to insert */
/* r2 contains the position of insertion : 
      0 start string 
      if r2 > lenght string 1 insert at end of string*/
/* r0 return the address of new string  on the heap */
strInsert:
    push {r1-r4,lr}                         @ save  registres
    mov r3,#0                                // length counter 
1:                                           // compute length of string 1
    ldrb r4,[r0,r3]
    cmp r4,#0
    addne r3,r3,#1                          // increment to one if not equal
    bne 1b                                   // loop if not equal
    mov r5,#0                                // length counter insertion string
2:                                           // compute length of insertion string
    ldrb r4,[r1,r5]
    cmp r4,#0
    addne r5,r5,#1                          // increment to one if not equal
    bne 2b
    cmp r5,#0
    beq 99f                                  // string empty -> error
    add r3,r3,r5                             // add 2 length
    add r3,r3,#1                             // +1 for final zero
    mov r6,r0                                // save address string 1
    mov r0,#0                                // allocation place heap
    mov r7,#BRK                               // call system 'brk'
    svc #0
    mov r5,r0                                // save address heap for output string
    add r0,r0,r3                             // reservation place r3 length
    mov r7,#BRK                               // call system 'brk'
    svc #0
    cmp r0,#-1                               // allocation error
    beq 99f
    //
    mov r7,#0                                // index load characters string 1
    cmp r2,#0                                // index insertion = 0
    beq 5f                                   // insertion at string 1 begin
3:                                           // loop copy characters string 1
    ldrb r0,[r6,r7]                          // load character
    cmp r0,#0                                // end string ?
    beq 5f                                   // insertion at end
    strb r0,[r5,r7]                          // store character in output string
    add r7,r7,#1                             // increment index
    cmp r7,r2                                // < insertion index ?
    blt 3b                                   // yes -> loop
5:
    mov r4,r7                                // init index character output string
    mov r3,#0                                // index load characters insertion string
6:
    ldrb r0,[r1,r3]                          // load characters insertion string
    cmp r0,#0                                // end string ?
    beq 7f
    strb r0,[r5,r4]                          // store in output string
    add r3,r3,#1                             // increment index
    add r4,r4,#1                             // increment output index
    b 6b                                     // and loop
7:
    ldrb r0,[r6,r7]                          // load other character string 1
    strb r0,[r5,r4]                          // store in output string
    cmp r0,#0                                // end string 1 ?
    beq 8f                                   // yes -> end
    add r4,r4,#1                             // increment output index
    add r7,r7,#1                             // increment index
    b 7b                                     // and loop
8:
    mov r0,r5                                // return output string address 
    b 100f
99:                                          // error
    mov r0,#-1
100:
    pop {r1-r4,lr}                          @ restaur registers 
    bx lr                                   @ return  
/******************************************************************/
/*   insert string at character insertion                         */ 
/******************************************************************/
/* r0 contains the address of string 1 */
/* r1 contains the address of insertion string   */
/* r0 return the address of new string  on the heap */
/* or -1 if error   */
strInsertAtChar:
    push {r1-r7,lr}                         @ save  registres
    mov r3,#0                                // length counter 
1:                                           // compute length of string 1
    ldrb r4,[r0,r3]
    cmp r4,#0
    addne r3,r3,#1                           // increment to one if not equal
    bne 1b                                   // loop if not equal
    mov r5,#0                                // length counter insertion string
2:                                           // compute length to insertion string
    ldrb r4,[r1,r5]
    cmp r4,#0
    addne r5,r5,#1                           // increment to one if not equal
    bne 2b                                   // and loop
    cmp r5,#0
    beq 99f                                  // string empty -> error
    add r3,r3,r5                             // add 2 length
    add r3,r3,#1                             // +1 for final zero
    mov r6,r0                                // save address string 1
    mov r0,#0                                // allocation place heap
    mov r7,#BRK                               // call system 'brk' 
    svc #0
    mov r5,r0                                // save address heap for output string
    add r0,r0,r3                             // reservation place r3 length
    mov r7,#BRK                               // call system 'brk'
    svc #0
    cmp r0,#-1                               // allocation error
    beq 99f
 
    mov r2,#0
    mov r4,#0
3:                                           // loop copy string begin 
    ldrb r3,[r6,r2]
    cmp r3,#0
    beq 99f
    cmp r3,#CHARPOS                           // insertion character ?
    beq 5f                                   // yes
    strb r3,[r5,r4]                          // no store character in output string
    add r2,r2,#1
    add r4,r4,#1
    b 3b                                     // and loop
5:                                           // r4 contains position insertion
    add r7,r4,#1                              // init index character output string
                                             // at position insertion + one
    mov r3,#0                                // index load characters insertion string
6:
    ldrb r0,[r1,r3]                          // load characters insertion string
    cmp r0,#0                                // end string ?
    beq 7f                                   // yes 
    strb r0,[r5,r4]                          // store in output string
    add r3,r3,#1                             // increment index
    add r4,r4,#1                             // increment output index
    b 6b                                     // and loop
7:                                           // loop copy end string 
    ldrb r0,[r6,r7]                          // load other character string 1
    strb r0,[r5,r4]                          // store in output string
    cmp r0,#0                                // end string 1 ?
    beq 8f                                   // yes -> end
    add r4,r4,#1                             // increment output index
    add r7,r7,#1                             // increment index
    b 7b                                     // and loop
8:
    mov r0,r5                                // return output string address 
    b 100f
99:                                          // error
    mov r0,#-1
100:
    pop {r1-r7,lr}                          @ restaur registers 
    bx lr                                   @ return  
/***************************************************/
/*      ROUTINES INCLUDE                 */
/***************************************************/
.include "../affichage.inc"
Output:
insert string
 stinsertring
 string insert
abcdinsertefg
abcdef insert
insert abcdef

APL

      s  'Mary had a ∆ lamb'  s[s'∆']  'little'  s  s
      s
Mary had a little lamb

⍝⍝⍝ Or, for a more general version which interpolates multiple positional arguments and can
⍝⍝⍝ handle both string and numeric types...

r  s sInterp sv
⍝⍝ Interpolate items in sv into s (string field substitution)
⍝ s: string - format string, '∆' used for interpolation points
⍝ sv: vector - vector of items to interpolate into s
⍝ r: interpolated string
  s[('∆'=s)/⍳⍴s]  ¨(¨sv)
  r  s

      'Mary had a ∆ lamb, its fleece was ∆ as ∆.' sInterp 'little' 'black' 'night'
Mary had a little lamb, its fleece was black as night.
      'Mary had a ∆ lamb, its fleece was ∆ as ∆.' sInterp 'little' 'large' 42
Mary had a little lamb, its fleece was large as 42.

Arturo

sizeOfLamb: "little"

print ~"Mary had a |sizeOfLamb| lamb."
Output:
Mary had a little lamb.

Asymptote

string s1 = "big";
write("Mary had a " + s1 + " lamb");
s1 = "little";
write("Mary also had a ", s1, "lamb");

AutoHotkey

; Using the = operator
LIT = little
string = Mary had a %LIT% lamb.

; Using the := operator
LIT := "little"
string := "Mary had a" LIT " lamb."

MsgBox %string%

Documentation: Variables (see Storing values in variables and Retrieving the contents of variables)

AWK

String interpolation is usually done with functions sub() and gsub(). gawk has also gensub().

#!/usr/bin/awk -f
BEGIN {
	str="Mary had a # lamb."
	gsub(/#/, "little", str)
	print str
}

BASIC

Applesoft BASIC

10 x$ = "big"
20 print "Mary had a "; x$; " lamb"

BASIC256

x$ = "big"
print "Mary had a "; x$; " lamb"

x$ = "little"
print "Mary also had a "; ljust(x$, length(x$)); " lamb"

Chipmunk Basic

Works with: Chipmunk Basic version 3.6.4
10 x$ = "big"
20 print "Mary had a "; x$; " lamb"

GW-BASIC

Works with: PC-BASIC version any
Works with: BASICA
Works with: QBasic
Works with: MSX BASIC
10 X$ = "big"
20 PRINT "Mary had a "; X$; " lamb"
30 X$ = "little"
40 PRINT USING "Mary also had a & lamb"; X$
50 END

Minimal BASIC

10 LET X$ = "BIG"
20 PRINT "MARY HAD A "; X$; " LAMB"
30 END

MSX Basic

Works with: MSX BASIC version any

The GW-BASIC solution works without any changes.

QBasic

x$ = "big"
PRINT "Mary had a "; x$; " lamb"
x$ = "little"
PRINT USING "Mary also had a & lamb"; x$
' this code above doesn't modify the first string subsustituting a piece of it with another string
'surely it gives the right output on the screen

Quite BASIC

10 LET X$ = "BIG"
20 PRINT "Mary had a "; x$; " lamb"

True BASIC

LET x$ = "big"
PRINT "Mary had a "; x$; " lamb"

LET x$ = "little"
PRINT USING "Mary had another $##### lamb": x$

LET outstring$ = USING$("$#####", x$)
PRINT "Mary also had a "; outstring$; " lamb"
END

XBasic

Works with: Windows XBasic
PROGRAM	"String append"
VERSION	"0.0000"

DECLARE FUNCTION  Entry ()
FUNCTION  Entry ()
 X$ = "big"
 PRINT "Mary had a "; X$; " lamb"
END FUNCTION
END PROGRAN

Yabasic

x$ = "big"
print "Mary had a ", x$, " lamb"

Batch File

@echo off
setlocal enabledelayedexpansion
call :interpolate %1 %2 res
echo %res%
goto :eof

:interpolate
set pat=%~1
set str=%~2
set %3=!pat:X=%str%! 
goto :eof

Demo

>interpolate.cmd "Mary had a X lamb" little
Mary had a little lamb

BQN

_interpolate is a generalized string interpolation modifier that returns a function based on the replacement character given. The function will take a string on the right and replace the given symbol with the elements of the array given on its left.

Here, the symbol for Nothing(`·`) is used as a replacement character.

Str  (3⌊•Type)2=•Type,0,1,0
_interpolate  {(•Fmt(¬Str)¨𝕨)((𝕗=𝕩)/)𝕩}

'a'"def"45‿⟨1,2,3⟩‿0.34241 '·'_interpolate "Hi · am · and · or · float ·"

Bracmat

Use pattern matching to find the part of the string up to and the part of the string following the magic X. Concatenate these parts with the string "little" in the middle.

@("Mary had a X lamb":?a X ?z) & str$(!a little !z)

C

Include the <stdio.h> header to use the functions of the printf family:

#include <stdio.h>

int main() {
  const char *extra = "little";
  printf("Mary had a %s lamb.\n", extra);
  return 0;
}

C#

This is called "composite formatting" in MSDN.

class Program
{
    static void Main()
    {
        string extra = "little";
        string formatted = $"Mary had a {extra} lamb.";
        System.Console.WriteLine(formatted);
    }
}

C++

#include <string>
#include <iostream>

int main( ) {
   std::string original( "Mary had a X lamb." ) , toBeReplaced( "X" ) ,
      replacement ( "little" ) ;
   std::string newString = original.replace( original.find( "X" ) ,
	 toBeReplaced.length( ) , replacement ) ;
   std::cout << "String after replacement: " << newString << " \n" ;
   return 0 ;
}
==C++==
Works with: C++11
// Variable argument template

#include <string>
#include <vector>

using std::string;
using std::vector;

template<typename S, typename... Args>
string interpolate( const S& orig , const Args&... args)
{
   string out(orig);

   // populate vector from argument list
   auto va = {args...};
   vector<string> v{va};
   
   size_t i = 1;

   for( string s: v)
     {
       string is = std::to_string(i);
       string t = "{" +  is + "}";  // "{1}", "{2}", ...
       try
	 {
	   auto pos = out.find(t);

	   if ( pos != out.npos)  // found token
	     {
	       out.erase(pos, t.length()); //erase token
	       out.insert( pos, s);       // insert arg
	     }

	   i++;                           // next 
	 }
	 catch( std::exception& e)
	   {
	     std::cerr << e.what() << std::endl;
	   }

     } // for

   return out;
}

Clojure

(let [little "little"]
  (println (format "Mary had a %s lamb." little)))

COBOL

Works with: OpenCOBOL
       IDENTIFICATION DIVISION.
       PROGRAM-ID. interpolation-included.

       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  extra PIC X(6) VALUE "little".

       PROCEDURE DIVISION.
           DISPLAY FUNCTION SUBSTITUTE("Mary had a X lamb.", "X", extra)

           GOBACK
           .

Coco

As CoffeeScript, but the braces are optional if the expression to be interpolated is just a variable:

size = 'little'
console.log "Mary had a #size lamb."

CoffeeScript

size = 'little'
console.log "Mary had a #{size} lamb." # Mary had a little lamb.
console.log "Escaping: \#{}" # Escaping: #{}
console.log 'No #{ interpolation} with single quotes' # No #{ interpolation} with single quotes

# Multi-line strings and arbtrary expressions work: 20
console.log """
  Multi-line strings and arbtrary expressions work: #{ 5 * 4 }
  """

Common Lisp

(let ((extra "little"))
  (format t "Mary had a ~A lamb.~%" extra))

More documentation on the FORMAT function.

D

void main() {
    import std.stdio, std.string;

    "Mary had a %s lamb.".format("little").writeln;
    "Mary had a %2$s %1$s lamb.".format("little", "white").writeln;
}
Output:
Mary had a little lamb.
Mary had a white little lamb.

More documentation on the format() function.

Delphi

program Project1;

uses
  System.SysUtils;

var
  Template : string;
  Marker : string;
  Description : string;
  Value : integer;
  Output : string;

begin
  // StringReplace can be used if you are definitely using strings
  // http://docwiki.embarcadero.com/Libraries/XE7/en/System.SysUtils.StringReplace
  Template := 'Mary had a X lamb.';
  Marker := 'X';
  Description := 'little';
  Output := StringReplace(Template, Marker, Description, [rfReplaceAll, rfIgnoreCase]);
  writeln(Output);

  // You could also use format to do the same thing.
  // http://docwiki.embarcadero.com/Libraries/XE7/en/System.SysUtils.Format
  Template := 'Mary had a %s lamb.';
  Description := 'little';
  Output := format(Template,[Description]);
  writeln(Output);

  // Unlike StringReplace, format is not restricted to strings.
  Template := 'Mary had a %s lamb. It was worth $%d.';
  Description := 'little';
  Value := 20;
  Output := format(Template,[Description, Value]);
  writeln(Output);

end.
Output:
Mary had a little lamb.
Mary had a little lamb.
Mary had a little lamb. It was worth $20.

DWScript

PrintLn(Format('Mary had a %s lamb.', ['little']))
Output:
Mary had a little lamb.

Dyalect

Dyalect has a built-in string interpolation feature.

let lamb_size = "little"
print("Mary had a \(lamb_size) lamb.")

E

def adjective := "little"
`Mary had a $adjective lamb`

The `...` syntax in general may be used as a sort of syntax extension; string interpolation is just the default case. More information on E quasi-literals. (Note that this documentation may be somewhat out of date.)

The above code is equivalent to (expands into):

def adjective := "little"
simple__quasiParser.valueMaker("Mary had a ${0} lamb").substitute([adjective])

If an identifier precedes the opening `, then it replaces simple; the quasiParser may be an arbitrary user-defined object. In this way, E provides lightweight syntax for embedding other languages: XML, JSON, GUI layouts, regular expressions, etc.

EchoLisp

format and printf use replacement directives to perform interpolation. See format specification in EchoLisp documentatiuon.

;; format uses %a or ~a as replacement directive
(format "Mary had a ~a lamb" "little")
    "Mary had a little lamb"
(format "Mary had a %a lamb" "little")
    "Mary had a little lamb"

ECL

IMPORT STD;
STD.Str.FindReplace('Mary had a X Lamb', 'X','little');

Elena

ELENA 4.x :

import extensions;
 
public program()
{
    var s := "little";
    console.printLineFormatted("Mary had a {0} lamb.",s).readChar()
}

Elixir

Elixir borrows Ruby's #{...} interpolation syntax.

x = "little"
IO.puts "Mary had a #{x} lamb"

Emacs Lisp

(let ((little "little"))
  (format "Mary had a %s lamb." little)
  ;; message takes a format string as argument
  (message "Mary had a %s lamb." little))

Erlang

Output:
7> S1 = "Mary had a ~s lamb".
8> S2 = lists:flatten( io_lib:format(S1, ["big"]) ).
9> S2.
"Mary had a big lamb"

Euphoria

constant lambType = "little"
sequence s
s = sprintf("Mary had a %s lamb.",{lambType})
puts(1,s)

See sprintf, printf

F#

Documentation

let lambType = "little"
printfn "Mary had a %s lamb." lambType

Factor

USE: formatting 

SYMBOL: little

"little" little set

little get "Mary had a %s lamb" sprintf

I tried to be as specific as possible here. The challenge says to use a variable so that is what I used. It could have been done more cleanly using a CONSTANT.

USE: formatting 

CONSTANT: little "little"

little "Mary had a %s lamb" sprintf

Falcon

'VBA/Python programmer's approach. I'm just a junior Falconeer but this code seems falconic

/* created by Aykayayciti Earl Lamont Montgomery
April 9th, 2018 */

size = "little"
> @ "Mary had a $size lamb"

// line 1: use of the = operator
// line 2: use of the @ and $ operator
Output:
Mary had a little lamb
[Finished in 0.2s]

Fantom

Interpolating a variable value into a string is done by using a $ prefix on the variable name within a string. For example:

fansh> x := "little"
little
fansh> echo ("Mary had a $x lamb")
Mary had a little lamb

Documentation at: Fantom website

Forth

variable	     'src
variable	     #src
variable       'out
variable       #out

: Replace~     dup [char] ~  =                   \ test for  escape char
               if   'out @ 1+  #out @ type  drop \ replace the escape char
               else emit                         \ otherwise write  char
               then  ;
: format       0
               begin  dup  #src @ u<
               while  1+ dup 'src @ + c@
                      replace~
               repeat ;

\ Test of  function
Here 'src ! ," Mary had a ~ lamb" here  'src @ - #src  !
page
cr ." Original        : "
'src @ 1+ #src @ type
cr ." 1st Replacement : "
  here 'out ! ," little" here 'out @ - #out !
  format
cr ." 2nd Replacement : "
  here 'out  ! ," BIG" here 'out @ - #out !
  format
Output:
Original        : Mary had a ~ lamb
1st Replacement : Mary had a little lamb
2nd Replacement : Mary had a BIG lamb

Fortran

program interpolate

  write (*,*) trim(inter("Mary had a X lamb.","X","little"))

contains

  elemental function inter(string,place,ins) result(new)
    character(len=*), intent(in)                          :: string,place,ins
    character(len=len(string)+max(0,len(ins)-len(place))) :: new
    integer                                               :: idx
    idx = index(string,place)
    if ( idx == 0 ) then
      new = string
    else
      new = string(1:idx-1)//ins//string(idx+len(place):len(string))
    end if
  end function inter
  
end program interpolate

FreeBASIC

FreeBASIC has a complex Print statement which, amongst other things, enables variables to be embedded in the string to be printed.

It is also possible to use C library functions such as printf or sprintf, which allow more conventional string interpolation, as easily as if they were part of FB itself:

' FB 1.05.0 Win64

#Include "crt/stdio.bi"  '' header needed for printf

Dim x As String = "big"
Print "Mary had a "; x; " lamb"   '' FB's native Print statement
x = "little"
printf("Mary also had a %s lamb", x) 
Sleep
Output:
Mary had a big lamb
Mary also had a little lamb

Frink

x = "little"
println["Mary had a $x lamb."]

FunL

X = 'little'
println( "Mary had a $X lamb." )

FutureBasic

CFStringRef string, extra
extra = @"little"
string = fn StringWithFormat( @"Mary had a %@ lamb", extra )

print string

HandleEvents

Gambas

Click this link to run this code

Public Sub Main()

Print Subst("Mary had a &1 lamb", "little")

End

Output:

Mary had a little lamb

Gastona

This kind of string interpolation is indeed a strong feature in Gastona. We add one more indirection in the sample just to ilustrate it.

#listix#

   <how>   //little
   <what>  //has a @<how> lamb
   
   <main>  //Mary @<what>
Output:
Mary has a little lamb

Go

Doc: http://golang.org/pkg/fmt/

package main

import (
    "fmt"
)

func main() {
    str := "Mary had a %s lamb"
    txt := "little"
    out := fmt.Sprintf(str, txt)
    fmt.Println(out)
}

Groovy

def adj = 'little'
assert 'Mary had a little lamb.' == "Mary had a ${adj} lamb."

Haskell

No such facilities are defined in Haskell 98, but the base package distributed with GHC provides a printf function.

import Text.Printf

main = printf "Mary had a %s lamb\n" "little"

Haxe

Translation of: C#
class Program {
  static function main() {
    var extra = 'little';
    var formatted = 'Mary had a $extra lamb.';
    Sys.println(formatted);
  }
}
Output:
Mary had a little lamb.

HicEst

Further documentation on HicEst string interpolation function EDIT()

CHARACTER original="Mary had a X lamb", little = "little", output_string*100

output_string = original
EDIT(Text=output_string, Right='X', RePLaceby=little)

Icon and Unicon

Icon and Unicon are descended from a line of languages with a wealth of string manipulation capabilities. See The Icon Programming Language, 3rd Edition; Griswold and Griswold; Chapter 3 String Scanning

  s2 := "humongous"
  s3 := "little"
  s1 :=  "Mary had a humongous lamb."
  s1 ?:= tab(find(s2)) || (=s2,s3) || tab(0)          # replaces the first instance of s2 with s3
  while s1 ?:= tab(find(s2)) || (=s2,s3) || tab(0)    # replaces all instances of s2 with s3, equivalent to replace

Note the strings library includes convenient procedures for string replacement such as replace(s1,s2,s3) which replaces all occurrences of s2 in s1 with s3 and replacem(s1,s2,s3,...) which replaces multiple pairs.

J

The strings and printf scripts are part of the base library.

   require 'printf'
   'Mary had a %s lamb.' sprintf <'little'
Mary had a little lamb.

   require 'strings'
   ('%s';'little') stringreplace 'Mary had a %s lamb.'
Mary had a little lamb.
   'Mary had a %s lamb.' rplc '%s';'little'
Mary had a little lamb.

Documentation:

The comments in these library files give brief descriptions of their contents, and you can browse them using open:

   open'strings printf'

Alternatively, both strings and printf have various web pages describing them, and printf has a lab demonstrating its use (from J's IDE's menu, go Studio -> Labs... and then look in the System category).

That said, note that in recent versions of J, strings is no longer a separate script but part of the core library.

Java

Java includes the Formatter class which includes numerous ways to interpolate text values.
The String and Writer classes both implement a form of Formatter.

There are numerous demonstrations on the documentation page on how to apply different interpolations.
https://docs.oracle.com/en/java/javase/20/docs/api/java.base/java/util/Formatter.html

The format is inspired by the C printf, and is nearly the same except for a few accomodations.
The most idiomatic approach would be to use the String.format or String.formatted methods.

String adjective = "little";
String lyric = String.format("Mary had a %s lamb", adjective);
String adjective = "little";
String lyric = "Mary had a %s lamb".formatted(adjective);

If you wanted to print the string you could use the System.out.printf method.

String adjective = "little";
System.out.printf("Mary had a %s lamb", adjective);

You could also use a combination of StringBuilder and Formatter.

StringBuilder string = new StringBuilder();
Formatter formatter = new Formatter(string);
String adjective = "little";
formatter.format("Mary had a %s lamb", adjective);
formatter.flush();


Alternately

String original = "Mary had a X lamb";
String little = "little";
String replaced = original.replace("X", little); //does not change the original String
System.out.println(replaced);
//Alternative:
System.out.printf("Mary had a %s lamb.", little);
//Alternative:
String formatted = String.format("Mary had a %s lamb.", little);
System.out.println(formatted);

JavaScript

var original = "Mary had a X lamb";
var little = "little";
var replaced = original.replace("X", little); //does not change the original string

Or,

// ECMAScript 6
var X = "little";
var replaced = `Mary had a ${X} lamb`;

jq

"little" as $x
  | "Mary had a \($x) lamb"
Any valid jq expression (including a pipeline) can appear between the interpolating parentheses, e.g.:
$ jq -M -n -r '"Jürgen" as $x | "The string \"\($x)\" has \($x|length) codepoints."'
The string "Jürgen" has 6 codepoints.

Documentation: String interpolation

Julia

X = "little"
"Mary had a $X lamb"

Kotlin

// version 1.0.6

fun main(args: Array<String>) {
   val s = "little"
    // String interpolation using a simple variable
    println("Mary had a $s lamb")

    // String interpolation using an expression (need to wrap it in braces)
    println("Mary had a ${s.toUpperCase()} lamb")

    // However if a simple variable is immediately followed by a letter, digit or underscore
    // it must be treated as an expression
    println("Mary had a ${s}r lamb") // not $sr    
}
Output:
Mary had a little lamb
Mary had a LITTLE lamb
Mary had a littler lamb

Lambdatalk

{def original Mary had a X lamb}
-> original
{def Y little}
-> Y
{S.replace X by {Y} in {original}}
-> Mary had a little lamb

Lasso

Lasso doesn't really have built-in string interpolation, but you can use the built-in email mail-merge capability:

email_merge("Mary had a #adjective# lamb", map("token"="little", "adjective"=""), null, 'plain')
Output:
Mary had a little lamb

LiveCode

Livecode has a merge function for interpolation

local str="little"
put merge("Mary had a [[str]] lamb.")

-- Mary had a little lamb.

Lua

Variable names

There is no default support for automatic interpolation of variables names being used as placeholders within a string. However, interpolation is easily emulated by using the [string.gsub] function:

str = string.gsub( "Mary had a X lamb.", "X", "little" )
print( str )

or using [string.format] function like C:

str1 = string.format( "Mary had a %s lamb.", "little" )
str2 = ( "Mary had a %s lamb." ):format( "little" )
print( str1, str2 )

Literal characters

Interpolation of literal characters escape sequences does occur within a string:

print "Mary had a \n lamb"    -- The \n is interpreted as an escape sequence for a newline

M2000 Interpreter

module checkit {
      size$="little"
      m$=format$("Mary had a {0} lamb.", size$)
      Print m$
      Const RightJustify=1
      \\ format$(string_expression)  process escape codes
      Report RightJustify, format$(format$("Mary had a {0} {1} lamb.\r\n We use {0} for size, and {1} for color\r\n", size$, "wh"+"ite"))
      \\ we can use { } for multi line string
      Report RightJustify, format$({Mary had a {0} {1} lamb.
             We use {0} for size, and {1} for color
             }, size$, "wh"+"ite")
}
checkit

Mathematica/Wolfram Language

Extra = "little";
StringReplace["Mary had a X lamb.", {"X" -> Extra}]
->"Mary had a little lamb."

Maxima

printf(true, "Mary had a ~a lamb", "little");

Neko

/**
 <doc><h2>String interpolation, in Neko</h2>
   <p><a href="https://nekovm.org/doc/view/string/">NekoVM String Library</a></p>
 </doc>
**/

var sprintf = $loader.loadprim("std@sprintf", 2)

$print(sprintf("Mary had a %s lamb\n", "little"))
Output:
prompt$ nekoc string-interpolation.neko
prompt$ neko string-interpolation.n
Mary had a little lamb

Nemerle

Nemerle has a few ways to accomplish this. It provides an implementation of printf(), $ interpolation within the print() method, and the most general use is $ interpolation within $ quoted strings.

using System;
using System.Console;
using Nemerle.IO;  // contains printf() and print()

module Stringy
{
    Main() : void
    {
        def extra = "little";
        printf("Mary had a %s lamb.\n", extra);
        print("Mary had a $extra lamb.\n");
        WriteLine($"Mary had a $extra lamb.");
    }
}

NetRexx

The Built In Functions (BIFs) of NetRexx can be employed to manipulate strings quite successfully but for more flexible string interpolation a function package like Java's MessageFormat should be used.

/* NetRexx */

options replace format comments java crossref savelog symbols

import java.text.MessageFormat
import java.text.FieldPosition

useBif()
useMessageFormat()

return

method useBif public static

  st = "Mary had a %1$ lamb."
  si = 'little'

  say st.changestr('%1$', si)

  return

method useMessageFormat public static

  result = StringBuffer('')

  args = Object [                       -
    Object Integer(7),                  -
    Object Date(),                      -
    Object 'a disturbance in the Force' -
  ]
  msgfmt = MessageFormat('At {1, time} on {1, date}, there was {2} on planet {0, number, integer}.')
  result = msgfmt.format(args, result, FieldPosition(0))
  say result

  return
Output:
Mary had a little lamb.
At 5:43:05 PM on Aug 22, 2011, there was a disturbance in the Force on planet 7.

Nim

Nim offers two methods to build a string with interpolation. The first one uses the procedure format or the operator %. Note that with the procedure, an implicit conversion of the arguments is done. With the operator, the conversion must be explicit, using for instance the $ operator.

import strutils

var str = "little"
echo "Mary had a $# lamb".format(str)
echo "Mary had a $# lamb" % [str]
# Note: doesn't need an array for a single substitution, but uses an array for multiple substitutions.

The second method allows to place the expressions directly in the string. There is also two forms, one using the prefix "fmt", the other using the prefix "&". The second form must be used if the string contains newline characters.

import strformat

var str: string = "little"
echo fmt"Mary had a {str} lamb"
echo &"Mary had a {str} lamb"

OCaml

The OCaml standard library provides the module Printf:

let extra = "little" in
Printf.printf "Mary had a %s lamb." extra

Another option is to use compiler plugin mechanism and ppx_string_interpolation:

let extra = "little" in
[%string "Mary had a $extra lamb."]

OOC

In a String all expressions between #{...} will be evaluated.

main: func {
  X := "little"
  "Mary had a #{X} lamb" println()
}

Oz

String interpolation is unidiomatic in Oz. Instead, "virtual strings" are used. Virtual strings are tuples of printable values and are supported by many library functions.

declare
  X = "little"
in
  {System.showInfo "Mary had a "#X#" lamb"}

PARI/GP

The Pari library has string interpolation, which extends C's:

GEN
string_interpolate(GEN n)
{
  pari_printf("The value was: %Ps.\n", n);
  GEN s = pari_sprintf("Storing %Ps in a string", n);
}
Works with: PARI/GP version version 2.4.4 and above

GP can also interpolate strings:

s=Strprintf("The value was: %Ps", 1<<20);
printf("The value was: %Ps", 1<<20);

Perl

$extra = "little";
print "Mary had a $extra lamb.\n";
printf "Mary had a %s lamb.\n", $extra;

Phix

Library: Phix/basics
string size = "little"
string s = sprintf("Mary had a %s lamb.",{size})
?s
Output:
"Mary had a little lamb."

Phixmonti

/# Rosetta Code problem: https://rosettacode.org/wiki/String_interpolation_(included)
by Galileo, 11/2022 #/

include ..\Utilitys.pmt

"big" var s

( "Mary had a " s " lamb" ) lprint nl

"little" var s

( "Mary had a " s " lamb" ) lprint
Output:
Mary had a big lamb
Mary had a little lamb
=== Press any key to exit ===

PHP

<?php
$extra = 'little';
echo "Mary had a $extra lamb.\n";
printf("Mary had a %s lamb.\n", $extra);
?>

Picat

main => 
  V = "little",
  printf("Mary had a %w lamb\n", V),
  
  % As a function
  S = to_fstring("Mary had a %w lamb", V),
  println(S).


PicoLisp

(let Extra "little"
   (prinl (text "Mary had a @1 lamb." Extra)) )

PL/I

*process or(!) source xref attributes;
 sit: Proc Options(main);
 /*********************************************************************
 * Test string replacement
 * 02.08.2013 Walter Pachl
 *********************************************************************/
 Dcl s Char(50) Var Init('Mary had a &X lamb. It is &X');
 Put Edit(repl(s,'little','&X'))(Skip,A);

 repl: Proc(str,new,old) Returns(Char(50) Var);
 /*********************************************************************
 * ooREXX has CHANGESTR(old,str,new[,count])
 * repl follows, however, the translate "philosophy"
 * translate(str,new,old) when old and new are just  a character each
 * and replaces all occurrences of old in str by new
 *********************************************************************/
 Dcl str Char(*) Var;
 Dcl (new,old) Char(*);
 Dcl (res,tmp) Char(50) Var init('');
 Dcl p Bin Fixed(31);
 tmp=str;                             /* copy the input string       */
 Do Until(p=0);
   p=index(tmp,old);                  /* position of old in tmp      */
   If p>0 Then Do;                    /* found                       */
     res=res!!left(tmp,p-1)!!new;     /* append new to current result*/
     tmp=substr(tmp,p+length(old));   /* prepare rest of input       */
     End;
   End;
 res=res!!tmp;                        /* final append                */
 Return(res);
 End;
 End;
Output:
Mary had a little lamb. It is little

PowerShell

Using the format (-f) operator:

$extra = "little"
"Mary had a {0} lamb." -f $extra

Using format string with the WriteLine static method

$extra = "little"
[console]::writeline("Mary had a {0} lamb.", $extra)

Using the format method of the string type

$extra = "little"
[string]::Format("Mary had a {0} lamb.", $extra)

Note: numeric and date/time formats can be specified with {index:formatString} (i.e. {0:###,###})

Prolog

Extra = little,
format('Mary had a ~w lamb.', [Extra]),  % display result
format(atom(Atom), 'Mary had a ~w lamb.', [Extra]).  % ... or store it a variable

Using library(func) for SWI-Prolog:

Extra = little,
Atom = 'Mary had a ~w lamb' $ Extra.

Using library(interpolate) for SWI-Prolog:

Extra = little,
Atom = 'Mary had a $Extra lamb'.

PureBasic

The function ReplaceString() is built-in and can have both constants and variables as parameters.

ReplaceString("Mary had a X lamb.","X","little")

Implemented in a program context

; String variable can be defined by appending .s to its name during definition or by appending and using $ as a part of its name.
Define txt$, txtvar.s="little"

;Load datasegment into variable txt$
Restore Mary 
Read.s  txt$

; Replace X with "little" and store result in txt$
txt$=ReplaceString(txt$,"X",txtvar)

OpenConsole(): Print(txt$)

DataSection:
  Mary:
  Data.s  "Mary had a X lamb."
EndDataSection

Python

Python has more than one inbuilt way of accomplishing the task. The methods have different capabilities that are not stretched by this small task

Using the % string interpolation operator:

>>> original = 'Mary had a %s lamb.'
>>> extra = 'little'
>>> original % extra
'Mary had a little lamb.'

Using the .format method of strings:

>>> original = 'Mary had a {extra} lamb.'
>>> extra = 'little'
>>> original.format(**locals())
'Mary had a little lamb.'

Using the format method, but replace by an expressions position as an argument to the format method call instead of by name:

>>> original = 'Mary had a {0} lamb.'
>>> extra = 'little'
>>> original.format(extra)
'Mary had a little lamb.'

Using the Template class of the string module:

>>> from string import Template
>>> original = Template('Mary had a $extra lamb.')
>>> extra = 'little'
>>> original.substitute(**locals())
'Mary had a little lamb.'

Using the new f-strings string literal available from Python 3.6:

>>> extra = 'little'
>>> f'Mary had a {extra} lamb.'
'Mary had a little lamb.'
>>>

Quackery

The Task

Quackery does not have built-in string interpolation.

Not The Task

interpolate$ replaces every instance of a specified character in a string with a specified string. Note that the specified string should not include the specified character as this will cause interpolate$ to loop indefinitely.

  [ stack ] is int.chr
  [ stack ] is int.str

  [ int.str put
    int.chr put
    [] swap witheach
      [ dup int.chr share = if
          [ drop int.str share ]
        join ]
    int.str release
    int.chr release ]            is interpolate$ ( $ n $ --> $ )

$ "Mary had a lamb." char X $ "little" interpolate$ echo$ cr
$ "Mary had a X lamb." char X $ "little" interpolate$ echo$ cr
$ "Mary had a X X lamb." char X $ "little" interpolate$ echo$ cr
Output:
Mary had a lamb.
Mary had a little lamb.
Mary had a little little lamb.

QB64

DefStr S

' Qbasic /QuickBasic MID$ statement needs that string2 and substring
' to replace in string1 must have the same length,
' otherwise it overwrites the following part of string1
String1 = "Mary has a X lamb"
Print String1, "Original String1"
Print "Interpolation of string by MID$ statement"
String2 = "little"
Mid$(String1, InStr(String1, "X")) = String2
Print String1

String1 = "Mary has a X lamb"
String2 = "@"
Mid$(String1, InStr(String1, "X")) = String2
Print String1

Print "Interpolation by string's functions"
String1 = "Mary has a X lamb"
String2 = "little"
String1 = Mid$(String1, 1, InStr(String1, "X") - 1) + String2 + Mid$(String1, InStr(String1, "X") + 1, Len(String1) - InStr(String1, "X"))
Print String1, "by MID$"

String1 = "Mary has a X lamb"
String2 = "#§[]@"
String1 = Left$(String1, InStr(String1, "X") - 1) + String2 + Right$(String1, Len(String1) - InStr(String1, "X") + 1)
Print String1, "by LEFT$ and RIGHT$"

Racket

See the documentation on fprintf for more information on string interpolation in Racket.

#lang racket

(format "Mary had a ~a lamb" "little")

Raku

(formerly Perl 6)

my $extra = "little";
say "Mary had a $extra lamb";           # variable interpolation
say "Mary had a { $extra } lamb";       # expression interpolation
printf "Mary had a %s lamb.\n", $extra; # standard printf
say $extra.fmt("Mary had a %s lamb");   # inside-out printf
my @lambs = <Jimmy Bobby Tommy>;
say Q :array { $$$ The lambs are called @lambs[]\\\.} # only @-sigiled containers are interpolated

REBOL

str: "Mary had a <%size%> lamb"
size: "little"
build-markup str

;REBOL3 also has the REWORD function
str: "Mary had a $size lamb"
reword str [size "little"]

REXX

Interpolation does not occur in literal strings, neither within   singlequote   or   doublequote   enclosures.
However, interpolation can be emulated using the   changestr   function:

/*REXX program to demonstrate string interpolation (string replacement).*/
                                       /*the string to be replaced is   */
replace   = "little"                   /*usually a unique character(s)  */
                                       /*string and is  case  sensative.*/
original1 = "Mary had a X lamb."
new1      = changestr('X', original1, replace)
say 'original1 =' original1
say 'replaced  =' new1
say

original2 = "Mary had a % lamb."
new2      = changestr('%', original2, replace)
say 'original2 =' original2
say 'replaced  =' new2
say

original3 = "Mary had a $$$ lamb."
new3      = changestr('$$$',original3,replace)
say 'original3 =' original3
say 'replaced3 =' new3
say

original4 = "Mary had a someKindOf lamb."
new3      = changestr('someKindOf', original4, "little")
say 'original4 =' original4
say 'replaced4 =' new3
                                       /*stick a fork in it, we're done.*/

Some older REXXes don't have a   changestr   BIF,   so one is included here   ──►   CHANGESTR.REX.

output

original1 = Mary had a X lamb.
replaced  = Mary had a little lamb.

original2 = Mary had a % lamb.
replaced  = Mary had a little lamb.

original3 = Mary had a $$$ lamb.
replaced3 = Mary had a little lamb.

original4 = Mary had a someKindOf lamb.
replaced4 = Mary had a little lamb.

Ring

aString =substr("Mary had a X lamb.", "X", "little")
see aString + nl

An alternate approach using the print() function:

extra = "little"
print("Mary had a #{extra} lamb.\n")

Ruby

irb(main):001:0> extra = 'little'
=> "little"
irb(main):002:0> "Mary had a #{extra} lamb."
=> "Mary had a little lamb."
irb(main):003:0> "Mary had a %s lamb." % extra
=> "Mary had a little lamb."

Documentation:

  • string_spec.rb describes interpolation using #{....} in double-quoted strings.
  • Core API describes printf-style interpolation by String#% and Kernel#sprintf.

Run BASIC

"a$ = Mary had a X lamb."
a$ = word$(a$,1,"X")+"little"+word$(a$,2,"X")
print a$

Rust

Rust has very powerful string interpolation. Documentation here.

fn main() {
    println!("Mary had a {} lamb", "little");
    // You can specify order
    println!("{1} had a {0} lamb", "little", "Mary");
    // Or named arguments if you prefer
    println!("{name} had a {adj} lamb", adj="little", name="Mary");
}

Scala

Library: Scala
object StringInterpolation extends App {

  import util.matching.Regex._
  val size = "little"

  { // Method I (preferred)
    // Scala 2.10.0 supports direct string interpolation
    // by putting "s" at the beginning of the string.
    println("V2.10+  : " + s"Mary had a $size lamb,")
  }

  { // Method II
    // Pre Scala 2.10 indirect use of Java Class Formatter
    val originalFormatter = "Mary had a %s lamb,"
    println("V2.10- 1: " + originalFormatter format size)
    // Above mentioned is Scala's postfix notation and equivalent for: 
    println("V2.10- 2: " + originalFormatter.format(size))
    // Also possible
    printf(("V2.10- 3: " + originalFormatter + '\n').format(size))
    // All will be expanded to
    print(("V2.10- 3: " + originalFormatter + '\n').format(size))
    print((new java.util.Formatter).format("V2.10- 4: " + originalFormatter + '\n', size))
  }

  { // Method III
    // Regular expressions, only for demonstration
    val extractor = """\$\{([^}]+)\}""".r
    println((extractor.replaceAllIn("Regex  1: Mary had a ${x} lamb,", "snow white")))

    // RegEx freaking
    def interpolate(text: String, vars: (String, String)*) =
      extractor.replaceAllIn(text,
        _ match { case Groups(v) => vars.toMap.getOrElse(v, "" /*in case nothing provided*/ ) })

    println(interpolate("Regex  2: ${who} had a ${size} ${pet}, ${unknown}",
      ("pet", "lamb"), ("size", "fat"), ("size", "humongous"), ("who", "Mary")))
  }

  { // Method IV, not recommended.
    // Standard API method, search argument (1st ones) supposed to be a regular expression
    println("Replace1: " + "Mary had a ${x} lamb".replaceAll("""\$\{x\}""", size))
    // Standard API method, literally, on regular expression
    println("Replace2: " + "Mary had a ${x} lamb".replaceAllLiterally("${x}", size))
  }

  { // Method IV, not recommended.
    println("Split   : " + "Mary had a ${x} lamb.".split("""\$\{([^}]+)\}""").mkString(size))
  }
}

Documentation:

Sed

#!/bin/bash
# Usage example: . interpolate "Mary has a X lamb" "quite annoying"
echo "$1" | sed "s/ X / $2 /g"

Seed7

$ include "seed7_05.s7i";

const proc: main is func
  local
    const string: original is "Mary had a X lamb";
    const string: little is "little";
    var string: replaced is "";
  begin
    replaced := replace(original, "X", little);
    writeln(replaced);
  end func;
Output:
Mary had a little lamb

SenseTalk

SenseTalk does string interpolation through the merge function, which can evaluate any sort of embedded expression, including entire sections of code like conditionals or repeat loops. For convenience, the merge function can be invoked by simply using a ! before a string literal (this is needed because string literals are actually literal in SenseTalk -- there are no characters with hidden meaning by default).

put "little" into x

put "Mary had a [[x]] lamb." -- this is a literal string
put !"Mary had a [[x]] lamb." -- this is an interpolated string
put
put !"[[repeat with n=2 to 6]]Mary had [[n]] [[x]] lambs.[[return]][[end repeat]]"
put !"Mary had [[repeat with n=2 to 6]][[n]] [[x]] [[end repeat]]lambs."
Output:
Mary had a [[x]] lamb.
Mary had a little lamb.

Mary had 2 little lambs.
Mary had 3 little lambs.
Mary had 4 little lambs.
Mary had 5 little lambs.
Mary had 6 little lambs.

Mary had 2 little 3 little 4 little 5 little 6 little lambs.

Sidef

var extra = 'little';
say "Mary had a #{extra} lamb";

or:

say ("Mary had a %s lamb" % 'little');

See: documentation

Slope

(define str "little")
(display (string-format "Mary had a %v lamb." str))

Documentation.

SNOBOL4

Every statement in SNOBOL can is a subset of pattern replacement having a subject (s1 in this case), object (s2), and replacement (s3).

        s1 = "Mary had a humongous lamb."
	s2 = "humongous"
        s3 = "little"           
	s1 s2 = s3 
end

See The SNOBOL4 Programming Language; Griswold, Poage, Polonsky; Chapter 2 Pattern Matching

Stata

See printf in Stata help.

: printf("Mary had a %s lamb.\n", "little")
Mary had a little lamb.

Swift

let extra = "little"
println("Mary had a \(extra) lamb.")

Tailspin

String interpolation is the normal way to create strings in Tailspin, see string literal in the Tailspin reference

def size: 'little';
'Mary had a $size; lamb' -> !OUT::write

Tcl

String interpolation is a fundamental operation of the Tcl language itself, and is carried out in a "double-quoted" program strings as well as bare-words. Thus, interpolation of the string from a variable is carried out with the $ syntax and the string result of a command is interpolated with the […] syntax.

set size "little"
puts "Mary had a $size lamb."

proc RandomWord {args} {
   lindex $args [expr {int(rand()*[llength $args])}]
}
puts "Mary had a [RandomWord little big] lamb."

When more sophisticated control is required the format command can be used, which is very similar to the standard C library's sprintf function:

puts [format "Mary had a %s %s." [RandomWord little big] [RandomWord lamb piglet calf]]

A third approach is to use string map.

set s "Mary had a @SIZE@ lamb."
puts [string map {@SIZE@ "miniscule"} $s]

Tcl also supports variable variable names. Even more powerful is nested interpolation with the subst command.

set grandpa {$daddy}; set grandma \$mommy
set daddy myself; set mommy {lil' bro}
set fun1 \[string\ to
set fun2 lower
set lower middle
set middle upper
set fun3 {aNd]}
puts [subst "$grandpa $fun1$[subst $$fun2]  $fun3 $grandma"]

Transd

#lang transd

MainModule: {
    size: "little",

	_start: (λ 
        // Transd supports direct interpolation
        (with s String("Mary had a " size " lamb.")
            (lout s))

        // To interpolate a string variable within another
        // string variable we use 'replace'
        (with s "Mary had a %s lamb."
            (lout (replace s "%s" size)))
    )
}
Output:
Mary had a little lamb.
Mary had a little lamb.

TUSCRIPT

$$ MODE TUSCRIPT

sentence_old="Mary had a X lamb."

values=*
DATA little
DATA big

sentence_new=SUBSTITUTE (sentence_old,":X:",0,0,values)
PRINT sentence_old
PRINT sentence_new
Output:
Mary had a X lamb.
Mary had a little lamb. 

UNIX Shell

Works with: Bourne Shell

Within the Unix shell, interpolation only occurs within doublequotes. Strings enclosed in singlequotes will not be subject to interpolation. Note that within the shell, a string may be used bare. If this is done each word within the string is treated separately, and any variable references or escape sequences will be substituted for their values:

extra='little'
echo Mary had a $extra lamb.
echo "Mary had a $extra lamb."
printf "Mary had a %s lamb.\n" $extra

A parameter substitution, like $extra or ${extra}, interpolates its value into some string. This happens outside quotes or inside "double quotes". The other form of interpolation is printf(1) with %s.

The shell has more forms of parameter substitution, like ${tea:?no tea}. Your shell's manual explains those. For the original Bourne Shell, sh(1) manual explains those.

C Shell

set extra='little'
echo Mary had a $extra lamb.
echo "Mary had a $extra lamb."
printf "Mary had a %s lamb.\n" $extra

C Shell has $extra and ${extra}. There are also modifiers, like $file:t; csh(1) manual explains those.

Ursala

Expressions like this

-[foo-[ x ]-bar]-

evaluate to a list of character strings beginning with foo and ending with bar, where foo and bar are literal text (possibly multiple lines) and x is any expression evaluating to a list of character strings. Using a dot like this

-[foo-[. f ]-bar]-

makes it a function returning a list of character strings consisting of the output from the function f bracketed by the literal text foo and bar. In this task, the identity function, ~&, is used for f.

x = <'little'>

#show+

main = -[Mary had a -[. ~& ]- lamb.]- x

These operators are parsed like parentheses.

Output:
Mary had a little lamb.

Vala

void main() {
  string size = "little";
  print(@"Mary had a $size lamb\n");
  stdout.printf("Mary had a %s lamb\n", size);
}
Output:
Mary had a little lamb
Mary had a little lamb

VBA

Here are 2 examples:

With Replace

a="little"
debug.print replace("Mary had a X lamb","X",a)  'prints Mary had a little lamb

Replace

With Interpolation function

Sub Main()
    a="little"
    debug.print Format("Mary had a {0} lamb",a)
End Sub

Public Function Format(ParamArray arr() As Variant) As String
    Dim i As Long, temp As String
    temp = CStr(arr(0))
    For i = 1 To UBound(arr)
        temp = Replace(temp, "{" & i - 1 & "}", CStr(arr(i)))
    Next
    Format = temp
End Function

CStr UBound ParamArray

Verbexx

////////////////////////////////////////////////////////////////////////////////////////
//
//  The @INTERPOLATE verb processes a string with imbedded blocks of code.  The code
//  blocks are parsed and evaluated.  Any results are converted to a string, which 
//  is then inserted into the output string, replacing the code and braces.
//  
// example: @INTERPOLATE "text{ @IF (x > y) then:{x} else:{y} }more text "
//
////////////////////////////////////////////////////////////////////////////////////////

@VAR v = "little"; 

@SAY (@INTERPOLATE "Mary had a { v } lamb");

//   output:    Mary had a litle lamb

Visual Basic .NET

Dim name as String = "J. Doe"
Dim balance as Double = 123.45
Dim prompt as String = String.Format("Hello {0}, your balance is {1}.", name, balance)
Console.WriteLine(prompt)

Wren

var s = "little"
var t = "Mary had a %(s) lamb"
System.print(t)
Output:
Mary had a little lamb

V (Vlang)

txt := "little"
str := "Mary had a $txt lamb"
println(str)

XPL0

char X;
[X:= "little";
Text(0, "Mary had a ");  Text(0, X);  Text(0, " lamb.");
]

zkl

"Mary had a X lamb.".replace("X","big")

Generates a new string. For more info, refer to manual in the downloads section of zenkinetic.com zkl page