4:43:42beachIt is hard to understand, and I wanted to know whether it would be harder to keep them in the same environment.

4:44:24beachDoing it over is not as scary as it sounds. Now I know a lot more about what is needed and when, and I know a lot more about sharing code between phases.

4:45:22beachYesterday, I finished phase 1 in this rewrite. If phase 2 turns out to be fairly fast to write, I think I will go with this new system.

4:45:47beachAlso, I learned some other lessons from the mistakes of my first and second attempts.

4:46:39beachI should not hesitate splitting up functions in the CLOS module into smaller ones. That way, I can replace smaller amounts of code at bootstrapping time if I need to.

4:47:49beachAnd I should not hesitate introducing an indirection, so that a function calls another function when needed. An example: FIND-CLASS. During bootstrapping, different calls to FIND-CLASS mean different things.

4:48:17beachFor instance, when I create a class metaobject, it has to find both the metaclass and the superclasses.

4:49:26beachSo I introduce two functions FIND-METACLASS and FIND-SUPERCLASS. In production code, they both just call FIND-CLASS.

4:49:50beachBut during bootstrapping, they are two small pieces of code that I can redefine as I wish.

4:50:43beachThese "ideas" (that I should have realized a long time ago, but hey) make it possible to reuse more production code during bootstrapping, so the total amount of bootstrapping code decreases.

4:53:45no-defun-allowed(this vacuum cleaner is very good at getting cat hair stuck in it. i would not reccomend you give it to cat people.)

4:54:46beachI don't have a cat, and I have a cleaning lady and two very good vacuum cleaners, so I think I am set.

4:55:06beachSo, SBCL is a bit strange with its representation. In the distant past, someone thought that CAR and CDR would be used a lot, so it would be a win to avoid having to check for NULL and CONS each time.

4:58:33beachTesting for whether the end is NIL or some other atom is only needed at the end of the list.

4:59:41beachNow that cleaver idea in SBCL now penetrates all over the code as a special case, which, in addition, is no longer an optimization, because traversing a list takes longer, and CAR/CDR has been replaced by generic-function accessors for data structures.

5:00:05beachThis is why I avoid all possible special cases that I can in SICL.

5:00:41beachThis is why all SICL heap-allocated objects are represented as a two word block.

5:01:00beachEither that's all there is to it (if it is a CONS), or the second word points to a "rack".

5:01:24beachThis way, I get the indirection that is needed by CLOS for standard objects.

5:01:40beachAnd I get to reuse the CLOS/MOP machinery for other objects as well.

5:11:03beachThere might have been a slight advantage to use 001 and 011 for CONS cells and general instances, because then 0x1 means a heap-allocated object. But I don't think it matters.

5:12:08beachEther way, none of that matters for SICL because there is no C or assembly file in which these tags are defined.

5:12:45beachThey are hidden in a few functions such as FIXNUMP, CHARACTERP, etc.

5:13:00beachIf I redefine those functions and recompile, I should be fine.

5:14:12beachThere might be some code in SICL right now that mentions those tags, but that code is obsolete. It will be removed when I get around to it.

5:18:37beachInterestingly, as you probably know, in SICL each class has a UNIQUE NUMBER which changes when the class is redefined. One might think that some of those class numbers, like for STANDARD-CLASS etc., would have to be mentioned somewhere.

5:18:37beachNot so. They get assigned during bootstrapping, and they acquire the same number in each phase. So, in the last phase, all I need to do is to define a constant that takes the value of a class number in the previous phase, should I need such a thing. But I don't think I even need it at all.