How to install MJRCALC-system in SBCL by Quicklisp - common-lisp

I've installed SBCL with Quicklisp in my Tumbleweed. Quicklisp has also ASDF inbuilt. After that I also intalled MJRCALC-system in Home/quicklisp/local-projects/mjrcalc-folder. Quicklisp (and ASDF) can recognize the system (in SBCL):
(ql:quickload "mjrcalc")
To load "mjrcalc":
Load 1 ASDF system:
mjrcalc
; Loading "mjrcalc"
("mjrcalc")
The problem is that I can't (or don't know how to) load packages from the mjrcalc-system. I also tried to get a list of the packages in the system without result. Any ideas?

1- look for documentation
2- grep for in-package and/or def.*package

Related

How to make Quicklisp available to a script that runs from a Shebang?

I've been playing around with Quicklisp lately, and have this minor problem working with scripts with Shebangs.
Setup
I did the following:
Downloaded quicklisp with curl https://beta.quicklisp.org/quicklisp.lisp -o /tmp/quicklisp.lisp
Installed it with (quicklisp-quickstart:install) while having /tmp/quicklisp loaded in the environment.
Added Quicklisp to init file using (ql:add-to-init-file)
Problem
For a script that needs Quicklisp (specifically ASDF), I can run it with sbcl --load ~/quicklisp/setup.lisp --script start.lisp just fine. However, when I run it as a standalone script with the Shebang /usr/bin/env sbcl --script, it fails with an error saying that it isn't able to find things like UIOP, etc. unless I place the below two lines in the script itself:
(load "~/quicklisp/setup.lisp")
(ql:quickload "asdf")
You can find my stupid experiment here, and the script in question here.
PS: Any pointers would be really helpful.
PPS: I'm sure it's a stupid mistake on my end, forgive me.
In that case you need:
(require :asdf)
TBH, I don't know exactly why. --script equals to --no-sysinit --no-userinit --disable-debugger --end-toplevel-options, so it's a lot we ignore. (thus loading quicklisp's setup.lisp seems required too, because it won't be loaded by your .sbclrc, which is where Quicklisp adds this little snippet)
It's a setting I have needed in other environments, such as a CI.
I would use roswell - which makes standalone scripts available which use Common Lisp code.
I described setting up roswell here. It is super easy.
I describe there system-wide installation of roswell or also how to locally install roswell in ubuntu, mac and windows.
Or you could also directly lookup on roswell's site.
Using roswell would have the advantage that you can use any roswell-installable Common Lisp implementations, which are:
Candidates impls for installation are:
abcl-bin
allegro
ccl-bin
clasp-bin
clasp
clisp
cmu-bin
ecl
mkcl
sbcl-bin
sbcl
sbcl-source
not only sbcl alone.
And roswell allows scripts which are call-able directly from the shell while written in Common Lisp.
From inside roswell $ ros ... commands , quicklisp is available. So $ ros install xxx uses usually quicklisp to install xxx.
Using roswell, you can make any Common Lisp program callable from the bash by a single command - including your script - written in common lisp.
Look at e.g. here:
https://roswell.github.io/Roswell-as-a-Scripting-Environment.html

How to update a dependency with quicklisp?

