[Bug-openmcl] type cache
gb at clozure.com
Tue Feb 24 21:03:30 MST 2004
On Tue, 24 Feb 2004, bryan o'connor wrote:
> a funny thing happened on the way to fixing some copy-pprint-dispatch
> tests, i inadvertently found the source of the problem for 5 of the
> subtypep failures (SUBTYPEP.EQL.1, .EQL.2, .MEMBER.12, .MEMBER.17,
> and .MEMBER.18) --
> the type cache.
> forms like this:
> (let ((obj '(foo bar)))
> (typep obj `(member ,obj))
> (typep obj `(eql ,obj))))
> work only once because the type-spec gets cached with the stack-consed
> obj. a quick verify of the problem is to just disable the cache.
In that example, OBJ isn't stack-consed (but I think that I know what
I haven't seen the test case failures, so I'm not entirely sure what
the bug(s) are.
> my plan is to fix it by selectively not caching certain forms and
> investigating if the code with the comment about using copy-tree
> "in case it was stack-consed" is part of the problem.
Ignoring the case of stack-consed objects for the moment: is there
anything in the spec which says anything about whether/when/how
a list that's used as a type specifier can be destructively modified ?
(let* ((x (list 'integer)))
(typep 3 x) ; we might want to pat the compiler on the back if it says
; T here.
(foo x) ; FOO might destructively modify X; we don't know
(typep 3 x)); Should this return T or call TYPEP or ???
If an implementation has some idea of what type a type specifier denotes,
does it have to make conservative assumptions based on the "mutablity"
of the type specifier ?
If we have to assume that any (non-quoted) list used as a type specifier
is mutable, it'd be pointless to cache any information associated with
such a list: something could change from being a number specifier to
being an array specifier and still be EQUAL to itself (we could only
cache a carefully constructed copy.)
I think that the question of whether a list used as a type specifier
can be subsequently modified is related to the question of how
dynamic-extent objects should be treated. I tend to think that
modifying type-specifier lists is a questionable practice (though if
there's code in the lisp that does so I'm probably to blame for it
...). If a list "becomes immutable" when it's used as a type specifier,
then it shouldn't reference any dynamic-extent objects (which get
mutated left and write as soon as their extent is exited.) If a type
specifier isn't immutable, then exactly when can it be modified ?
Can a DEFTYPE expander or a function used in a SATISFIES specifier
modify a containing type specifier ? If so, in what order are
subforms of AND and OR processed, since that order may determine
the result ?
There are far fewer of these sort of questions if we think of
type specifiers as being immutable designators for an abstract
type (the abstract type happens to be concretely represented as
a ctype - more or less - in OpenMCL.) I tend to think of types
(whether concretely represented or not) as being of indefinite
extent, which makes the concept of an EQL or MEMBER type which
refers to a stack-consed object hard to understand or reason
about (does the type stop existing as soon as the object does ?
If so, what does that mean ?)
> or.. perhaps changing the cache lookup to avoid the clash.
> before i continue down this path, any suggestions or pitfalls?
> ps. the copy-pprint-dispatch failures most probably are still related
> since they are using similar '(eql (foo bar)) type-specs.
I'll try to look at the test suite to try to get a better idea of what
fails, and will try to think about some of these questions a bit
harder. I tend to wonder whether the -real- problem is that the
pretty printer will blithely shove objects in hash tables even if they
were stack allocated, that those hash tables will then sometimes
contain what the rest of the printer would think of as #<BOGUS
OBJECT>s, and that this has long been asking for trouble (whether it's
the root cause of the current set of failures or not ...) In 68K MCL,
SAVE-APPLICATION used to choke on this stuff, because it couldn't
figure out how to relocate all of the bogus pointers in the pretty
printer's hash tables.
More information about the Bug-openmcl