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

Helpful: Adding Contextual Help to Emacs

Suggest.el: Synthesising Constants

Optimising Dash.el

These Weeks in Remacs II

Synthesising Elisp Code