📜 ⬆️ ⬇️

Developing web applications in Common Lisp (part two)

This review is a small guide for those who decide (or decide) to entrust the future of their startup to this wonderful language. Despite the fact that the main focus will be on web development, I will try to cover also more general topics related to Common Lisp in one way or another. The material will be gathered from my own experience in developing the AlterMoby web service.

The second part of this review will be devoted to the basic configuration of the Lisp environment. Installation of a simple Lisp system will be described. In addition, we will briefly consider the ASDF dependency management system.

Before proceeding further, we will need to set up a simple Lisp system needed for experimentation. The following installation instructions are designed for Debian Lenny, but will probably work in many other Linux distributions (for example, in Ubuntu).

So, first we install the following packages: SBCL, Emacs and SLIME. SBCL is a Common Lisp compiler, which we discussed in the first part of this review. Emacs is a text editor in which we will write program code. I would never recommend this editor to you if it were not for one significant circumstance. It was written for him SLIME, the third of the above packages. SLIME (Superior Lisp Interaction Mode for Emacs) is a client-server system for interacting with Lisp. The client part, which is called SLIME, is integrated with Emacs (being its extension module). The server part of SLIME is called SWANK and interacts directly with Lisp. The SLIME client and SWANK communicate with each other via TCP, which makes it possible to remotely control the Lisp system.
After installing these three components, you need to introduce them to each other. To do this, add the following lines to the configuration file ~ / .emacs:

(setq inferior-lisp-program "/usr/bin/sbcl") (require 'slime) (slime-setup) 

Now we can safely run our Lisp system. Open Emacs, enter Mx slime (for newcomers to Emacs to read the quick start guide ). If everything went well, a REPL (Lisp console) will open. Enter something like ( + 1 1 ) to make sure that SBCL is up and running our commands.

Slime allows you to calculate current expressions, search for character definitions, format code, make contextual prompts, and much more. Convenience of working with SLIME becomes indisputable in comparison with the work of bare SBCL in the terminal. Later, when you have experience with Emacs (for those who have not had it before), you can finely configure the interface. For example, change the color of the background and text, add Unicode support and so on. Now it is not so important, the main thing is that we have a simple Lisp-environment in which you can already work.

Since we cannot write everything from scratch, we need ready-made third-party libraries. Therefore, it will be useful to understand the way they are distributed. Most third-party libraries use the ASDF dependency management system, which has become the de facto standard in the Common Lisp world. We do not need to install ASDF - it comes with SBCL.

So what is ASDF? This system can be compared to the make utility in the UNIX world. It tracks the links and dependencies between different code points (from a single file to a large framework), coordinating their compilation and loading. Most ASDF-compatible libraries have a single asd file in the root directory that describes the software system (in ASDF terminology). Any complex system consists of several components. A component can be like a module, i.e. container for other components, and a separate file. Components depend on other components, and systems depend on other systems. Based on this and other data, ASDF determines the order in which the target system is compiled and loaded.

The structure and relationships of the system are described using declarative DSL (domain-specific language). The most important part of this DSL is the defsystem directive. I will give an example of a simple asd file:

 (in-package :asdf) (defsystem my-lib :name "my-lib" :version "0.1" :components ( (:module "common" :components ( (:file "common-file-1") (:file "common-file-2") (:file "common-file-3" :depends-on ("common-file-1" "common-file-2")))) (:module "main" :components ( (:file "main-file")) :depends-on (:common))) :depends-on (:my-base-lib)) 

Here, the first line contains the directive to switch to a package (similar to the namespace in Common Lisp — hereafter the word “package” will be used in this sense) ASDF. This is done for convenience, so as not to interfere with the description of the system and its implementation code in one heap (as an alternative, you can create a new package my-lib-asd for this). Next, the system my-lib is defined, containing two modules and dependent on the system my-base-lib. Typically, each module corresponds to a directory with source files combined by some structural or functional feature. In this example, the first module is called “common” and contains three files: independent “common-file-1” and “common-file-2” and dependent on these two “common-file-3”. The second module is called “main”, contains a single file “main-file” and depends on the module “common”.

To load the system “my-lib” we need to enter the following command:

 (asdf:oos 'asdf:load-op :my-lib) 

This command will first check the relevance of each of the components in each of the systems (my-lib, my-base-lib and those on whom the latter depends). Irrelevant components will be recompiled, actual ones will be immediately loaded into memory (that is, their characters will be processed and added to the appropriate packages). If not all the systems or components on which the target system depends are found, then a loading error will occur.

Now let's figure out where ASDF knows where to look for asd files. When compiling or loading the system, ASDF looks at the list of directories stored in the asdf variable: * central registry *, checking for the required asd file (its name must match the name of the target system). Therefore, before loading a new system, you can add the path to its root directory to this list. A more reasonable approach is to select a special directory containing symbolic links to asd-files of all existing systems. For this purpose, the / usr / share / common-lisp / systems / directory is suitable, the path to which is added by default to asdf: * central-registry *.

Having a basic knowledge of ASDF, we can already use the many third-party libraries that are abundantly available on the Internet (here the most important guide is CLiki , the largest portal dedicated to Common Lisp). Only one question remains: how to install the necessary libraries, automatically tracking and downloading their dependencies? ASDF has only basic functionality, not allowing to automate the installation process. Fortunately, there are enough ASDF extensions to solve this problem. These include, in particular, ASDF-INSTALL . Despite these extensions, I would recommend at first not to use them and install dependencies manually. This will allow a good understanding of the internal links in the libraries used.

Source: https://habr.com/ru/post/105215/

All Articles