From: Bruno H. <br...@cl...> - 2017-08-03 21:51:21
|
Hi Sam, > http://clhs.lisp.se/Body/03_bcaa.htm: > >> It is not specified whether definitions made available in the > >> compilation environment are available in the evaluation environment, nor > >> is it specified whether they are available in subsequent compilation > >> units or subsequent invocations of the compiler. This part of CLHS - the specification of side effects of COMPILE-FILE - was probably the area where the standardization had the most positive effect. Before this standardization, the instructions to compile a given package depended a lot on the particular CL implementation. Afterwards, package authors learned where to put EVAL-WHEN wrappers around selected top-level forms. The standards committee considered that separating the compile-time environment from the evaluation environment was a good thing, but left a considerable amount of leeway to the implementations, if they wanted to not break existing code. > Some macros form Figure 3-8 leak into the evaluation environment and > some do not. > > Specifically, declaim, defvar, defconstant, defparameter do NOT. > defmacro, defclass, defstruct, defpackage DO. Yes, this is how it behaves in clisp. Let's compare clisp with sbcl. I compiled this file: ================== compile with compile-file =================== (declaim (special foo1)) (defvar foo2 10) (defconstant foo3 11) (defparameter foo4 12) (defmacro foo5 () '(list 73 55)) (defclass foo6 () ()) (defstruct foo7 ()) (defpackage foo8) ================================================================ Results: * Regarding DEFVAR, DEFPARAMETER: clisp and sbcl behave the same, no side effects on the evaluation environment. * Regarding DEFMACRO, DEFPACKAGE: clisp and sbcl behave the same, the definitions are made available in the evaluation environment. * Regarding DECLAIM, DEFCONSTANT: clisp provides better separation: no side effects in clisp, whereas definitions are available in the evaluation environment for sbcl. * Regarding DEFCLASS: sbcl provides better separation. The class definition is available in the evaluation environment for clisp. * Regarding DEFSTRUCT: sbcl provides slightly better separation. The class definition is available in the evaluation environment for clisp. In sbcl, the class definition is available, but the accessors are not, so that (find-class 'foo7) returns true but (make-instance 'foo7) nevertheless fails. > This kinda makes sense - except for declaim which I think should be in > the second list. No. Ideally none of the defining macros should have an effect on the evaluation environment. It makes no sense to make DECLAIM behave worse in clisp, now that over 25 years so many packages have been made to work with clisp. Taking this argument the other way: It would be possible to make DEFCLASS behave better in clisp, namely as good as sbcl does - now that over 15 years so many packages have been made to work with sbcl. It's "only" an implementation issue: I don't know how to modify the CLOS so that it considers two separate worlds of classes: the compilation environment and the evaluation environment. > On the second thought, I think this is not quite right. > Compiling a file should have an effect of loading its lib file. No, ideally compiling a file would leave no traces at all in the clisp process that ran the COMPILE-FILE. > E.g., in a single session, using an example from > http://clisp.org/impnotes/require.html, > > (compile-file "foo") > > will _not_ define variables defined in "foo", but > > (compile-file "bar") > > will load "foo.lib" (because of `(require "foo")` in "bar.lisp") and > thus will define the variables. Yes, but it should load "foo.lib" when stumbling across (require "foo") in bar.lisp. It should not rely on the traces in memory, left by the previous COMPILE-FILE command. That is the precise raison d'être for the .lib files. I don't know how other implementations handle this issue when they produce just one file as the result of COMPILE-FILE. I invented the .lib files precisely so that (compile-file "bar") could work - without requiring prior (compile-file "foo") nor (load "foo") in the same session, - without implicitly loading all the definitions of "foo" (thus leaving way too many side effects in the compilation environment). Bruno |