6

I'm currently trying to get an output of ... \hline in GNU Common lisp 2.49, but I can't get the format to work. This is what I've tried so far to get a single backslash:

(format nil "\ ") => " "
(format nil "\\ ") => "\\ "
(format nil "\\\ ") => "\\ "

I thought that the double backslash would make it work, why isn't the backslash escaping just the other backslash?

DarkSuniuM
  • 2,523
  • 2
  • 26
  • 43
iHowell
  • 2,263
  • 1
  • 25
  • 49
  • 2
    Note that you don't do any output. You create data - here a string - which then is printed by the REPL. If you want do output with FORMAT, you need to give FORMAT a stream instead of NIL. – Rainer Joswig Oct 12 '18 at 18:53

2 Answers2

8

See for example:

CL-USER> (write "\\" :escape nil)
\
"\\"

Here above, the first backslash is your string, printed without escaping backslashes. The returned value is the string, printed by the REPL with the standard io syntax (http://clhs.lisp.se/Body/m_w_std_.htm), which escapes strings.

So, your string contains a single backslash, but is printed in such a way that it can be read back, hence the need to escape the backslash in the output string.

Note also that calling format with NIL and a single string returns the same string.

You can inspect your strings, for example by mapping each character to its name:

(loop
   for input in '("\ " 
                  "\\ "
                  "\\\ ")
   collect (list :input input
                 :characters (map 'list #'char-name input)))

This gives:

((:INPUT " " :CHARACTERS ("Space"))
 (:INPUT "\\ " :CHARACTERS ("REVERSE_SOLIDUS" "Space"))
 (:INPUT "\\ " :CHARACTERS ("REVERSE_SOLIDUS" "Space")))

Or, simply use inspect:

CL-USER> (inspect "\\hline")

The object is a VECTOR of length 6.
0. #\\
1. #\h
2. #\l
3. #\i
4. #\n
5. #\e
coredump
  • 37,664
  • 5
  • 43
  • 77
  • 1
    This is a thorough and wonderful answer, which teaches you other inspecting-fus too. Thank you! – Student Jan 28 '21 at 13:42
6

Note the difference between creating a string and actually doing output to a stream:

CL-USER 69 > (format nil "\\ ")
"\\ "                               ; result

CL-USER 70 > (format t "\\ ")
\                                   ; output
NIL                                 ; result

CL-USER 71 > (format *standard-output* "\\ ")
\                                   ; output
NIL                                 ; result
Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346