lispcommon-lispsbcl

"undefined variable: COMMON-LISP-USER::PRIMELIST" warning, using SBCL


Though I have been using Common Lisp on Linux for a while, my experience with SBCL is extremely limited.

And my experience with SBCL on Mac is equal to nothing.

I just installed SBCL on Mac (Sonoma 14.2.1) using homebrew.

I now have : SBCL 2.4.1

I am hitting a first problem when trying to use a separate file to include functions.

As a first test I have this file (test1):

   % cat test1
  #!/opt/homebrew/bin/sbcl --script

  (format t "Hello Lisp World !~%")
   % 

which works as expected:

   % ./test1
  Hello Lisp World !
   % 

Next I want to include functions from a separate file:

   % cat test2 
  #!/opt/homebrew/bin/sbcl --script

  (load "testInc")

  (format t "Hello Lisp World !~%")
  (outFunc)
   % 

And testInc is as follow:

   % cat testInc 
  (defun outFunc()
    (format t "Hello Lisp Library !~%")
    (format t " From testInc.~%"))
   % 

At this point things still work as expected:

   % ./test2    
  Hello Lisp World !
  Hello Lisp Library !
    From testInc.
   % 

Things go wrong with my third test. I now change the testInc file to:

   % cat testInc
  (setq PrimeList '((2 1) (3 2)))

  (defun outFunc()
    (format t "Hello Lisp Library !~%")
    (format t " From testInc.~%")
    (format t "P1: ~a.~%" (car (car PrimeList)))
  ) ; End of outFunc.
   % 

When I now try to run test2 I hit problems. Like this:

   % ./test2     

  ; file: /.../testInc
  ; in: SETQ PRIMELIST
  ;     (SETQ PRIMELIST '((2 1) (3 2)))
  ; 
  ; caught WARNING:
  ;   undefined variable: COMMON-LISP-USER::PRIMELIST
  ; 
  ; compilation unit finished
  ;   Undefined variable:
  ;     PRIMELIST
  ;   caught 1 WARNING condition

  ; file: /.../testInc
  ; in: DEFUN OUTFUNC
  ;     (CAR PRIMELIST)
  ; 
  ; caught WARNING:
  ;   undefined variable: COMMON-LISP-USER::PRIMELIST
  ; 
  ; compilation unit finished
  ;   Undefined variable:
  ;     PRIMELIST
  ;   caught 1 WARNING condition
  Hello Lisp World !
  Hello Lisp Library !
    From testInc.
  P1: 2.
    % 

One can see that the expected last line is showing up. And this code has no problem when used with common lisp (on Debian). Why am I getting the issue (WARNING):

  ;   undefined variable: COMMON-LISP-USER::PRIMELIST

How should I write the code to avoid this kind of warning ?

So I hope somebody with a knowledge of SBCL will be able to give me a hint on how to keep SBCL happy.


Solution

  • You are using a variable before declaring it. You can use defvar or defparameter to declare it.

    (defparameter PrimeList '((2 1) (3 2)))
    

    Keep in mind that these will not be lexical variables, they will be dynamicly bound.

    Most of the time it is better to keep passing additional variable.

    If you don't want a global variable always available, you can still do this:

    (let ((prime-list '((2 1) (3 2))))
      (defun some-func ()
        (format t "~A~%" prime-list)))
    

    While this (let (state-var ...) (defun ...) (defun ...) ... ) will be useful to share a state between several functions, without a visible state it can be a source for tricky bugs.

    There is defconstant for global constants, if you never want to set it again.