3

I tried looking through related questions, but I couldn't find a straightforward answer as to how I should define my variables in Common LISP. I use the sbcl implementation and I've been using tutorials to help me learn the language, but for some reason this code:

;;print a line many times
(setq xx 1)
(while (< xx 20)
  (message "yay")
  (setq xx (1+ xx))
  )

Returns an error: The variable XX is unbound. I also get style-warnings for while and message. Could someone point me in the right direction on what the issue is with this code?

jch
  • 5,382
  • 22
  • 41
DsDude
  • 135
  • 1
  • 8
  • 2
    Common Lisp. XX is undefined. You haven't defined it. You may want to define it. WHILE does not exist. See LOOP. MESSAGE does not exist either. Does not look like Common Lisp. Maybe you should check a language reference first. Their are also built-in tools like APROPOS and DOCUMENTATION which should help. – Rainer Joswig Apr 11 '16 at 09:53
  • 2
    **"I've been using tutorials to help me learn the language, but for some reason this code"** could you provide a link to that tutorial? **while** isn't a looping macro in Common Lisp (though you could easily define one), so either the tutorial isn't a great one, isn't a common lisp one, or provided this code in a context that hasn't been reproduced entirely. – Joshua Taylor Apr 11 '16 at 12:02
  • 1
    I would recommend [this](http://www.gigamonkeys.com/book/) over any web tutorial. – molbdnilo Apr 11 '16 at 12:25
  • @RainerJoswig Hm ... does one *need* to define a variable before use? Running `(setq foobar 42)` with nothing bound to `foobar` works fine (`CLISP-2.49`) for me ... an according to the HyperSpec `setq` does not have any "exceptional situations". – Daniel Jour Apr 11 '16 at 12:38
  • 2
    setting undefined variables has undefined consequences. Try to put it into a file and compile that file. You will see that the CLISP compiler will complain about unbound/undeclared variables. – Rainer Joswig Apr 11 '16 at 13:14
  • **"works fine (CLISP-2.49) for me"** Are you sure it doesn't have any unexpected consequences like making the variable dynamically scoped? That might not qualify as "works". :) E.g., if you run `(compile nil (lambda () (setq x 52)))` (which is like Rainer's suggestion to put it in a file and compile it), you'll get the output: "X is neither declared nor bound, it will be treated as if it were declared SPECIAL." That can lead to some confusion later. – Joshua Taylor Apr 11 '16 at 13:35
  • 1
    @DanielJour: however `setq` refers to 'a symbol naming a variable': if a symbol is unbound it does not name a variable. –  Apr 11 '16 at 13:38
  • 1
    As a note on this: I'd guess this is meant to be elisp code (based on `while` and `message`). –  Apr 11 '16 at 13:39
  • @tfb I don't think that's quite precise either, though. If you do, e.g., `(defparameter *x* 42)`, then `(makunbound '*x*)`, then `(setq *x* 43)`, I think you'd be OK, even though `*x*` is unbound at the last call. – Joshua Taylor Apr 11 '16 at 13:41
  • @JoshuaTaylor Yes: probably I meant 'unbound' and with no special declaration in effect (or symbol macro). It is too long since I thought about the details of CL. However it is clear that just using `setq` on a symbol with no other qualification is outwith the spec. –  Apr 11 '16 at 14:08
  • Hey everyone, thanks for you input, this is what I've been using: [link](http://www.tutorialspoint.com/lisp/lisp_macros.htm) I'm going to start using the book that molbdnilo said, it seems a lot better. I'm using emacs with slime which I believe it used for Common LISP development, I'm guessing the tutorial I was using was showing a different kind of LISP that would work for some other LISP implementation, right? – DsDude Apr 11 '16 at 18:09
  • No, it just seems to have very low quality. – Svante Apr 11 '16 at 21:44

2 Answers2

1

Well this tutorial doesn't seems common lisp, it seems more emacs lisp, to execute this functions use emacs and ielm command

*** Welcome to IELM ***  Type (describe-mode) for help.
ELISP> ;print a line many times
(setq xx 1)
(while (< xx 20)
  (message "yay")
  (setq xx (1+ xx))
  )
*** IELM error ***  More than one sexp in input
ELISP> (setq xx 1)
1 (#o1, #x1, ?\C-a)
ELISP> (while (< xx 20)
     (message "yay")
     (setq xx (1+ xx)))
nil
ELISP> (message "yay")
"yay"
ELISP> (while (> xx 20)
     (message "yay")
     (setq xx (1+ xx)))
nil
ELISP> xx
20 (#o24, #x14, ?\C-t)
ELISP> 

So this is one of the many reasons that this code doesn't work, if you run it in the SBCL REPL it will prompt many errors unknown function, unbound variables,...

as the comments show take a good lisp tutorial or a book, I recommend ANSI Common lisp from Paul Graham but if you like fun Land of Lisp from Conrad barski is your book, and for your code in lisp could be something like this:

CL-USER> (dotimes (xx 20 xx) (print "yay"))
"yay"
"yay"
"yay"
"yay"
"yay"
"yay"
"yay"
"yay"
"yay"
"yay"
"yay"
"yay"
"yay"
"yay"
"yay"
"yay"
"yay"
"yay"
"yay"
"yay"
20

you need to learn how to define variables, setq vs defparameter, special variables ... loops, a lot of thing I begin learning lisp few years ago, an I think that is an amazing trip

anquegi
  • 11,125
  • 4
  • 51
  • 67
1

If the question title and/or the unbound compiler complaint is/are why you ended up here, it's likely that the answer you are interested in is buried near the bottom of anquegi's answer: consider (for starters) using defvar or defparameter or let. The former two are typically used as top-level forms. In contrast, let is used to establish "temporary" named variables within a limited scope.

 ;; define *xx* so that it can be "seen" globally
 (defparameter *xx* 23)
 ;; establish a variable which is only "seen" locally
 (let ((xx 0))
   (format t "xx: ~S~%" xx)
   (incf xx)
   (format t "xx: ~S~%" xx))

You may also find Difference between `set`, `setq`, and `setf` in Common Lisp? helpful.

Community
  • 1
  • 1
dat
  • 1,580
  • 1
  • 21
  • 30