[comp.lang.lisp] STRUCTUREP

gat@robotics.Jpl.Nasa.Gov (Erann Gat) (10/10/90)

Is there any way in Common Lisp to test if an object is a structure?  There
doesn't seem to be a structurep function.

E.

moore%cdr.utah.edu@cs.utah.edu (Tim Moore) (10/10/90)

In article <753@forsight.Jpl.Nasa.Gov> gat@robotics.Jpl.Nasa.Gov (Erann Gat) writes:
>Is there any way in Common Lisp to test if an object is a structure?  There
>doesn't seem to be a structurep function.
>
>E.

Not portably.

If your Common Lisp has a fully integrated CLOS, then

(defun structurep (x) (typep (class-of x) 'structure-class))

should work.

If not...

Most implementations leave clues around that a given type is a
structure; a glance at a structured type's property list can be
instructive. From these clues you can construct your own
structure-type-p, e.g. in Utah Common Lisp you could write

(defun structure-type-p (x) (get x 'lisp::structure-info))

Then structurep is

(defun structurep (x) (structure-type-p (type-of x)))

Dick Waters' XP pretty printer uses this technique.

Also, all implementations probably have a structure-p predicate that is
not documented; you can root around with apropos and use it if you
dare.

Tim Moore                    moore@cs.utah.edu {bellcore,hplabs}!utah-cs!moore
"Ah, youth. Ah, statute of limitations."
		-John Waters

cowan@marob.masa.com (John Cowan) (10/10/90)

In article <753@forsight.Jpl.Nasa.Gov> gat@robotics.Jpl.Nasa.Gov (Erann Gat) writes:
>Is there any way in Common Lisp to test if an object is a structure?  There
>doesn't seem to be a structurep function.

No, there isn't, and that's intentional.  Some of the Common Lisp standard
types, notably STREAM, READTABLE, RANDOM-STATE, PATHNAME, and PACKAGE
may be implemented using the structure mechanism, but this fact is hidden
from the user.  A STRUCTUREP function would be unable to discriminate
between these implementation-defined structures and user-defined ones.

There's very little you can say about a structure qua structure, anyway.
The names of the {access, constructor} functions aren't deducible from the
outside, given that the default names can be overridden at DEFSTRUCT time.
-- 
cowan@marob.masa.com			(aka ...!hombre!marob!cowan)
			e'osai ko sarji la lojban

gat@robotics.Jpl.Nasa.Gov (Erann Gat) (10/11/90)

In article <1990Oct10.091722.4495@hellgate.utah.edu>, moore%cdr.utah.edu@cs.utah.edu (Tim Moore) writes:
> In article <753@forsight.Jpl.Nasa.Gov> gat@robotics.Jpl.Nasa.Gov (Erann Gat) writes:
> >Is there any way in Common Lisp to test if an object is a structure?  There
> >doesn't seem to be a structurep function.
> >
> >E.
> 
> Not portably.

Thanks, that's what I wanted to know.

In a later article, Tim writes:
> Incidently, I feel that Common Lisp, with the exception of call/cc,
> has the same semantic power (and much more) of scheme. Any
> disagreement? (Warning, religious war ahead!)

You are right, of course.  However, there are a number of things that you
can do in T which you can't do in Common Lisp.  Among these are:

1.  Create callable objects (which allow you to do things like SETF a locative
passed to a function as an argument)
2.  Tell if an object is a structure :-)

Personally, I think that it's the "and much more" part that is Common
Lisp's biggest problem.  It's getting to the point where it is very difficult
to get a grip on the entire language.  Not only does this make CL hard to
write, it encourages writing code that is nearly impossible to read without
a copy of CLTL in hand (and sometimes even then).  (It also makes it harder
to tell when some crtitical feature has been omitted from the language :->)

Just my opinion.
E.

moore%cdr.utah.edu@cs.utah.edu (Tim Moore) (10/11/90)

In article <754@forsight.Jpl.Nasa.Gov> gat@robotics.Jpl.Nasa.Gov (Erann Gat) writes:
>You are right, of course.  However, there are a number of things that you
>can do in T which you can't do in Common Lisp.  Among these are:
>
>1.  Create callable objects (which allow you to do things like SETF a locative
>passed to a function as an argument)

I'm not sure what you mean by this. If you mean that T has locatives,
it's not hard to simulate locatives in Common Lisp (see Lisp Pointers,
vol. 2 no. 2); they're just closures that encapsulate the information
needed to store into the general variable (I think that's essentially
what they are in T; feel free to correct me).

I think that locatives a la Lisp Machine Lisp (essentially pointers)
are impractical without massive gc complexity or microcode support.

>2.  Tell if an object is a structure :-)

It's unclear why you want to do this. Only system code should really
need a structurep.

>Personally, I think that it's the "and much more" part that is Common
>Lisp's biggest problem.  It's getting to the point where it is very difficult
>to get a grip on the entire language.  Not only does this make CL hard to
>write, it encourages writing code that is nearly impossible to read without
>a copy of CLTL in hand (and sometimes even then).  (It also makes it harder
>to tell when some crtitical feature has been omitted from the language :->)

The "hard-to-write" argument is the one I hear most frequently,
especially around here (where we are close to finishing a CL
implementation). I think only a handful of people (Lisp implementors)
really care about this.

I don't think Common Lisp function names are cryptic. There are a few
macros whose syntax is unfortunate, mostly for hysterical raisons. 

I keep a copy of CLTL around when I write code, mostly to check that
what I'm about to write isn't already part of the language. It's easy
to write obscure code in any Lisp.

>
>Just my opinion.
>E.
That's what the net is for!
Tim Moore                    moore@cs.utah.edu {bellcore,hplabs}!utah-cs!moore
"Ah, youth. Ah, statute of limitations."
		-John Waters

gat@robotics.Jpl.Nasa.Gov (Erann Gat) (10/11/90)

In article <27133D6E.715C@marob.masa.com>, cowan@marob.masa.com (John Cowan) writes:
> In article <753@forsight.Jpl.Nasa.Gov> gat@robotics.Jpl.Nasa.Gov (Erann Gat) writes:
> >Is there any way in Common Lisp to test if an object is a structure?  There
> >doesn't seem to be a structurep function.
> 
> No, there isn't, and that's intentional.  Some of the Common Lisp standard
> types, notably STREAM, READTABLE, RANDOM-STATE, PATHNAME, and PACKAGE
> may be implemented using the structure mechanism, but this fact is hidden
> from the user.  A STRUCTUREP function would be unable to discriminate
> between these implementation-defined structures and user-defined ones.

Oh, come on!  Since the implementation gets to define structurep, it
can make explicit checks to exclude other types which the implementation
implements as structures.  It may not be pretty or efficient, but it's
certainly not impossible!

> There's very little you can say about a structure qua structure, anyway.
> The names of the {access, constructor} functions aren't deducible from the
> outside, given that the default names can be overridden at DEFSTRUCT time.

This strikes me as another severe deficiency in Common Lisp.  Suppose I
wanted to write a function that took an arbitrary structure and printed
out all the slot names and values.  This can't be done in CL, but the
inspector can do it so the underlying capability must be there (at least
in every implementation I've ever used).  This is another example of something
that can be done in T but not in CL.  (BTW, this function might want to
be able to check that its argument was indeed a structure before proceeding.)

None of these "impossible" or "impractical" arguments will stand up.  It is
possible to implement a T-style structure system within Common Lisp.  (The
details are left as an excercise for the reader.)  Perhaps structurep will
appear in CLTL3.  (Perhaps everyone will see the light and start using T.
Perhaps we can banish Fortran.  Perhaps the horse will sing.  :->)

E.

gat@robotics.Jpl.Nasa.Gov (Erann Gat) (10/11/90)

In article <1990Oct10.130925.18317@hellgate.utah.edu>, moore%cdr.utah.edu@cs.utah.edu (Tim Moore) writes:
> In article <754@forsight.Jpl.Nasa.Gov> gat@robotics.Jpl.Nasa.Gov (Erann Gat) writes:
> >You are right, of course.  However, there are a number of things that you
> >can do in T which you can't do in Common Lisp.  Among these are:
> >
> >1.  Create callable objects (which allow you to do things like SETF a locative
> >passed to a function as an argument)
> 
> I'm not sure what you mean by this.

See chapter 7 of the T manual.

> If you mean that T has locatives,

No, I mean callable objects.  (See note above.)

> it's not hard to simulate locatives in Common Lisp (see Lisp Pointers,
> vol. 2 no. 2); they're just closures that encapsulate the information

This sounds like a handy book.  Where do I find it?

> It's unclear why you want to do this. Only system code should really
> need a structurep.

There are dozens of applications I can think of for structurep.  My particular
reason is that I have a stream to which I wish to print arbitrary objects
but on which it is important that no #S read macros appear.  (The reason
for that is too lengthy to go into here, and entirely beside the point in
any case.)  Therefore, I need to be able to tell if the object I am about
to print out is a structure so that I can intercept the print function.
(And yes, I know about the :print-function option to defstruct.  I want
to be able to print out structures created by other people as well!)

