9

I understand that this is trivial with an if, but is there an option, like %S or %s that interpolates nil as no string at all?

Example:

(format "%?.el" nil) ; ".el"
(format "%?.el" "beginner") ; "beginner.el"
Drew
  • 75,699
  • 9
  • 109
  • 225
The Unfun Cat
  • 2,393
  • 16
  • 32
  • Ps. requesting `interpolation` tag. – The Unfun Cat Mar 01 '15 at 08:36
  • FWIW, "interpolate" meant nothing to me in this title. "Format" would have been clearer. – Malabarba Mar 01 '15 at 08:43
  • @Malabarba Perhaps it isn't a common (or the right?) term in the elisp world. – The Unfun Cat Mar 01 '15 at 08:52
  • 1
    Yes, string interpolation is the right term to use. It's a variation on the subject of quoting / macros, where strings are generated using templates. – wvxvw Mar 01 '15 at 08:59
  • Also, depending on how much formatting you need to do, you might consider this: https://github.com/magnars/s.el#s-format-template-replacer-optional-extra (s.el is a modern ELisp library that tries to provide many useful string-processing functions). @Malabarba - formatting is a subset of interpolation, so it's not really a matter of habit. But it is true that the code that deals with string templates in many Lisps is not included in the standard library (unlike in, say, Python, Ruby or PHP). – wvxvw Mar 01 '15 at 09:16
  • 1
    It's a good question. Consider requesting a `format` indicator for this (use `M-x report-emacs-bug` for that). The rest of us have gotten used to using `concat` for this, sometimes in combination with `format` (for other conversions). Or else passing an arg to `format` such as `(if something "foobar" "")`, corresponding to `format` indicator `"%s"`. – Drew Mar 01 '15 at 15:10
  • 2
    FYI - I just filed such an [enhancement request](http://debbugs.gnu.org/cgi/bugreport.cgi?bug=19975) (#19975), so you don't need to. (Should have done that years ago.) – Drew Mar 01 '15 at 15:35
  • Thanks. Andreas suggests `(or foo "")` which is a decent idiom I guess, but I want to interpolate MANY possibly nil values into this giant regex which makes it a chore. Thanks Drew. – The Unfun Cat Mar 01 '15 at 18:16
  • 1
    That sounds like a pretty dubious way to build a regexp (perhaps consider using the `rx` macro in such a scenario. At minimum make sure you are `regexp-quote`ing as appropriate), but that aside if you have a large number of maybe-strings in LIST you could always do something like `(apply 'format "%s%s%s%s" (mapcar (lambda (x) (or x "")) LIST))`. Of course if your format string is literally like `"%s%s%s"`, then `concat` does indeed make more sense. – phils Mar 02 '15 at 00:21

2 Answers2

9

Depending on your application, concat might be of use:

(concat "live long " nil "and prosper")
;; => "live long and prosper"

This works because concat acts on sequences, and nil is an empty list.

Malabarba
  • 22,878
  • 6
  • 78
  • 163
6

The special form or is useful here. This macro returns the value of the first argument, unless it's nil in which case it returns the second. So, assuming the variable you want to check is foo, the following will do what you want:

(format "%s.el" (or foo ""))

In some ways it's better than a magic tag since it makes it clear what value should be returned if the argument is nil.