Strange symbols in filespec when calling load

2019-06-23 22:02发布

I'm trying to get familiar with a large project, possibly, initially written in Allegro Common Lisp. I have come across this piece of code:

(load "epilog:lib;compile.lisp")

Could please anyone explain what does it mean? Perhaps, if that helps, "epolig" is the name of a package "lib;compile.lisp" is a file "lib/compile.lisp", or so I could understand.

Is this a standard way to do something? And if so, what was the intention of this code? SBCL doesn't recognize colon as a special character in file name, i.e. it reports Couldn't load "epilog:lib;compile.lisp": file does not exist.

标签: common-lisp
1条回答
Explosion°爆炸
2楼-- · 2019-06-23 22:36

Logical Pathnames are a standard Common Lisp feature

It's not a symbol, it is a logical pathname.

Common Lisp has a portable logical pathname facility. The purpose is to abstract from physical pathnames like /usr/local/lisp/src/epilog/lib/compile.lisp or lispm:>sources>epilog>lib>compile.lisp.432 or any other type of pathname (just think of the differences between Unix, Mac OS X, Windows, ...).

The purpose is to use one single pathname scheme and one single logical file organization for your software. Regardless on what machine you are and where your files are, all you need is a mapping from the real file organization into the logical Lisp organization.

History

This facility came from a time when there were lots of different operating system and many different files (DEC VMS, IBM MVS, Multics, Unix, Lisp Machines, MS DOS, Macs, ...). The Lisp Machines were networked and could talk to all kinds of computers - so they learned the native file syntax for all those. In different laboratories (MIT, Xerox, SRI, ...) there were different machines on the network and different file servers. But the Lisp users wanted to load epilog:src;load.lisp and not remember where the stuff really is: on the local machine? but where? On a file server? But where? So on each network there was a registry for the translations from real file locations to logical pathnames.

So this is like an early 'URIs' facility for files - Uniform Resource Identifiers'.

The example explained

"epilog:lib;compile.lisp" is the name of a logical pathname.

  • epilog is the name of the logical host
  • lib; is the directory path
  • compile is the file name
  • lisp is the file type

Logical Pathname Translations

What you need is a translation between logical pathnames and physical pathnames:

Let's say we have a logical host EPILOG with just one translation rule. All files are on this machine for this Lisp under /usr/local/sources/epilog/. So we use some Unix conventions.

CL-USER 40 > (setf (logical-pathname-translations "EPILOG")
                   `(("**;*.*" "/usr/local/sources/epilog/**/*.*")))
(("**;*.*" "/usr/local/sources/epilog/**/*.*"))

Above only has one translation rule:

From EPILOG:**;*.* to /usr/local/sources/epilog/**/*.*.

It maps the logical hosts and all its subdirectories to a directory in a UNIX file system.

One could have more rules:

  • the documentation might be in a different place
  • there might be data files on a larger file system
  • compiled fasl files might be stored somewhere else
  • it might use logical subdirectories from other physical directories

But, again, here we use only one translation rule.

the example explained - part 2

Now we can parse a logical pathname:

CL-USER 41 > (pathname "epilog:lib;compile.lisp")
#P"EPILOG:LIB;COMPILE.LISP"

Let's describe it:

CL-USER 42 > (describe *)

#P"EPILOG:LIB;COMPILE.LISP" is a LOGICAL-PATHNAME
HOST           "EPILOG"
DEVICE         :UNSPECIFIC
DIRECTORY      (:ABSOLUTE "LIB")
NAME           "COMPILE"
TYPE           "LISP"
VERSION        NIL

As you see above, the parts have been parsed from our string.

Now we can also see how a logical pathname translates into a real pathname:

Translate a Logical Pathname to a physical pathname

CL-USER 43 > (translate-logical-pathname "epilog:code;ui;demo.lisp")
#P"/usr/local/sources/epilog/code/ui/demo.lisp"

So, now when you call (load "epilog:lib;compile.lisp"), then Lisp will translate the logical pathname and then really load the file from the translated physical pathname. What we also really want is that the Lisp for all purposes remembers the logical pathname - not the physical one. For example, when the file has a function named FOO, we want that Lisp records the location of the source of the function - but using the logical pathname. This way you can move a compiled file, a compiled application or a Lisp image to a different computer, update the translations and immediately it will be able to locate the source of FOO - if it is available on that machine or somewhere on a network accessible to that machine.

Logical Pathnames need to have a translation

To work with a logical pathname one needs to have a logical pathname translation like above. Often they are stored in a translations file by themselves. Define the translation, load it and then you can use corresponding logical pathnames to compile and load files. A typical software system using them, thus needs a corresponding translation. Sometimes it needs to be edited according to your file path, but sometimes they can be computed while loading the translations file. You'd to look where and how the logical host and the translations are defined.

History part 2

On a Symbolics Lisp Machine there is a site-wide directory, where systems and logical pathnames can be registered. Loading a system can then look up the system definition using this central directory and it also usually load a translations file. Thus the mechanism tells you what the structure of the system is (files, versions, patches, system versions, ...) and it tells you where it is located (which can be scattered around over several hosts or file systems).

Logical pathnames are not much used in newer software - you will encounter them sometimes in certain older software and especially those which were running on Lisp Machines - where this feature was extensively used throughout the system.

查看更多
登录 后发表回答