> >Personally, I think that it's the "and much more" part that is Common
> >Lisp's biggest problem.  It's getting to the point where it is very difficult
> >to get a grip on the entire language.  Not only does this make CL hard to
> >write, it encourages writing code that is nearly impossible to read without
> >a copy of CLTL in hand (and sometimes even then).  (It also makes it harder
> >to tell when some crtitical feature has been omitted from the language :->)
> 
> The "hard-to-write" argument is the one I hear most frequently,
> especially around here (where we are close to finishing a CL
> implementation). I think only a handful of people (Lisp implementors)
> really care about this.

I think that the people who buy Common Lisp implementations and have to pay
for thousands of obscure features that they never use might care about it as
well.

> I don't think Common Lisp function names are cryptic. There are a few
> macros whose syntax is unfortunate, mostly for hysterical raisons. 
> 
> I keep a copy of CLTL around when I write code, mostly to check that
> what I'm about to write isn't already part of the language. It's easy
> to write obscure code in any Lisp.

How can you be sure that what you are writing isn't already part of the
language, but that it has an obscure name and is tucked away in a remote
corner of Steele's tome?  I tend to discover surprizing new features of
CL on a fairly regular basis (and pity the poor programmer who spends hours
searching through the book saying to himself, "There's just got to be a
way to test for structures, there's just got to be! :->)

> >Just my opinion.
> That's what the net is for!
Thanks.

E.

gat@robotics.Jpl.Nasa.Gov (Erann Gat) (10/11/90)

In article <1990Oct10.130925.18317@hellgate.utah.edu>, moore%cdr.utah.edu@cs.utah.edu (Tim Moore) writes:
> I don't think Common Lisp function names are cryptic. There are a few
> macros whose syntax is unfortunate, mostly for hysterical raisons. 
                                                 ^^^^^^^^^^
With this I heartily agree! :-)

