The Astounding Variety of Groovy Strings


I’ve been writing Groovy recently. Groovy has a shockingly flexible string syntax, as I discovered when trying to improve the Emacs mode.

Groovy tries really hard to make you happy. It provides normal strings:

"hello world"

and since it’s a recent scripting language, it provides string interpolation too!

def name = "wilfred"
"hello $name"

Groovy doesn’t stop there, however. Oh no.

The string interpolation is very flexible. You can access object attributes, or even write arbitrary Groovy expressions.

"hello $user.name"
// Interpolations are challenging to highlight,
// because { } can nest!
"hello ${if (true) { 1 } else { 2 }}"

Naturally, you might not always want interpolation. Groovy provides an escaping mechanism, and an additional syntax for this:

// Escaping the $.
"the cost is \$10"
// No interpolation with single-quoted strings.
'the cost is $10'

You want multiline strings? Groovy has those too, in both interpolated and raw flavours:

"""hello
world"""
'''hello
world'''

These are useful, but sometimes you want to start a line with """. Groovy lets you escape that:

def foo = """\
line 1 (no newline before this line)
line 2"""

Other scripting languages also support a /foo/ syntax. Groovy users might want this as well, so of course they’re available:

// This is tricky to highlight correctly, because "" is 
// an empty string but // begins a comment.
/fo+b{ar,az}/

For the brave of heart, you can interpolate into your regular expressions:

// Simple interpolation.
def name = "wilfred"
/user $name/

// However, what if we want to use $ in a pattern?
// This works because $ is not a legal interpolation,
// so it magically falls back to a literal pattern.
/user$/

Groovy doesn’t even stop here. What if you have a string with many embedded single-quotes and double-quotes? The interpolated, multiline, dollar-slashy-string is available!

The dollar-slashy-string is so awkward to highlight that even the official docs don’t try to highlight it!

def message = $/Dear ${user.capitalize()},
Thank you for signing up to "Acme's Mailing list".

Kind Regards./$

// This string syntax has its own escaping mechanism:
"foo / /$ bar" == $/foo $/ $/$ bar/$

To stake its claim as an incredibly versatile syntax, Groovy strings have one last trick up their sleeves. Strings can be lazily evaluated!

def number = 1
def eagerString = "${number}"
number = 2
assert eagerString == "1"

// However:
def number = 1
def lazyString = "${ -> number}"
assert lazyString == "1"
number = 2
assert lazyString == "2"

Needless to say, only a total madman would try to write a syntax highlighter for this:

Groovy is a really neat language that is excellent for glue code. I’ve had a whole lot of fun making it work in Emacs.

Recent Posts

These Weeks in Remacs II

Synthesising Elisp Code

Remacs Talk Transcript

Pattern Matching in Emacs Lisp

These Weeks in Remacs