1

I am having what I believe to be a syntax issue in Common Lisp. I have a global variable, *LOC*, I can set its initial value and change it. My issue isn't with the variable, it works fine, it is when I try to display a message with its value.

For example, When i use an if statement and say something like:

(if ( UPSTAIRSP *LOC*)

           (progn (princ "I AM UPSTAIRS IN THE *LOC*"))
           (progn (princ "I AM DOWNSTAIRS IN THE *LOC*"))
)

I will get:

I AM UPSTAIRS IN THE *LOC*

I'm pretty sure it is because my variable is in the quotations, but I don't know how else to express it.

coredump
  • 37,664
  • 5
  • 43
  • 77
  • Common Lisp does not do string interpolation by default. It's possible to write string interpolation libraries, then use those. – Vatine May 18 '16 at 10:10

2 Answers2

9

First, you don't need to use progn if you only have a single expression in one of the IF branches. Now, as you said, variables are not interpolated in strings. For actual string interpolation, see this answer, but I think you should first try to learn a little more about the basics.

You could print things like so:

(if (upstairsp *LOC*)
  (progn 
    (princ "I AM UPSTAIRS IN THE ")
    (princ *LOC*))
  (progn 
    (princ "I AM DOWNSTAIRS IN THE ")
    (princ *LOC*)))

Generally, when you spot IF with PROGN, chances are that you need COND. Here this is not necessary because you print *LOC* in both branches and you can factor that outside of the conditional.

(progn
  (if (upstairsp *LOC*)
    (princ "I AM UPSTAIRS IN THE ")
    (princ "I AM DOWNSTAIRS IN THE "))
  (princ *LOC*))

But you should probably use FORMAT instead. For example:

(if (upstairsp *LOC*)
  (format t "I AM UPSTAIRS IN THE ~A" *LOC*)
  (format t "I AM DOWNSTAIRS IN THE ~A" *LOC*))

In fact, FORMAT supports conditional directives. Below, the return value of (upstairsp *LOC*), a boolean, is used in the ~:[...~;...~] directive to select which text to print:

(format t 
        "I AM ~:[DOWNSTAIRS~;UPSTAIRS~] IN THE ~A"
        (upstairsp *LOC*)
        *LOC*)

Have a look at A Few Format Recipes (Practical Common Lisp, Seibel) for more examples.

Community
  • 1
  • 1
coredump
  • 37,664
  • 5
  • 43
  • 77
2

In Common Lisp you can compose string and values either for printing or for other purposes with the format operator:

(if (upstairsp *LOC*)
    (format t "I AM UPSTAIRS IN THE ~a" *LOC*)
    (format t "I AM DOWNSTAIRS IN THE ~a" *LOC*"))

The first parameter of format is a stream (or T for the standard output), to print the message on that stream, or NIL to produce a formatted string. You can find all the details in tha manual.

Renzo
  • 26,848
  • 5
  • 49
  • 61