E.

eliot@phoenix.Princeton.EDU (Eliot Handelman) (10/11/90)

In article <1990Oct10.091722.4495@hellgate.utah.edu>, moore%cdr.utah.edu@cs.utah.edu (Tim Moore) writes:
> In article <753@forsight.Jpl.Nasa.Gov> gat@robotics.Jpl.Nasa.Gov (Erann Gat) writes:
> >Is there any way in Common Lisp to test if an object is a structure?  There
> >doesn't seem to be a structurep function.
> >
;> >E.
;> 
;> Not portably.


You can do this, though:

>(defstruct structure)

>(defstruct (foo (:include structure))
   blah)

>(structure-p (make-foo))
T

Zetalisp, I think, did something like that automatically. the "structure"
structure would have DOCUMENTATION as one of its slots, eg. (I've
read most of the lisp machine manual, but I don't know too much about
its internals, on the other hand.)

--eliot

moore%cdr.utah.edu@cs.utah.edu (Tim Moore) (10/11/90)

In article <756@forsight.Jpl.Nasa.Gov> gat@robotics.Jpl.Nasa.Gov (Erann Gat) writes:
>In article <1990Oct10.130925.18317@hellgate.utah.edu>, moore%cdr.utah.edu@cs.utah.edu (Tim Moore) writes:
>> In article <754@forsight.Jpl.Nasa.Gov> gat@robotics.Jpl.Nasa.Gov (Erann Gat) writes:
>> >You are right, of course.  However, there are a number of things that you
>> >can do in T which you can't do in Common Lisp.  Among these are:
>> >
>> >1.  Create callable objects (which allow you to do things like SETF a locative
>> >passed to a function as an argument)
>> 
>> I'm not sure what you mean by this.
>
>See chapter 7 of the T manual.

