emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RFC: String interpolation


From: Clément Pit--Claudel
Subject: RFC: String interpolation
Date: Wed, 7 Dec 2016 20:13:41 -0500
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.5.1

Hi all,

Many languages are gaining literal string interpolations features of late (the 
latest example is Python; see https://www.python.org/dev/peps/pep-0498/).  The 
TL;DR is that in Python 3.6 one can write this:

    value = 1.3
    print(f'The value is {value + 1:.2f}.')

This prints "The value is 2.30."  Plenty of other languages have similar 
features.

It would be nice if Emacs offered something similar out of the box. It could be 
a reader macro, but a plain macro would do just as well, and indeed it's 
relatively easy to code something up (I attached an example implementation).

With the attached fmt.el, you can write things like this:

    (let ((a 12) (b 15))
      (fmt "$a + $b = $(+ a b)"))
    ⇒ "12 + 15 = 27"

    (let ((password "letmein"))
      (fmt "The password is ${password}"))
    ⇒ "The password is letmein"

    (let ((n 25) (price-per-unit 10.5))
      (fmt "The price for $n units is €$[%.2f](* n price-per-unit)"))
    ⇒ "The price for 25 units is €262.50"

    (fmt "Here's a symbol: '${'a}; "
         "and a padded number: ‘$[%-6.3f]{1}’.")
    ⇒ "Here's a symbol: 'a; and a padded number: ‘1.000 ’."

    (fmt "Welcome to Emacs! "
         "Press $[where-is]{'help-with-tutorial} to open the tutorial.")
    ⇒ "Welcome to Emacs! Press C-h t to open the tutorial."

    (fmt "Today is $[date|%Y-%m-%d](current-time).")
    ⇒ "Today is 2016-12-07."

There's also an fmt-message macro that just calls ‘message’ on the interpolated 
string. The prototype that I attached supports a range of placeholders:

* $a, $a-b, $abc-123-def expand to the values of the corresponding variables
* ${a}, ${123}, ${[x y z]}, ${(+ 1 2)} expand to the value of the corresponding 
ELisp forms
* $(+ 1 2), $(buffer-file-name), $(current-column) are a shorthand for ${(…)}
* $[%.2f](+ 1 2) and $[%S]{'(1 2 3)} feed the result of evaluation through 
format, with the given specifier
* $[whereis]{…}' and $[date|%Y-%m-%d]{…} feed the result of evaluating "…" 
through a custom formatting function, with an optional format specifier
* $$ produces a literal $ sign

fmt expands the strings at compile time (so they must be constant strings).  
For example, (fmt "$a + $b = $[%.2f](+ a b)") more or less expands to

    (concat (fmt--print a) " + " (fmt--print b) " = " (fmt--print (+ a b) 
'format "%.2f"))

(fmt--print is a thin wrapper that sets print-depth and print-length).

I'd like some feedback on the following:

* Should this go into MELPA, ELPA, or core?
* What do we think of the syntax? An alternative to $[…]{…} would be ${…}%… 
(which is a bit trickier to parse, and makes it hard to have custom formatters).

Cheers,
Clément.

Attachment: fmt.el
Description: Text Data

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]