Messages#
Printing text in the console is essential to be able to debug your code. There are several ways to do that.
The display
function prints any object (be it a string or not). Use it several
times to print several objects. display
does not insert any newlines
automatically; you need to add a newline at the end of the string (if you are
displaying a string), or to add a call (display "\n")
, which can be shortened
as (newline)
. For example, this code:
(define surname "Salima")
(display "Hello ")
(display surname)
(display "!\n")
can also be written
(define surname "Salima")
(display "Hello ")
(display surname)
(display "!")
(newline)
Both of the examples above were somewhat tedious. It is more convenient to use
the format
procedure. To begin, we are going to use #t
as its first argument
(read on to understand what this object is). The second argument is a string,
which can contain special sequences. There must be the same number of remaining
arguments as special sequences. They are formatted in a certain way depending on
which special sequence is used, and inserted in the string. The formatted string
is then displayed on the console. One of the commonly used escape sequences is
~a
, which prints objects exactly like display
would.
(define surname "Salima")
(format #t "Hello ~a!\n" surname)
⊨ Hello Salima!
⇒ #t
With #t
, format
returns an unimportant value. On the other hand, if #f
is
used, format
returns the formatted string, without displaying it:
(define surname "Salima")
(format #f "Hello ~a!" surname)
⇒ "Hello Salima!"
As an example, LilyPond extensively uses format
with #f
to build its
PostScript output. The following code excerpt is taken from
framework-ps.scm.
(format #f "%%BeginDocument: ~a
~a
%%EndDocument
"
file-name
(cached-file-contents file-name))
There is another procedure, which is defined by LilyPond, called ly:message
.
It works much like format
. Its only purpose is to display the messages, so it
does not take the first argument #t
or #f
; it is as if #t
were used. Its
advantage is that it prints the message in the standard error stream, not in the
standard output stream, which prevents it from being intermingled with the rest
of logging messages in the Frescobaldi interface (or another interface).
(Actually, it would be possible to replace #t
with (current-error-port)
in
format
to get the same effect.) Moreover, ly:message
automatically prepends
a newline.
(define file "emmentaler-20.otf")
(ly:message "Reading ~a..." file)
⊨ Reading emmentaler-20.otf...
Another special sequence is ~s
. It formats values like the sandbox would do.
For example, it prints quotes around strings. ~s
is more suitable for
debugging than ~a
.
(define file "emmentaler-20.otf")
(ly:message "Reading ~s..." file)
⊨ Reading "emmentaler-20.otf"...