OK, I have. It looks like callable objects are an abstraction of the
objects-as-closures style that has appeared in other articles today.
Nice as far as that style of object-oriented programming goes.

>> it's not hard to simulate locatives in Common Lisp (see Lisp Pointers,
>> vol. 2 no. 2); they're just closures that encapsulate the information
>
>This sounds like a handy book.  Where do I find it?
>

Lisp Pointers is a periodical that is published irregularly. It is now
a publication of the ACM.

>> It's unclear why you want to do this. Only system code should really
>> need a structurep.
>
>There are dozens of applications I can think of for structurep.  My particular
>reason is that I have a stream to which I wish to print arbitrary objects
>but on which it is important that no #S read macros appear.  (The reason
>for that is too lengthy to go into here, and entirely beside the point in
>any case.)  Therefore, I need to be able to tell if the object I am about
>to print out is a structure so that I can intercept the print function.
>(And yes, I know about the :print-function option to defstruct.  I want
>to be able to print out structures created by other people as well!)
>

It's true that there aren't any facilities for getting at the slots of
an arbitrary structured type (unless you have the source of the
defstruct). I don't know whether this is good or bad. slots of a
structured type must exist somewhere in the system in order to support
inheritance in a practical manner.

It seems like a bad idea to overide a structure's print function,
unless you are handling *print-circle*, *print-length*, etc. You might
get a nasty surprise. You could print the object to a string and
strip the #S...

