[armedbear-devel] Problem with defstruct accessor functions and included structures in combination with conc-names
ehuels at gmail.com
Tue Aug 7 12:58:43 UTC 2012
> > Thanks for the report. I've been thinking about it and I think the best
> solution is even easier to code: when an included DEFSTRUCT already defines
> the same accessor, we should simply not define it again: the result will be
> that the accessor checks for structs of type 'A and all of its subtypes
> will be allowed.
> I thought about this, but the problem with my example (repeated here for
> (defstruct a (s1 nil))
> (defstruct (b (:include a) (:conc-name foo-)) (s2 nil))
> (defstruct (c (:include a) (:conc-name foo-)) (s3 nil))
> is that, if we focus on defstruct "c", it is not the included defstruct
> "a" which defines foo-s1 but it is defstruct "b", which is not related to
> "c" at all. Thus, in a naive view, the code that generates "c" has to have
> a look at all substructs of those which are (directly or indirectly)
> included into "c" (possibly going up and down in the hierarchy several
> times). I can hardly imagine that this idea will lead to a stable
> implementation. So, the code for "b" must somehow store in the management
> info for defstruct "a" that there is a successor function foo-s1 for a's
> slot s1 (and the accessor is called foo-s1).
Ah. I thought the problem was in the foo-s1 accessor being generated
multiple times. Sorry I missed the important bit where the definition of A
wasn't also defining the :nconc-name FOO-.
> This slot accessor is not to be generated again for "c", of course, as you
> said. The strange thing this is that, in principle, foo-s1 is not
> applicable to instances of "a", but to instances of "b" and "c" only. Since
> new sub-structures of "a" (with conc-name foo-) can be defined at any time,
> the type for the applicable structures used in the implementation of foo-s1
> cannot be statically encoded but must be dynamically determined, or the
> code for foo-s1 could be dynamically adapted for every new sub-defstruct of
> "a" with conc-name foo-. I tend to believe this is not easy to implement.
Actually, it's really easy to implement. But the runtime cost of doing so
is huge, unfortunately: we can simply use DEFMETHOD to define the
accessors. That will automatically notice the accessor is already defined
and add a method for each additionally defined type.
But, the performance of a method is by no means as efficient as the current
You're talking about adding types to be checked for dynamically to the
current accessors. That's indeed far from trivial: the defstruct generates
inline expansions. These expansions would have to be "dynamically
As far as your change to remove the type checks goes: The type checks were
added by me a few years ago exactly because the 'type-check-less' versions
didn't catch errors in my code. I mean to say: the original ones were
without type checks.
I see multiple options:
1. Remove the type checks in the inline expansions
and use DEFMETHOD for the accessor functions, where we need to use the
only with sufficiently high SAFETY declarations
2. Use your patch to remove the type checks completely
3. Come up with a way to add dynamic type checks to the inline expansions
and function definitions (ie not methods) - possibly executed conditionally
with safety settings.
4. Do nothing (not saying it's a good option, but it's always an option)
Do you see any others? I'm not sure about the performance impact of dynamic
checks, but I do think that if we decide to apply a caching strategy, using
the slow-path of updating the cache in case of a type-mismatch, the impact
may not be much worse than it is today. After all, the biggest change would
be to generate code which allows to check more than one type instead of the
current single type.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the armedbear-devel