Following this clisp basic website tutorial it asks me to define a package to persist the code:
(defpackage :retro-games
(:use :cl :cl-who :hunchentoot :parenscript))
However, I cannot work out where my code is being persisted. Where are the files?
NB: I have only one day's experience with lisp!
Where are the files? They are where you want them.
Create a new file anywhere you want.
Put the definitions into the file.
Done
Lisp can LOAD files and you can use COMPILE-FILE.
In Common Lisp there no connections between files, the location of a file and a package. The package definition just defines a namespace to symbols. But this is not necessarily connected to a file. Some tools help maintain something called a system, which is a collection of files, which can be compiled and loaded together.
To get a basic understanding how to use Common Lisp I recommend reading Practical Common Lisp by Peter Seibel.
Related
I am interested in creating an emacs extension that delegates the work to an external program.
I have my logic as a library, however, written in Common Lisp. If I can directly call the CL library from Elisp, that would be simpler for me; otherwise, I can use a client/server architecture.
I have looked into emacs LSP implementation, but I couldn't find a simple entry on how to do it.
You could build a binary of your CL app and call it from the Elisp side. It seems to suit you fine, so here are more pointers:
How to build a Common Lisp executable
short answer: see https://lispcookbook.github.io/cl-cookbook/scripting.html
Building a binary is done by calling sb-ext:save-lisp-and-die from the terminal (and not from a running image). Note that this function name changes on the different implementations.
ASDF has a directive that allows to do it declaratively, and portably (for all implementations). You add 3 lines in your .asd file and you mention what is your program's entry point. For example:
;; myprogram.asd
:build-operation "program-op" ;; leave this as is.
:build-pathname "myprogram"
:entry-point "myprogram::main" ;; up to you to write main.
Now, call (asdf:make :myprogram).
See a more complete example in the Cookboo.
Call it from Elisp
See https://wikemacs.org/wiki/Emacs_Lisp_Cookbook#Processes
This returns the output as a string:
(shell-command-to-string "seq 8 12 | sort")
Full documentation: https://www.gnu.org/software/emacs/manual/html_node/elisp/Synchronous-Processes.html
Other approaches
Other approaches are discussed here: https://www.reddit.com/r/lisp/comments/kce20l/what_is_the_best_way_to_call_common_lisp_inside/
For example, one could start a lisp process with Slime and execute CL code with slime-eval.
I am currently trying to wrap my head around packages, systems & co.
I now have read Packages, systems, modules, libraries - WTF? a few times, and I think I'm still having difficulties to get it right.
If I simply want to split a Lisp source file into two files, where one shall "use" the other - how do I do that? Do I need to build a system for this? Should I use a module? …? I'm coming from a Node.js background, and there you can simply say
var foo = require('./foo');
to get a reference to what's exported in file foo.js. What is the closest equivalent to this in Lisp?
I understand that ASDF is for systems, and that it is bundled as part of Quicklisp, at least according to its documentation:
ASDF comes bundled with all recent releases of active Common Lisp implementations as well as with quicklisp […]
Okay, Quicklisp is for libraries, but what is their relationship? Is Quicklisp something such as a "package manager" in other languages? And if so, then what exactly does ASDF provide?
Sorry for these many questions, but I think it just shows the trouble I have to understand how to structure Lisp applications. Any help would be greatly appreciated :-)
System
For structuring large system use a system management tool. A 'free' one is ASDF.
You would need a system declaration, which lists the parts of you library or application. Typically it goes into an own file. Then you load a system or compile a system. There should be tutorials how to do that.
A simple Lisp system might have the following files:
a system file describing the system, its parts and whatever other stuff is needed (other systems)
a package file which describes the namespaces used
a basic tools file (for examples functions used by the macro)
a macro file which lists the macros (used so that they get compiled/loaded before the rest of the software)
one or more other files with functionality.
Quicklisp is independent of that. It's a software distribution tool.
Quick hack to compile and load files
But you can also compile and load files the old fashioned way without a system tool:
(defparameter *files*
'("/yourdir/foo.lisp" "/yourdir/bar.lisp"))
(defun compile-foobar ()
(mapc #'compile-file *files*))
(defun load-foobar ()
(mapc #'load *files*))
(defun compile-and-load ()
(mapc (lambda (file)
(load (compile-file file)))
*files*))
In reality there might be more to it, but often it's enough. It should be easy to write your own building tool. A typical system tool will provide many more features for building more complex software in a structured way. Many of the ideas for these tools reach back at least 35 years. See for example the Lisp Machine manual, here the edition from 1984, chapter Maintaining Large Systems.
The role of files
Note that in plain Common Lisp the role of files and its semantics are not very complex.
A file is not a namespace, it is not associated with a class/subclass or an object, it is not a module. You mix Lisp constructs in a file like you want. Files can be arbitrary large (for example one complex library has a version where it is delivered as single source file with 30000 lines). The only real place in the standard semantics where a file plays a role is when compiling a file. What side effects has compiling a file? What optimizations can a compiler do?
Other than that it is assumed that the development environment provides services like load and compiling groups of files aka systems, provide overviews of compilation errors, record source locations of definitions, can locate definitions and more. A tool like ASDF handles the system part.
There is a require function in Common Lisp, but it deprecated. If you simply want to split your code in one or more pieces, to use it interactively in the REPL, you can put the code in different files and then load each of them. If instead you want to write a full lisp project, I have found very useful the quickproject package, that provides a simple starting point for the creation of new packages.
I wrote two functions in two separated files, assumed to be file A.lisp and B.lisp, where both files have some main program code for test and A.lisp would call the function in B.lisp. This means using the load method directly in A.lisp would execute the main code in B.lisp, which is not supposed to happen. And these files are, in my opinion, too small to be considered using something like package.
Is there anything like Python's if __name__ == "__main__": stuff in Common Lisp? Top-level code that's wrapped inside this condition will only be executed if the current file is the main module, i.e. the running program, but not if it's imported as a library.
Packages are only namespaces for symbols. They don't say anything about loading or compiling code.
Common Lisp does not have the idea of a library, module or even something like a 'main' module/routine in its ANSI Common Lisp standard. The standard defines two routines PROVIDEand REQUIRE. But those are not very well specified.
Most applications and libraries use a 'system' tool to structure, specify, compile and load code.
There is a 'free' one called ASDF. 'Another System Definition Facility'. For most types of applications a tool like ASDF is useful. For primitive applications you can write your own tools using standard functions like COMPILE-FILEand LOAD.
Nick Levine wrote a tutorial for ASDF (part of his abandoned Lisp book project): Systems.
Several Lisp implementations have more extensive facilities to create applications (for example Mac OS X applications written with Clozure Common Lisp).
The if __name__ == "__main__": idiom is very specific to Python, and even some people in the Python community consider using it for test code bad style.
With Common Lisp's high emphasis on interactive development in the REPL, it would actually be a disadvantage to have to reload the whole file each time you want to run the tests. Just put the tests into a function definition instead of the top level, it works and is more convenient.
Top level forms are evaluated.
You could define a main function as in the following example, and you could call that function whatever you like:
a.lisp:
(defun main ()
...)
b.lisp:
(load "a.lisp")
(main)
I don't really know how it works in Python but it looks like a file is
a module, and two files are two distinct modules. This not the case in
Common Lisp. If you don't define any package, when you load a file,
all definitions will be available in the current package (CL-USER is
the default). It's more like if you've pasted your code into the REPL.
But packages aren't really hard to use.
in A.lisp:
(defpackage foo
(:use #:cl)
(:export main))
(in-package :foo)
(defun main ()
(do-some-stuff)
(baz:main some-args))
in B.lisp:
(defpackage baz
(:use #:cl)
(:export main))
(in-package :baz)
(defun main (some-args)
(do-some-stuff))
You could read
The Complete Idiot's Guide to Common Lisp Packages
and
PCL chapter on packages.
The example below is given in Paul Grahams ANSI Common Lisp as an example of doing encapsulation:
(defpackage "CTR"
(:use "COMMON-LISP")
(:export "COUNTER" "INCREMENT" "CLEAR"))
(in-package ctr)
;function definitions here
However in Peter Seibels Practical Common Lisp, link here, he says:
Because packages are used by the reader, a package must be defined
before you can LOAD or COMPILE-FILE a file that contains an IN-PACKAGE
expression switching to that package. Packages also must be defined
before other DEFPACKAGE forms can refer to them...
The best first step toward making sure packages exist when they need
to is to put all your DEFPACKAGEs in files separate from the code that
needs to be read in those packages
So he recommends creating two files for every package, one for the defpackage and one for the code. The files containing defpackages should start with (in-package "COMMON-LISP-USER").
To me it seems like putting the defpackage in the same file, before the in-package and code, is a good way to ensure that the package is defined before used. So the first method, collecting everything into one file seems easier. Are there any problems with using this method for package creation?
I think that using a separate file for defpackage is a good habit
because:
You don't « pollute » your files with defpackage.
It makes it easier to find the exported/shadowed/... symbols, you
know you just have to look at package.lisp.
You don't have to worry about the order when you use ASDF.
(defsystem :your-system
:components ((:file "package")
... the rest ...))`
Peter Seibel says so ;)
EDIT:
I forgot to mention quickproject which facilitates the creation of
new CL projects.
REPL> (quickproject:make-project "~/src/lisp/my-wonderful-project/"
:depends-on '(drakma cl-ppcre local-time))`
This command will create a directory "~/src/lisp/my-wonderful-project/"
and the following files:
package.lisp
my-wonderful-project.asd (filled)
my-wonderful-project.lisp
README.txt
And thus, I think it's good to use the same convention.
I tend to use multiple source code files, a single "packages.lisp" file and a singe "project.asd" system definition file for most of my projects. If the project requires multiple packages, they're all defined in "packages.lisp", with the relevant exports in place exported.
There is this reason for putting DEFPACKAGE in its own file: if you have a large package, then you might have several groups of related functions, and you might want to have separate source files per function group. Then all the source files would have their own IN-PACKAGE at the top, but they would all "share" the external DEFPACKAGE. Then as long as you get the DEFPACKAGE loaded first, it doesn't matter the order you load the other source files.
An example I'm currently working on has multiple classes in the package, and the source files are broken up to be per class, each having a class definition and the related generic function and method definitions.
I'm learning Lisp (SBCL) and I'm confused about how lisp code is structured. I believe that Lisp Packages are like Python's Modules?
I want to do something like this.
utilities.py:
def foo():
print "And there is silence!"
main.py:
import utilities as u
u.foo()
I've looked up packages, loading and asdf systems. I still don't understand how it all fits together.
Regarding the comparison to Python:
Packages are the most similar thing in CL to Python modules since both are namespaces. Systems and system tools (like ASDF) are more similar to stuff like Distutils and Setuptools in Python.
The most important difference between Python modules and CL packages: packages are independent from files and directories. Instead you use defpackage to create packages and use-package to place the following code into a specific package. There are other package-related operators, but they are mostly for interactive use, these two are the most important in source files.
See the relevant chapter in Practical Common Lisp to get more detailed information.
A package is a namespace for symbols. One can import and export symbols from and to symbols. A symbol maybe interned in one package. Packages can be used by other packages.
A program is structured into systems. A system is a collection of files, dependencies, build rules, default information and more - depebding on the system tool used. ASDF is one of those. Loading libraries is then done by loading systems. Systems can also be compiled, printed, ...
Packages and systems are independent of each other and not related.
It makes sense for each larger piece of software, library or program, to use one or more custom packages. This avoids name clashes with symbols from other loaded software.
As has been remarked, compared to other languages:
Packages correspond to namespaces.
Systems correspond to modules or libraries (i.e., collections of code).
About packages: In order to grok those (which is necessary to avoid symbol conflicts and the like), I strongly recommend reading Ron Garret's Complete Idiot's Guide to Common Lisp Packages.