>> I don't think Common Lisp function names are cryptic. There are a few
>> macros whose syntax is unfortunate, mostly for hysterical raisons. 
>> 
>> I keep a copy of CLTL around when I write code, mostly to check that
>> what I'm about to write isn't already part of the language. It's easy
>> to write obscure code in any Lisp.
>
>How can you be sure that what you are writing isn't already part of the
>language, but that it has an obscure name and is tucked away in a remote
>corner of Steele's tome?  I tend to discover surprizing new features of
>CL on a fairly regular basis (and pity the poor programmer who spends hours
>searching through the book saying to himself, "There's just got to be a
>way to test for structures, there's just got to be! :->)

I use the index. It's not much different from browsing the Unix
manuals for C libraries. Also, experience helps, as with any large
language or system.
Tim Moore                    moore@cs.utah.edu {bellcore,hplabs}!utah-cs!moore
"Ah, youth. Ah, statute of limitations."
		-John Waters

gat@robotics.Jpl.Nasa.Gov (Erann Gat) (10/11/90)

In article <1990Oct10.165312.29838@hellgate.utah.edu>, moore%cdr.utah.edu@cs.utah.edu (Tim Moore) writes:
> You could print the object to a string and
> strip the #S...

That's actually not a bad solution to the puzzle:

(defun structurep (thing)
  (equal "#S" (subseq (format nil "~S" thing) 0 2)))

This would work for any structure which did not have a :print-function
defined.  (What a horrible hack, though!)

E.

lgm@cbnewsc.att.com (lawrence.g.mayka) (10/11/90)

In article <755@forsight.Jpl.Nasa.Gov>, gat@robotics.Jpl.Nasa.Gov (Erann Gat) writes:
> In article <27133D6E.715C@marob.masa.com>, cowan@marob.masa.com (John Cowan) writes:
> > In article <753@forsight.Jpl.Nasa.Gov> gat@robotics.Jpl.Nasa.Gov (Erann Gat) writes:
> > >Is there any way in Common Lisp to test if an object is a structure?  There
> > >doesn't seem to be a structurep function.
> > 
> > No, there isn't, and that's intentional.  Some of the Common Lisp standard
> > types, notably STREAM, READTABLE, RANDOM-STATE, PATHNAME, and PACKAGE
> > may be implemented using the structure mechanism, but this fact is hidden
> > from the user.  A STRUCTUREP function would be unable to discriminate
> > between these implementation-defined structures and user-defined ones.
> 
> Oh, come on!  Since the implementation gets to define structurep, it
> can make explicit checks to exclude other types which the implementation
> implements as structures.  It may not be pretty or efficient, but it's
> certainly not impossible!

As someone else has pointed out, ANSI Common Lisp integrates
DEFSTRUCTs into the object system (CLOS).  One can therefore test for
a structure with

(TYPEP obj 'STRUCTURE-OBJECT)

or

(TYPEP (CLASS-OF obj) 'STRUCTURE-CLASS)

Predefined types such as STREAM may have a metaclass of either
BUILT-IN-CLASS, STRUCTURE-CLASS, or STANDARD-CLASS.

> > There's very little you can say about a structure qua structure, anyway.
> > The names of the {access, constructor} functions aren't deducible from the
> > outside, given that the default names can be overridden at DEFSTRUCT time.
> 
> This strikes me as another severe deficiency in Common Lisp.  Suppose I
> wanted to write a function that took an arbitrary structure and printed
> out all the slot names and values.  This can't be done in CL, but the

The metaobject protocol (not yet officially standardized, though large
parts have been informally agreed upon by major vendors) helps out
here:

(DOLIST (slot-descriptor (CLASS-SLOTS (CLASS-OF obj)))
  (LET ((slot-name (SLOT-DEFINITION-NAME slot-descriptor)))
    (FORMAT T "~&~S : ~S~&" slot-name (SLOT-VALUE obj slot-name))))


	Lawrence G. Mayka
	AT&T Bell Laboratories
	lgm@iexist.att.com

Standard disclaimer.

pazzani@ics.uci.edu (Michael Pazzani) (10/11/90)

In article <758@forsight.Jpl.Nasa.Gov> gat@robotics.Jpl.Nasa.Gov (Erann Gat) writes:
>That's actually not a bad solution to the puzzle:
>
>(defun structurep (thing)
>  (equal "#S" (subseq (format nil "~S" thing) 0 2)))
>
>This would work for any structure which did not have a :print-function
>defined.  (What a horrible hack, though!)
>
>E.

If you get to define the structures (rather than using a large existing
program), you could do this in a different way:

(defstruct struct) ;; It has no slots, but a struct-p is created

now just include struct in every structure you care about, and struct-p
will work on them.

(defstruct (pig (:include struct)) piglets)
(defstruct (goat (:include struct)) kids)
etc.

(struct-p (make-pig :piglets nil)) 


Mike

cowan@marob.masa.com (John Cowan) (10/11/90)

Erann Gat writes:

[is there a STRUCTUREP in Common Lisp?]

I write:

[No; standard types can be implemented as structures]


Erann replies:

>Oh, come on!  Since the implementation gets to define structurep, it
>can make explicit checks to exclude other types which the implementation
>implements as structures.  It may not be pretty or efficient, but it's
>certainly not impossible!

The point is that the non-existence of STRUCTUREP allows freedom to the
implementor to make certain choices.  Structures are a "raw" construct
in CL, with very few specific semantics (see below).

>Suppose I
>wanted to write a function that took an arbitrary structure and printed
>out all the slot names and values.  This can't be done in CL, but the
>inspector can do it so the underlying capability must be there (at least
>in every implementation I've ever used).  This is another example of something
>that can be done in T but not in CL.  (BTW, this function might want to
>be able to check that its argument was indeed a structure before proceeding.)

The underlying capability is indeed there; however, the implementation is
not required to expose it to the user in any systematic way that might
constrain >how< this capability is provided.

>It is
>possible to implement a T-style structure system within Common Lisp.  (The
>details are left as an excercise for the reader.)  Perhaps structurep will
>appear in CLTL3.

Not only do I know it's possible, I've actually done it.  I have a nearly-
complete implementation of T3.0 written in Common Lisp (1st ed.).
T structures are all instances of a single CL structure type, T::STRUCT,
which uses an auxiliary CL structure T::STYPE to hold T-structure-type
meta-information.

My point is that Common Lisp structures >aren't< T structures, and aren't
meant to be.  CL structures are a layer of syntactic sugar that allow you
to define handy {access, construct, print} functions, and take care of
some of the work.  The underlying datatype can be a list, a vector, or
a MacLisp hunk (i.e. a cons with != 2 components).  The "hunk-level"
access provided in MacLisp is not standardized by CL, so you can't reliably
get at it, and implementers who think they can do better than hunks are
free to do so.  CL is not designed to require retaining any meta-information
at run time about structures, except for what is needed by debugging
tools (inspector, etc.) whose interfaces are not standardized.

T structures, OTOH, are much more abstract, with considerable meta-information,
more like T objects.  In fact, we can say that structures only exist in T
as a way of making certain kinds of rather "passive" objects more efficient.
-- 
cowan@marob.masa.com			(aka ...!hombre!marob!cowan)
			e'osai ko sarji la lojban

gat@robotics.Jpl.Nasa.Gov (Erann Gat) (10/12/90)

In article <2713DF17.555@ics.uci.edu>, pazzani@ics.uci.edu (Michael Pazzani) writes:
> If you get to define the structures (rather than using a large existing
> program), you could do this in a different way:
> 
> (defstruct struct) ;; It has no slots, but a struct-p is created
> 
> now just include struct in every structure you care about, and struct-p
> will work on them.

If I get to define all the structures then I could just as easily just
check for all the structure types that I have derfined.  There's no
sport in that.  I want to be able to tell if someone else's data object
is a structure.

There is actually a portable definition of structurp which no one seems
to have thought of.  The number of core data types in Common Lisp is
finite.  Therefore, one can check to see if an object is a structure
simply by checking that it is NOT anything else.  i.e. something like

(defun structurep (object)
  (and (not (numberp object))
       (not (consp object))
       (not (symbolp object))
      ... [ probably ten or fifteen more would do ]
       (commonp object)))

Of course, in CLTL2 they took out commonp (on the grounds that it wasn't
useful for anything!) but they added CLOS which lets you test for structures
in other ways.

E.

gat@robotics.Jpl.Nasa.Gov (Erann Gat) (10/12/90)

In article <2714943B.1332@marob.masa.com>, cowan@marob.masa.com (John Cowan) writes:
> The underlying capability is indeed there; however, the implementation is
> not required to expose it to the user in any systematic way that might
> constrain >how< this capability is provided.

Sorry, I don't see how the requirement to provide structurep to the user
would in any way constrain an implementation.  As you yourself acknowledge
the capability must already exist (mandated implicitly by other parts
of the standard) -  what impact could it have to require that this capability
be exposed in a standard way?

E.

jeff@aiai.ed.ac.uk (Jeff Dalton) (10/12/90)

In article <27133D6E.715C@marob.masa.com> cowan@marob.masa.com (John Cowan) writes:
>In article <753@forsight.Jpl.Nasa.Gov> gat@robotics.Jpl.Nasa.Gov (Erann Gat) writes:
>>Is there any way in Common Lisp to test if an object is a structure?  There
>>doesn't seem to be a structurep function.

>No, there isn't, and that's intentional.  Some of the Common Lisp standard
>types, notably STREAM, READTABLE, RANDOM-STATE, PATHNAME, and PACKAGE
>may be implemented using the structure mechanism, but this fact is hidden
>from the user.  A STRUCTUREP function would be unable to discriminate
>between these implementation-defined structures and user-defined ones.

So?  Is that supposed to be a bad thing (that some built-in types
might be structures)?

Note that in Common Lisps with an integrated CLOS (which is how
they'll probably all be after a while) you *can* find out if a 
type is a structure.

>There's very little you can say about a structure qua structure, anyway.
>The names of the {access, constructor} functions aren't deducible from the
>outside, given that the default names can be overridden at DEFSTRUCT time.

That's why you need more than STRUCTUREP.

jeff@aiai.ed.ac.uk (Jeff Dalton) (10/18/90)

In article <2714943B.1332@marob.masa.com> cowan@marob.masa.com (John Cowan) writes:

>Erann Gat writes:

>>Oh, come on!  Since the implementation gets to define structurep, it
>>can make explicit checks to exclude other types which the implementation
>>implements as structures.  It may not be pretty or efficient, but it's
>>certainly not impossible!
>
>The point is that the non-existence of STRUCTUREP allows freedom to the
>implementor to make certain choices.  Structures are a "raw" construct
>in CL, with very few specific semantics (see below).

Yes, it allows certain choices.  But are they choices worth allowing?

Earlier you write:

   [No; standard types can be implemented as structures]

Why is *that* a problem?  It looks like you're talking about
a different aspect of the structure issue in this message.
Anyway ...

It's a pain that one cannot determine whether an object is a structure
and find out what slots it has.  For example, you may want to write a
print function that works like the normal one in somce cases but not
in others.  You can't, because the information needed for the normal
case isn't available in portable form.  (Yes, this is the same example
given before.)

A number of people have written their own macro, on top of DEFSTRUCT,
just to provide such capabilities.  Note that (1) they can do this,
and (2) the implementation has the same freedom it had before.

(BTW, I'm glad to hear you've implemented a T in CL.  Good idea.)

>My point is that Common Lisp structures >aren't< T structures, and aren't
>meant to be.  CL structures are a layer of syntactic sugar that allow you
>to define handy {access, construct, print} functions, and take care of
>some of the work.  The underlying datatype can be a list, a vector, or
>a MacLisp hunk (i.e. a cons with != 2 components).  The "hunk-level"
>access provided in MacLisp is not standardized by CL, so you can't reliably
>get at it, and implementers who think they can do better than hunks are
>free to do so.  CL is not designed to require retaining any meta-information
>at run time about structures, except for what is needed by debugging
>tools (inspector, etc.) whose interfaces are not standardized.

1. STRUCTUREP should probably be true only of structures defined 
   without using the :TYPE option.  (N.B. that prevents the name
   from being a valid type specifier.)

2. DEFSTRUCT defines the name as a type specifier, defines a
   predicate, and causes a certain syntax to be used when printing.
   This suggests that structures can be recognized with a fair degree
   of reliability.  STRUCTUREP would have the same reliability (or
   lack of it), but it shouldn't be harder to provide STRUCTUREP than
   to provide the predicates.

3. CLtL II says structure types created by DEFSTRUCT must be disjoint
   from (among other types) CONS and ARRAY.  So the freedom to make
   the underlying type be a list or vector has been removed.

-- Jeff