skip to Main Content

Though I have been using Common Lisp on Linux for a while,
my experience with SBCL on Mac is still close to nothing.

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

I now have : SBCL 2.4.1

I am hitting one problem whith the following test.

Here is the test program:

me % cat test.lisp
#!/opt/homebrew/bin/sbcl --script

(with-input-from-string (strm (car *args*)) (setf ArgOne (read strm)))
(with-input-from-string (strm (cadr *args*)) (setf ArgTwo (read strm)))

(format "Argument One = ~a~%" ArgOne)
(format "Argument Two = ~a~%" ArgTwo)
me % 

When this same program (except for the first line) was run under clisp on debian like:

me % ./test.lisp 11 23

it would produce:

Argument One = 11
Argument Two = 23

as I expected.

But when run under sbcl on mac like:

me % ./test.lisp 11 23

It produces this unexpected output:

; file: /...././test.lisp
; in: WITH-INPUT-FROM-STRING (STRM (CAR *ARGS*))
;     (CAR *ARGS*)
; 
; caught WARNING:
;   undefined variable: COMMON-LISP-USER::*ARGS*

;     (SETF ARGONE (READ STRM))
; 
; caught WARNING:
;   undefined variable: COMMON-LISP-USER::ARGONE
; 
; compilation unit finished
;   Undefined variables:
;     *ARGS* ARGONE
;   caught 2 WARNING conditions
Unhandled UNBOUND-VARIABLE in thread #<SB-THREAD:THREAD "main thread" RUNNING
                                        {7005550003}>:
  The variable *ARGS* is unbound.

Backtrace for: #<SB-THREAD:THREAD "main thread" RUNNING {7005550003}>
0: ((LAMBDA NIL :IN "/..../test.lisp"))
1: (SB-INT:SIMPLE-EVAL-IN-LEXENV (WITH-INPUT-FROM-STRING (STRM (CAR *ARGS*)) (SETF ARGONE (READ STRM)))     #<NULL-LEXENV>)
2: (EVAL-TLF (WITH-INPUT-FROM-STRING (STRM (CAR *ARGS*)) (SETF ARGONE (READ STRM))) 0 NIL)
3: ((LABELS SB-FASL::EVAL-FORM :IN SB-INT:LOAD-AS-SOURCE) (WITH-INPUT-FROM-STRING (STRM (CAR *ARGS*))     (SETF ARGONE (READ STRM))) 0)
4: ((LAMBDA (SB-KERNEL:FORM &KEY :CURRENT-INDEX &ALLOW-OTHER-KEYS) :IN SB-INT:LOAD-AS-SOURCE)     (WITH-INPUT-FROM-STRING (STRM (CAR *ARGS*)) (SETF ARGONE (READ STRM))) :CURRENT-INDEX 0)
5: (SB-C::%DO-FORMS-FROM-INFO #<FUNCTION (LAMBDA (SB-KERNEL:FORM &KEY :CURRENT-INDEX &ALLOW-OTHER-KEYS)     :IN SB-INT:LOAD-AS-SOURCE) {1005F0E1B}> #<SB-C::SOURCE-INFO {70055166F3}> SB-C::INPUT-ERROR-IN-LOAD)
6: (SB-INT:LOAD-AS-SOURCE #<SB-SYS:FD-STREAM for "file /...././test.lisp" {7005510D73}> :VERBOSE NIL    :PRINT NIL :CONTEXT "loading")
7: ((LABELS SB-FASL::LOAD-STREAM-1 :IN LOAD) #<SB-SYS:FD-STREAM for "file /...././test.lisp" {7005510D73}   > NIL)
8: (SB-FASL::CALL-WITH-LOAD-BINDINGS #<FUNCTION (LABELS SB-FASL::LOAD-STREAM-1 :IN LOAD) {1005F09EB}>     #<SB-SYS:FD-STREAM for "file /...././test.lisp" {7005510D73}> NIL #<SB-SYS:FD-STREAM for "file /...././   test.lisp" {7005510D73}>)
9: (LOAD #<SB-SYS:FD-STREAM for "file /...././test.lisp" {7005510D73}> :VERBOSE NIL :PRINT NIL    :IF-DOES-NOT-EXIST :ERROR :EXTERNAL-FORMAT :DEFAULT)
10: ((FLET SB-IMPL::LOAD-SCRIPT :IN SB-IMPL::PROCESS-SCRIPT) #<SB-SYS:FD-STREAM for "file /...././test.   lisp" {7005510D73}>)
11: ((FLET SB-UNIX::BODY :IN SB-IMPL::PROCESS-SCRIPT))
12: ((FLET "WITHOUT-INTERRUPTS-BODY-11" :IN SB-IMPL::PROCESS-SCRIPT))
13: (SB-IMPL::PROCESS-SCRIPT "./test.lisp")
14: (SB-IMPL::TOPLEVEL-INIT)
15: ((FLET SB-UNIX::BODY :IN SB-IMPL::START-LISP))
16: ((FLET "WITHOUT-INTERRUPTS-BODY-3" :IN SB-IMPL::START-LISP))
17: (SB-IMPL::%START-LISP)

unhandled condition in --disable-debugger mode, quitting
me % 

There are obviously issues related to how I should use SBCL that I am not aware of.

Any lisp expert or better somone with SBCL knowledge will be very much appreciated to tell me how things ought to be done.

2

Answers


  1. sbcl‘s argv is in *posix-argv*
    and first argument is sbcl.

    modify your clisp program to sbcl runnable program is

    #!/opt/homebrew/bin/sbcl --script
    
    (defparameter ArgOne (read-from-string  (cadr *posix-argv*)))
    (defparameter ArgTwo (read-from-string  (caddr *posix-argv*)))
    
    (format t "Argument One = ~a~%" ArgOne)
    (format t "Argument Two = ~a~%" ArgTwo)
    
    Login or Signup to reply.
  2. To get them portably, the same way on different implementations, use (uiop:command-line-arguments).

    You might need (require :uiop), but ASDF (and thus UIOP) is shipped in most (not to say all) implementations.

    To properly parse CLI args, use libraries such as Clingon.

    See: https://lispcookbook.github.io/cl-cookbook/scripting.html

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search