On Slime Load , change default package from Cl-USER - common-lisp

When we start slime, it starts in CL-USER by default. Since I work with a particular package very frequently, I want to automatically in-package into that package on slime startup.
i.e. I want save myself the trouble of doing the below:
CL-USER> (ql:quickload :my-package)
CL-USER> (in-package my-package)
MY-PACKAGE>
I tried putting the following code in my ccl-init.lisp file but the in-package did not work:
(ql:quickload :my-package)
(in-package my-package)

You probably could do something with slime-repl-mode-hook
But I think it would be better to use the slime-sync-package-and-default-directory which is bound to C-c ~ and syncs your REPL to the package of your buffer.

Related

How to permanently save a macro in LISP (sbcl)

Lets say i define a macro
(defmacro foo(x)
(print x))
Now i want to be able to always load this macro in all my lisp files in future where should i save this macro?
Every CL implementation has an init file it calls on start. For SBCL that is ~/.sbclrc. Usually also quicklisp has some setup code in there if you installed quicklisp.
So you could add a line:
(load #P"path/to/your/macro/file.lisp")
And it'll get loaded each time you start SBCL.
You want to have a library.
A library can contain any number of definitions, not only macros.
The de facto standard way to define systems (which is a more general term for libraries, frameworks, and applications — units of software) is to use ASDF.
Let's say that you put your macro into a lisp file:
;;;; my-util.lisp
(in-package cl-user)
(defpackage my-util
(:use cl))
(in-package my-util)
(defmacro foo (x)
`(whatever ,x etc))
Then you put that under a directory that is known to ASDF. One useful directory for that is ~/common-lisp/, so let's use ~/common-lisp/my-util/. In the same directory, put the system definition file:
;;;; my-util.asd
(in-package asdf-user)
(defsystem "my-util"
:components ((:file "my-util")))
Now you can load this utility into any lisp interaction, e. g. on the repl:
CL-USER> (asdf:load-system "my-util")
Or in a different system:
;;;; my-application.asd
(in-package asdf-user)
(defsystem "my-application"
:depends-on ("my-util")
...)
In the case of utility libraries, you often want to use their package so that you don't need to package-qualify the symbols.
If you want things that only work on your computer (like shortcuts for your REPL use or one-off scripts), you can sometimes get away with adding things to your implementation's init file.

Referring to global symbols

I want to create a source file in which most of the functions there defined, are local to that source file. It's the same purpose that would be served in C by marking the functions static; in C++ one could also surround them with namespace { ... }. I get the impression in Lisp, the package system is the appropriate tool. However, my attempts so far are not working.
This is what I currently have, but SBCL rejects it with the claim that global-fun is undefined. Explicitly referring to it as cl-user:global-fun, produces similar results. What should I be doing?
(defun global-fun ()
(format t "global~%"))
(defpackage :local-package
(:use :common-lisp)
(:use :cl-user))
(in-package :local-package)
(defun local-fun ()
(global-fun)
(format t "local~%"))
You're nearly there. You might use Slime's autocompletion to find out.
Either export global-fun, or access it with a double colon: (cl-user::global-fun).
With another global-package:
(defpackage :global-package
(:use :common-lisp) ;; <-- can be :cl
;; (:use :cl-user) <-- not necessary
(:export :global-fun))
(in-package :global-package)
(defun global-fun () …)
(defpackage :local-package
(:use :cl
:global-defun)) ;; <-- one ":use" is possible
(in-package :local-package)
; etc
There seem to be some misconceptions here.
There is no such thing as a “global function” in Common Lisp. The thing you defined first in your file, global-fun is in some package, most likely the cl-user package.
There is also no direct correspondence between packages and files. You can define things for different packages in a single file, and you can define things for a single package in multiple files. To make things unambiguous and easy to read, there is a very sensible convention to always start a source file with an in-package form (in some styles preceded by a defpackage form), and to never put another in-package somewhere later in the file.
When you write a symbol without package, e. g. somefun or myarray, it is interned (i. e. a sort of idempotent registration) into the current package (see below what that is). This is independent from whether you currently define something or refer to it, because it is done by the reader when reading your source code forms. In both of the following forms, the symbol named foo is interned into the current package (and both result in the identical symbol to be used):
(defun foo ()
…)
(foo)
In order to refer to a symbol from a different package, you need to put the package name as a prefix with :: as separator, as in my-package::foo, but this is usually a code smell because…
… you should export any symbols that a user of your package is intended to use, from your package definition:
(defpackage my-package
(:use common-lisp)
(:export foo))
You can refer to exported symbols from another package with a single colon as separator, as in my-package:foo, and this is good style.
Now, the current package is just the value of the variable *package*. If you look at it from the point of view of a REPL session, this is the argument of the most recent in-package call. In the context of whole file compilation, it is the value of the lexically closest preceding in-package form. In the context of single-form compilation in a file, the IDE will (in any case I have seen) look for that preceding in-package form even if it is not evaluated explicitly. In a pristine Lisp image, the starting package is common-lisp-user, which has a nickname cl-user.

Common lisp about naming packages and using them

I try to use Common Lisp packages, but I have several (probably naming conventions) problems, first is the use of "#:" it seems not necessary but is like sharp-quote in functions that is better to use depending on your context.
(defpackage #:match-test
(:use #:match
#:fiveam
#:cl)
(:export #:run!
#:test-match)
(:documentation "Test package for testing match project 1 of CS202"))
Then is in how to use that package
(in-package #:match-test)
(in-package :match-test)
(in-package match-test)
it works, but when I want to delete that package it only works with:
CL-USER> (delete-package (in-package #:match-test))
#<BOOLEAN <<error printing object>> {2010004F}>
it gives that error, but it makes the job done. It seems working with the package as an object, I also do not understand the hyperspec, is a problem that I need to learn CLOS, that is true I'm a beginner learning Lisp, but I suppose that I can get a easy clarifying for my doubts.
I hope that I said it quite clearly.
Finally I want to say that I used emacs + sly + roswell and
CL-USER> (lisp-implementation-type)
"SBCL"
CL-USER> (lisp-implementation-version)
"1.4.6"
DEFPACKAGE and IN-PACKAGE are defined as macros. They take a literal name - a string designator: foobar, |FOOBAR|, #:FOOBAR, :FOOBAR or "FOOBAR".
DELETE-PACKAGE is a function and expects a string designator, too. But since it is a function, the argument is evaluated. This means: if you want to pass the name, you have to quote it - if it is a symbol not in the keyword package. Strings and keyword symbols are self-evaluating and don't need to be quoted. Valid arguments to DELETE-PACKAGE are for example:
'foobar
'|FOOBAR|
'#:FOOBAR
:FOOBAR or ':FOOBAR
"FOOBAR" or '"FOOBAR"
Since DELETE-PACKAGE is a function, the argument gets evaluated -> you can also evaluate variables, function calls, ... as argument.
The Error: Deleting the current package
LispWorks:
CL-USER 43 > (delete-package (in-package #:match-test))
Error: Cannot delete the current package, #<The MATCH-TEST package, 0/16 internal, 2/16 external>.
1 (abort) Return to top loop level 0.
SBCL:
* (delete-package (in-package #:match-test))
debugger invoked on a SIMPLE-TYPE-ERROR in thread
#<THREAD "main thread" RUNNING {10005605B3}>:
*PACKAGE* can't be a deleted package:
It has been reset to #<PACKAGE "COMMON-LISP-USER">.
Your code tries to delete the current package - you just used IN-PACKAGE to make it the current package - deleting the current package is usually not a good idea. You are shooting yourself in the foot. A Lisp might prevent that (like my example in LispWorks) or allow it - but then you have to live with the consequence.

lexical binding lost when switching package

All I wanted was to load an initialisation file for swank which wouldn't affect my lisp when it's started without swank...
I first tried #+swank (defun...) in my file that's loaded from ccl-init (trying this on ccl 1.10 + windows), and soon realised it's sourced before swank is loaded (obviously).
My aim is to define a simple function in :cl-user everytime I start swank. I just ended up with a swank add-hook to load my init.lisp file, and since I want to define the function in cl-user, I tried this in the init.lisp:
(let ((current-package *package*))
(in-package :cl-user)
(defun cd (dir)
(swank:set-default-directory
(parse-namestring dir)))
(in-package current-package))
Now, I don't recall if a defun in let was allowed, but lisp doesn't complain for it, but rather tells me that cur-pck symbol doesn't exist, and it seems when we switch the package, cur-pck binding gets out of scope. I thought cur-pck is a lexical binding, and that it should be reachable from within the lexical region, being independent from a package, am I wrong?
Why do I switch packages? I'm thinking that loading this file from swank at some initialisation point will define things in some swank package, that's why I wanted to try switching to cl-user first, define the function symbol, and switch back to let swank do it's thing.
At this point I guess I need someone to tell me I'm approaching the problem from the wrong angle, and that I should better choose an easier solution.
Additionally, out of curiosity in case above is the complete wrong approach, is there a way to define a symbol in another package within a function or a closure?
Switching packages in a form has no direct effect on the form
Let's look at this:
(in-package "FOO")
(let ((x 10))
(in-package "BAR")
(setf x 20))
Which x does it set to 20? FOO::X or BAR::X?
Well, it is FOO::X. Switching packages during execution has no effect on the symbols already read. The whole let form is read at once and the *package* value is used for that. Having an IN-PACKAGE in the form itself has no effect on the form itself.
Symbol with a package prefix
If you want to use a symbol in a certain package, just write the package prefix:
cl-user:foo ; if FOO is exported and the package exists
or
cl-user::foo ; if foo is not exported and the package exists
for example:
(defun cl-user::cd (...) ...)
Computing with symbols
You can also compute new symbols in packages you don't know yet:
(let ((sym-name "A-NEW-SYMBOL")
(my-package-name "SOME-EXISTING-PACKAGE"))
(intern sym-name my-package-name))
If the package does not exist, you can create it.
You can also set the function of a computed symbol:
(setf (symbol-function (compute-a-function-symbol))
#'(lambda ()
'foo))
If you want to define a function in a different package that the current one you can use a qualified symbol for a name
(defun cl-user::cd (dir)
(swank:set-default-directory
(parse-namestring dir)))
The binding is not being "lost". To test so yourself add (princ cur-pck) before the in-package form.
If you try evaluating (in-package *package*) you will see why your code fails to switch packages. The in-package macro does not evaluate its argument. The code that would give us the code we would want to evaluate is:
(let ((cur-pck *package*))
(in-package :cl-user)
(defun cd (dir)
(swank:set-default-directory
(1+ 2)))
(princ cur-pck)
`(in-package ,cur-pck))
However, as Rainer Joswig noted in his answer the in-package has no effect on forms already read, so it wouldn't work as desired even as a macro.
A style nitpick, don't use abbreviations, write current-package.
IN-PACKAGE is a macro, not a function. The problem in your code is that saying (in-package cur-pck) tries not to switch into the package denoted by the cur-pck variable but to the package named CUR-PCK (which obviously does not exist).
You can set the package temporarily with
(let ((*package* (find-package :cl-user)))
(defun cd (dir)
...))
But then again, the easiest way to achieve what you are doing would be
(defun cl-user::cd (dir)
...)
which totally eliminates the need to set the current package.

Quickload inside eval-when

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.

Resources