Open appleby opened 5 years ago
I think maybe the side-effecty stuff at the top of compile-toplevel-define-type-form
that appears to be registering the tycon
and it's constructors needs to be pushed down into the macro expansion, possibly within an eval-when
?
Proof-of-concept PR coming soon (hopefully)...
Thinking about this a bit more, perhaps things are not so simple as I had hoped (they never are!).
There seem to be at least three competing concerns here:
coalton-toplevel
form need to be visible to each other at macro-expansion time.:load-toplevel
time, so that loading a precompiled FASL does the right thing.The corollary to (3) is that the definitions should only be registered in the global environment once, probably inside the macro form and possibly wrapped in an (eval-when (:compile-toplevel :load-toplevel :execute) ...)
. (I suspect the :compile-toplevel
is not needed which means the eval-when
is not needed, but, as usual, staring at the hyperspec section for Processing Toplevel Forms has left me less than certain...).
But pushing the tycon and ctor registrations down into the macro form means that the macro expander needs some other provision to know about in-process definitions. The current implementation already tracks an extra-tycons
parameter for this purpose, and parse-type-expression
is smart enough to lookup stuff in extra-tycons
before trying the "global environment." Perhaps similar provisions could be made for ctors and the like. So far I have been ignoring other toplevel definition forms like define
and declare
, which may need similar treatment (haven't looked yet).
Maybe instead of just extra-tycons
any of the process-toplevel-*
functions (and whatever functions they call) could get passed some kind of environment object that tracks all type/ctor/value definitions, similar to the &environment
defmacro parameter.
tl;dr - Not quite as simple as I had hoped. I should probably read and understand the coalton source (and maybe the MACROEXPAND-ALL chapter of this Dick Waters paper) before proceeding further :). I have other stuff I want to work on first, but will circle back to this eventually (famous last words).
This is a good thing to pick up on. I've felt uneasy about the compile-time side effects Coalton does. There needs to be a better way to manage it all.
Probably what needs to happen is side effects need to happen at macroexpansion time, but they also need to be put in the macroexpansion as well so the FASL loader catches them.
It seems to be "working" when I do that, e.g.
diff --git a/src/toplevel-define-type.lisp b/src/toplevel-define-type.lisp
index b016280..9e56c55 100644
--- a/src/toplevel-define-type.lisp
+++ b/src/toplevel-define-type.lisp
@@ -101,6 +101,14 @@ where
;; TODO: Structs? Vectors? Classes? This should be thought
;; about. Let's start with classes.
`(progn
+ ;; Make sure database side effects are maintained.
+ (eval-when (:compile-toplevel :load-toplevel :execute)
+ (setf (find-tycon ',tycon-name) ,tycon)
+ ,@(loop :for (_ name ty) :in ctors
+ :collect `(unless (var-knownp ',name)
+ (forward-declare-variable ',name))
+ :collect `(setf (var-declared-type ',name) ,ty)))
+
;; Define types. Create the superclass.
;;
;; TODO: handle special case of 1 ctor.
Note: PR in progress https://github.com/stylewarning/coalton/pull/14
The diff in #14 looks similar to what I did in #12. I'm struggling to remember now why I abandoned that PR. Can't remember if I stumbled on a bug or if I was just vaguely unsatisfied with it.
I'm following along with the README and noticed a weird interaction between coalton and ASDF, whereby coalton gets confused if I try to reload it after restarting my inferior lisp (sbcl). For example:
First run, A-OK
On the first compile/load, everything is fine:
Second run
But if I then
slime-restart-inferior-lisp
and reload, coalton gets confused.The exact error is
Workarounds
Any of the following workarounds can be used immediately after restarting sbcl.
library.lisp
after loading the system:(ql:quickload :coalton) (load (asdf:system-relative-pathname :coalton "src/library.lisp"))
(asdf:load-system :coalton :force t)
instead of(ql:quickload :coalton)
$ rm ~/.cache/common-lisp/sbcl-1.4.16-linux-x64/home/ma/src/repos/coalton/src/*.fasl
(ql:quickload :coalton)