1atera1usz
1atera1usz

Reputation: 143

How to print blank character in the Lisp format function?

I hope there's someone to help me with this, because I can't find any useful answer, and I'm new with Lisp.

What I'm trying to do is to test a value of one element and to print something if its 1, otherwise to print blank character. This works when all of the list arguments have the value 1:

(defun print-lst (list)
  (format t "~%~a ~a ~a~%"
          (if (= (nth 0 list) '1)
              '¦)
          (if (= (nth 1 list) '1)
              'P)
          (if (= (nth 2 list) '1)
              '¦)))

so the output is ¦ P ¦. But, if the second element in list is 0, it prints NIL on that place ¦ NIL ¦ and I want it to print a space instead ¦ ¦(not just to skip that character¦¦, it is important to there is a blank character in that position in output line if the tested value is not 1).

Is there any way to return a blank character if the condition (if (= (nth 1 list) '1) 'P) is not fulfilled or is there any other way to perform this? I hope I explained that nicely. Thank you.

Upvotes: 3

Views: 4344

Answers (4)

Matthias Benkard
Matthias Benkard

Reputation: 15769

If you want to make full use of the power of format, you can use a combination of format conditionals and format GOTO.

Like this:

[1]> (format nil "~@{~:[<nothing>~;~:*~A~]~^ ~}" 1 2 nil 4 nil 6)
"1 2 <nothing> 4 <nothing> 6"

In your case, this should work:

(format t "~&~@{~:[ ~;~:*~A~]~^ ~}"
        ...)

This works by doing the following:

  1. ~& inserts a newline unless we're already at the beginning of a line.
  2. ~@{...~} processes the arguments iteratively.
  3. ~:[...~;...~] chooses between the nil and non-nil case.
  4. ~:* unconsumes the argument that was consumed by ~:[...~].
  5. ~A outputs the item being processed.
  6. ~^ escapes from the loop on the last iteration (so as not to output an excessive space after the last item).

Upvotes: 7

Inaimathi
Inaimathi

Reputation: 14065

Format is a beast waiting to devour the unwary.

That said, it looks like you may want to use some of its higher level directives here. Check out the Formatted Output section of the Lisp Hyperspec, and the format chapter of PCL (specifically, look at the section that deals with conditional formatting).

Upvotes: 0

Curd
Curd

Reputation: 12457

Counter question:
Do you really need output values that are identifiers ('something) or would also string literals work ("something")?

If the first is true: I suppose it is not possible to use space as an identifier.
If the second is true: use "|", "P" and " " as output values

Upvotes: 0

Svante
Svante

Reputation: 51511

If takes three arguments: condition, then-form, else-form; the else-form is optional. Besides, I would use literal character syntax for literal characters.

(if (= (nth 0 list) 1)
    #\P
    #\Space)

Documentation:

Upvotes: 5

Related Questions