I have updated quicklisp to the lates version
CL-USER> (ql:update-all-dists)
1 dist to check.
You already have the latest version of "quicklisp": 2017-06-30.
NIL
But this did not update the dependencies to the latest version, ex. Hunchentoot webserver is version 1.2.35, but I need 1.2.37 because of a bugfix.
/home/pio/quicklisp/dists/quicklisp/software/hunchentoot-1.2.35/hunchentoot.asd
How can I update the Hunchentoot to the latest release (https://github.com/edicl/hunchentoot/releases/tag/v1.2.37) with quicklisp?
Ql:quickload will first ask ASDF for locally available systems, which happens in a defined order.
I usually put all Lisp libraries that I want to be found under ~/common-lisp/ which is a standard place ASDF looks into, so it just works.
If you have some other directories, you can make these directories known to ASDF. You can for example use the file ~/.config/common-lisp/source-registry.conf:
(:source-registry
(:tree (:home "repos"))
:inherit-configuration)
This will make ASDF aware of any .asd files under the ~/repos/ directory.
You can then use asdf:load-system or ql:quickload to load such systems (the latter will also resolve and download missing dependencies).
If quicklisp has already installed a system in a different version and ASDF happens to find that version first, you might need to ql:uninstall it beforehand.

How to get Emacs/Slime/SBCL to recognize quicklisp packages

I am trying to get Emacs, SLIME and quicklisp to work together properly. I have the following environment set up:
Installed Emacs
Installed SLIME in Emacs
Installed SBCL
Installed quicklisp
Run (quicklisp-quickstart:install) in SBCL
Run (ql:add-to-init-file) in SBCL
Run (ql:quickload "quicklisp-slime-helper") in SBCL
Installed package cl-csv using (ql:quickload "cl-csv") in SBCL
Added (setq inferior-lisp-program "sbcl") to .emacs
Added (load (expand-file-name "~/quicklisp/slime-helper.el")) to .emacs
Restarted everything
I have a test.lisp file that starts with (ql:quickload "cl-csv") to load the package and use it. When I load the file into Emacs and run SLIME, then try to compile it using slime-compile-and-load-file, I get the error in SBCL that Package CL-CSV does not exist.
What have I missed to get these pieces working together properly?
If you compile a file which contains a statement
(ql:quickload "cl-csv")
then this call will be compiled, but not executed. That's what a compiler usually does: it compiles, but does not execute. Thus if you use some Lisp package (a namespace) later in the same file - a package which would be introduced in the system cl-csv - then it might not be present, if you have not loaded it before, by loading the system.
There are two typical solutions to this:
put the loading command in a file which one compiles (optionally) and/or loads before
use EVAL-WHEN with :compile-toplevel, :load-toplevel and :execute
Note that cl-csv is a system, organizing source files. A package is a Lisp namespace for organizing Lisp symbols. A package and a system can have the same name, but they really are two different things.
Calling ql:quickload directly is good for tests and while interacting with your development environment. If you use some systems a lot, you may quickload them inside your initialization file (in your case, ~/.sbclrc).
However, your purpose when programming is generally to develop a new system (a library, or an application, but as far as Common Lisp is concerned, this is a "system"). You generally do not need to have explicit (ql:quickload ...) calls inside your source code. Instead, you define a system where you declare dependencies and your code assumes that the appropriate dependencies are loaded.
Create and enter directory "my-system"
Create and edit "my-system.asd"
(in-package :asdf-user)
(defsystem :my-system
:depends-on (:cl-csv))
Quicklisp can find your system if you link the directory inside ~/quicklisp/local-projects/.
So the next time you restart your Lisp and want to develop on my-system, you can perform (ql:quickload :my-system) which will load all the declared dependencies.
Reinstall quicklisp at the Emacs' SLIME REPL.
The problem is that Emacs Slime (REPL) doesn't know neither whether quicklisp is installed nor where it is installed. All you have to do to fix the problem is to reinstall quicklisp at the Emacs' slime repl. ("quicklisp.lisp" file should be in the SLIME REPL's current working folder.)
M-x slime
CL-USER> (load "quicklisp.lisp")
CL-USER> (quicklisp-quickstart:install)
CL-USER> (ql:add-to-init-file)
CL-USER> (ql:quickload "quicklisp-slime-helper")
e.g.) My "~/.emacs" file:
(use-package slime
:ensure t
:defer t
:init
(setq inferior-lisp-program "clisp")
:config
(slime-setup '(slime-fancy slime-company))
:hook
(slime-mode . slime-company)
(slime-mode . (lambda ()
(load (expand-file-name "D:/util/emacs27/quicklisp/slime-helper.el"))
(add-to-list 'slime-contribs 'slime-fancy)
(add-to-list 'slime-contribs 'inferior-slime))))
(use-package slime-company
:after slime
:bind-keymap
("C-n" . company-select-next)
("C-p" . company-select-previous)
("C-d" . company-show-doc-buffer)
("M-." . company-show-location)
:config (setq slime-company-completion 'fuzzy
slime-company-after-completion 'slime-company-just-one-space))
Then, quicklisp will be reinstalled in the Emacs's HOME directory ("~/"). Now, you have installed the same quicklisp in the (a) Windows 10's HOME and (a) the Emacs' HOME. If you use quicklisp only at the Emacs' Slime REPL, the copy in the Windows 10' HOME is useless, and you can delete it.

Test if quicklisp has already been installed in clisp

I'm working on a project in Common Lisp which makes use of a package installed with quickload. I'm making a bash script in the root of the project which tests if the necessary programs are installed, and if it all checks out, it runs a lisp script which loads my project. I want some way of testing if quicklisp is installed, so that I can have it can ask the user for permission to download and install quicklisp automatically. Is there a way to test for this? Quicklisp is installed within clisp, not as a package on the OS, so using the bash builtins for testing if a program's installed won't work.
From inside Lisp: Quicklisp puts :quicklisp onto the cl:*features* list.
If Quicklisp is already loaded into Lisp, then this symbol is on the *features* list.
To test that:
(member :quicklisp *features*)
In Lisp code you can also use the conditional reader:
#+quicklisp (print "quicklisp installed")
or
#-quicklisp (print "quicklisp not installed")

cffi installation

I'm trying to install cffi package into sbcl.
First, I tried clbuild that is recommended on the cffi installation page.
When I tried to run :
clbuild quickload cffi
I was given an error saying :
The function ASDF::SOURCE-REGISTRY is undefined.
I then tried asdf-install, it end up complaining about
Component "cffi-examples" not found
Any help on this would be appreciated.
UPDATE
For asdf-install, I'm running sbcl with slime. It seems that whenever it complains about a component that is missing, that component is actually installed. I just have to abort the debugger and restart Emacs, start slime, and do that install again, and it will finish successfully. If I don't run it with slime, just running it inside sbcl prompt in terminal, it will keep complaining about the component missing nonstop.
So to get cffi installed with asdf-install, I had to restart Emacs for about 4-5 times.
I'm not sure if there is configuration issue with sbcl?
I suppose I should ask this question in different thread.
It's pretty easy with Quicklisp. To install Quicklisp:
Download http://beta.quicklisp.org/quicklisp.lisp
sbcl --load quicklisp.lisp
(quicklisp-quickstart:install)
(ql:add-to-init-file)
Then you can install and load CFFI like so:
(ql:quickload "cffi")
I wrote a bit about how I manage small projects and their required libraries at Making a small Lisp project with quickproject and Quicklisp.
Here are the exact steps for manual installation under Windows 7:
First, download and install SBCL from:
http://www.sbcl.org/platform-table.html
Then download and untar (tar xzf ...) babel, alexandria, trivial-features, and cffi.
Then, start SBCL, load ASDF, and add the paths to these systems to asdf:*central-registry*:
C:\Program Files\Steel Bank Common Lisp\1.0.49>sbcl.exe --core sbcl.core
This is SBCL 1.0.49, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
This is experimental prerelease support for the Windows platform: use
at your own risk. "Your Kitten of Death awaits!"
* (load "asdf/asdf")
T
* (push "C:/Users/dhl/build/asdf/babel_0.3.0/" asdf:*central-registry*)
("C:/Users/dhl/build/asdf/babel_0.3.0/")
* (push "C:/Users/dhl/build/asdf/alexandria/" asdf:*central-registry*)
("C:/Users/dhl/build/asdf/alexandria/" "C:/Users/dhl/build/asdf/babel_0.3.0/")
* (push "C:/Users/dhl/build/asdf/trivial-features_0.6/" asdf:*central-registry*)
("C:/Users/dhl/build/asdf/trivial-features_0.6/"
"C:/Users/dhl/build/asdf/alexandria/" "C:/Users/dhl/build/asdf/babel_0.3.0/")
* (push "C:/Users/dhl/build/asdf/cffi_0.10.6/" asdf:*central-registry*)
("C:/Users/dhl/build/asdf/cffi_0.10.6/"
"C:/Users/dhl/build/asdf/trivial-features_0.6/"
"C:/Users/dhl/build/asdf/alexandria/" "C:/Users/dhl/build/asdf/babel_0.3.0/")
*
(Of course, you'd have to give your paths to the libraries instead of `"C:/Users/dhl/...")
Then, you can load CFFI:
* (asdf:load-system 'cffi)
[much compilation output]
T
*
Now, that's pretty much the bare bones way to install systems for Common Lisp. Nowadays, there is Quicklisp, which is easy to use and covered by Xach's answer. Also, note that there are better ways to register your systems with asdf, like symlinking the asd-files to a single directory on platforms that support symlinking, and ASDF 2 provides a source-registry facility, so you won't have to deal with asdf:*central-registry* at all (I still like it for REPL use).
All in all, I guess Xach's answer provides the easiest way to get a working installation of CFFI, so I recommend his answer and will vote it up, but I already started writing my article before he posted it, and maybe its of some use to you to know how to do things manually.

Resources