I'm running LispWorks 7.1 on OSX (macOS High Sierra). I sometimes encounter a Quicklisp loading bug (I say sometimes because when I restart LispWorks I sometimes don't see this error again).
Example:
CL-USER 1 > (ql:quickload "iterate")
To load "iterate":
Load 1 ASDF system:
asdf
Install 1 Quicklisp release:
iterate
Error: Error detected during deflate decompression: Corrupted Data detected during decompression: Incorrect huffman code (1E55) in huffman decode!
1 (abort) Give up on "iterate"
2 Return to top loop level 0.
Type :b for backtrace or :c <option number> to proceed.
Type :bug-form "<subject>" for a bug report template or :? for other options.
Any idea what's going on?
I've verified I have a recent client:
CL-USER 6 > (ql:update-client)
The most up-to-date client, version 2017-03-06, is already installed.
T
Also, the backtrace, in case it helps:
CL-USER 12 : 1 > :b
Call to ERROR
Call to QL-GUNZIPPER::DECODE-HUFFMAN-BLOCK
Call to QL-GUNZIPPER::DECODE-BLOCK
Call to QL-GUNZIPPER::INFLATE-STREAM
Call to QL-GUNZIPPER::INFLATE-GZIP-STREAM
Call to QL-GUNZIPPER:GUNZIP
Call to (METHOD QL-DIST:INSTALL (QL-DIST:RELEASE))
Call to (METHOD QL-DIST:ENSURE-INSTALLED (T))
Call to MAP
Call to QUICKLISP-CLIENT::APPLY-LOAD-STRATEGY
Call to QUICKLISP-CLIENT::AUTOLOAD-SYSTEM-AND-DEPENDENCIES
Call to (METHOD QUICKLISP-CLIENT:QUICKLOAD (T))
Call to CLOS::NEXT-METHOD-CALL-2
Call to QL-DIST::CALL-WITH-CONSISTENT-DISTS
Call to CLOS::GENERIC-FUNCTION-NON-DISCRIMINATOR
Call to LET
Call to EVAL
Call to CAPI::CAPI-TOP-LEVEL-FUNCTION
Call to CAPI::INTERACTIVE-PANE-TOP-LOOP
Call to MP::PROCESS-SG-FUNCTION
As Rainer Joswig pointed out, I just had to (duh!) apply the latest patches.
For future reference, this involves
Downloading the patches listed here
Copying them to the appropriate private-patches directory (e.g. /Applications/LispWorks\ 7.1\ \(64-bit\)/Library/lib/7-1-0-0/private-patches for me)
Modifying load.lisp in the directory accordingly (in this case, adding (load-one-private-patch "lisp-memory-copy-32-chunks" :system64) and
(load-one-private-patch "replace-i-vectors" :system))
Restarting Lispworks
Related
I have created a small project using Steel Bank Common Lisp and I am using ASDF to compile and load it. The load command is:
(asdf:load-system :<my-system>)
Everything works fine (the program gets compiled and runs fine) but I keep getting output like
; compiling file "[...].lisp" (written 13 APR 2014 06:20:03 PM):
; compiling (DEFPACKAGE :<my-package> ...)
; compiling (DEFUN <my-func-1> ...)
; compiling (DEFUN <my-func-2> ...)
; compiling (DEFUN <my-func-3> ...)
each time the program is recompiled.
I suppose this output comes from asdf because I am invoking the application with
sbcl --noinform --noprint --script runner_sbcl.lisp
where runner_sbcl.lisp loads the actual application via asdf:load-system. So I suppose
this output does not come from sbcl.
Is there any way to disable console output in asdf:load-system? I would like to be only notified about compilation errors / warnings.
I could not find any information in the documentation.
what about
(setf *load-verbose* nil)
(setf *load-print* nil)
(setf *compile-verbose* nil)
(setf *compile-print* nil)
?
Why are they set, anyway?
This is my workaround for a similar issue I had with quicklisp's ql:quickload.
(with-output-to-string (*standard-output*)
;; asdf:load-system or ql:quickload..
(asdf:load-system :<your-system>))
I am trying to get live-coding to work in lisp. i have the file t.cl which contains only this line: (loop(write(- 2 1))). Now, when i run the file in bash with sbcl --load t.cl --eval '(quit)', it runs the line, but when I try to edit the file in another terminal and save it while it runs, nothing changes ..
Why your example fails
When running sbcl --load t.cl --eval '(quit)' in a shell, what this does is spin-up a SBCL Lisp image in a process, compile the file and run it. You then modify the file and save it to your disk. This last action is of no concern to the already running SBCL process, which has already compiled the previous file. SBCL read the file once when you asked it to, once it has the compiled instructions to run, it has no reason to look at the file again unless you explicitly ask it to.
A 'live' example with Emacs+SLIME
In order to perform 'live' changes to your running program, you must interact with the already running Lisp image. This is easily doable with Emacs+Slime. You can, for example, have a loop like so:
(defun foo (x) (+ x 3))
(dotimes (it 20)
(format t "~A~%" (foo it))
(sleep 1))
and then recompile foo during execution within the REPL with a new definition:
(defun foo (x) (+ x 100))
Another thread will be used to recompile the function. The new function will be used for future calls as soon as its compilation is finished.
The output in the REPL will look like:
3
4
5
CL-USER> (defun foo (x) (+ x 100))
WARNING: redefining COMMON-LISP-USER::FOO in DEFUN
FOO
103
104
105
...
This would also work with the new definition of foo being compiled from another file as opposed to being entered directly in the REPL.
Working from the system shell
While you can already use the example above for development purposes, you might want to interact with a running SBCL Lisp image from the shell. I am not aware of how to do that. For your exact example, you want to get SBCL to reload eventual files that you have modified. A brief look at the SBCL manual doesn't seem to provide ways to pipe lisp code to an already running SBCL process.
I've set up quicklisp (with latest SBCL) and done
* (ql:quickload "draw-cons-tree")
and I get the reply
To load "draw-cons-tree":
Load 1 ASDF system:
draw-cons-tree
; Loading "draw-cons-tree"
("draw-cons-tree")
I check my quicklisp directory and I see it's been downloaded, essentially exactly these contents. So how do I actually use draw-cons-tree in the SBCL REPL that I have opened? The github sites says:
* (draw-tree '(a b (c nil 1)))
should produce
[o|o]---[o|o]---[o|/]
| | |
A B [o|o]---[o|o]---[o|/]
| | |
C NIL 1
NIL
but I'm just getting
debugger invoked on a UNDEFINED-FUNCTION in thread
#<THREAD "main thread" RUNNING {10005385B3}>:
The function COMMON-LISP-USER::DRAW-TREE is undefined.
What am I missing here? My only other real experience with quicklisp has been slime, which had a specific .el file to call in Emacs to get slime going. Do I need to drill down into the directory
~/quicklisp/dists/quicklisp/software/draw-cons-tree-20131003-git/draw-cons-tree.lisp
and load the beast each time I want to use it? I tried that and, strangely for me at least, I get a list of WARNINGs of redefined functions, one is draw-tree. So my REPL knows about draw-tree but doesn't? What am I missing here?
Quicklisp loads a system, which may add zero, one or more packages to your environment. Sometimes the names of those packages are easy to guess, like when you install system cl-ppcre, you have a package named "CL-PPCRE" from which you can run things. Sometimes you must read the documentation to know how to use a system you installed.
But in case you are looking for a specific function, then you can use apropos:
CL-USER> (apropos "draw-tree")
DRAW-CONS-TREE::%DRAW-TREE
DRAW-CONS-TREE:DRAW-TREE (fbound)
:DRAW-TREE (bound)
Here, there is one exported symbol, either call it with its name fully qualified:
(DRAW-CONS-TREE:DRAW-TREE ...)
Or use the package first, so that the symbol is accessible from the current package:
> (use-package "DRAW-CONS-TREE")
> (draw-tree ...)
Alternatively, define a new package that uses the package, or go in that package with in-package to have access to its symbols, etc.
See Programming in the Large: Packages and Symbols.
Here's a strange situation. I have this code:
(eval-when (:compile-toplevel :load-toplevel :execute)
(ql:quickload "cffi-grovel")
(setf cffi-grovel::*cc* "mpicc")) ; <--- this is the line it complains about.
Which I belive has to load cffi-grovel package before setting cffi-grovel::*cc* variable. When this form is executed from SLIME it works, but it doesn't work when loaded directly by SBCL, here's the output:
$ sbcl --noinfo
* (ql:quickload "cl-mpi")
debugger invoked on a LOAD-SYSTEM-DEFINITION-ERROR in thread
#<THREAD "main thread" RUNNING {10029C0E43}>:
Error while trying to load definition for system cl-mpi from pathname
/home/wvxvw/quicklisp/local-projects/cl-mpi/cl-mpi.asd:
READ error during COMPILE-FILE:
Package CFFI-GROVEL does not exist.
Line: 6, Column: 25, File-Position: 264
< restarts ... >
* (ql:quickload "cffi-grovel")
To load "cffi-grovel":
Load 1 ASDF system:
cffi-grovel
; Loading "cffi-grovel"
..
("cffi-grovel")
* (ql:quickload "cl-mpi")
To load "cffi-grovel":
Load 1 ASDF system:
cffi-grovel
; Loading "cffi-grovel"
To load "cl-mpi":
Load 1 ASDF system:
cl-mpi
; Loading "cl-mpi"
; mpicc -m64 ...
; ...
.
("cl-mpi")
Why does it fail the first time?
PS. I also tried #.cffi-grovel::*cc* instead - same result.
It fails because Lisp reads every form before executing it. And when it reads it, package cffi-grovel indeed does not exist yet, because cffi-grovel is loaded at execution time (whatever it means for form wrapped with eval-when).
Try spliting the eval-when form into two eval-whens: ql:quickload and setf. Or write something like this:
(setf (symbol-value (find-symbol "*CC*" "CFFI-GROVEL"))
"mpicc")
monoid gives a good answer. Here is a slightly shorter form.
Find the symbol at runtime, when the package actually exists. Note the use of SET, not SETF here:
(set (find-symbol "*CC*" "CFFI-GROVEL") "mpicc")
To make it more robust, one would need to check that FIND-SYMBOL actually finds the symbol.
The following function also gives you meaningful error messages and restarts:
(defun set-runtime-symbol (name package value)
(assert (find-package package) (package))
(assert (find-symbol name package) (name))
(set (find-symbol name package) value))
Alternatively use two EVAL-WHEN statements, instead of one.
OK, finally figured it I can do it like so:
(setf #.(intern "cffi-grovel::*cc*") "mpicc")
But I'm not sure how much this is fail-safe.
Doing a SWIG tutorial, and using the example.c, example.i as they provided there. I generated lisp file with swig -cffi example.i.
But when I run test.lisp with SBCL, i get a complaint about undefined alien function, as well as complaints when compiling the example.lisp itself. I'm pretty sure I still have to compile my example.c into a library and then somehow tell SBCL to load it! But the docs are very scant on this, except for this.
Can somebody tell me how to do this or is there a better way than SWIG to automatically generate CFFI bindings from C/C++ sources??
sbcl output:
...
;
; caught STYLE-WARNING:
; Undefined alien: "fact"
;
; compilation unit finished
; caught 1 STYLE-WARNING condition
;
; caught STYLE-WARNING:
; Undefined alien: "my_mod"
...
test.lisp
;call C functions defined in example.c
(require :cffi)
;;;(require :example "example.lisp")
(load "example.lisp")
(fact 2)
(quit)
First, you need to compile the C library. Do something like:
gcc -shared example.c -o libexample.so
Of course, for a complex existing library compilation could be considerably more complex -- if you're wrapping an existing library, it probably comes with some sort of Makefile to help you build it.
Then, in Lisp, use CFFI to define and load the library. This seems to be the main part that you're missing.
(cffi:define-foreign-library libexample
(t (:default "libexample"))) ;; note no .so suffix here
(cffi:use-foreign-library libexample)
This part:
(t (:default "libexample"))
is a conditional which you can use to give different loading instructions for different platforms. (t ...) is the catchall option, much like with COND. You can find the exact syntax in the documentation for define-foreign-library.
You would now normally use cffi:defcfun and so on to define the functions in the library. This is what the SWIG-generated file does for you, so load it:
(load "example.lisp")
You can now call the functions as normal Lisp functions:
(fact 5)
=> 120