djk@cs.columbia.edu (David Kurlander) (11/27/90)
Is there a way to copy an instance of an object? Something similar to the structure copiers generated for defstructs? I'd hate to have to define a specific method for each class. Thanks, David -- ---------------------------------- David Kurlander Department of Computer Science djk@cs.columbia.edu Columbia University
barmar@think.com (Barry Margolin) (11/27/90)
In article <1990Nov26.192413.23214@cs.columbia.edu> djk@cs.columbia.edu (David Kurlander) writes: >Is there a way to copy an instance of an object? Something similar to >the structure copiers generated for defstructs? I'd hate to have to >define a specific method for each class. No, there is no standard copying function, and this was intentionally omitted. The same goes for equivalence functions (although we might have given in and defined EQUALP for CLOS objects, I don't remember). The appropriate behavior of a copying or equivalence function is generally application-dependent. Should the copy be deep (copying the entire structure, sharing pointers to leaves, a la copy-tree) or shallow (copying only the top-level structure, like copy-list)? If deep, what types of objects are leaves (for copy-tree it's simple -- anything but a cons is a leaf). What do you get when you pass an instance of a subclass to a superclass's copier (we almost got rid of DEFSTRUCT copiers while trying to hash out this ambiguity)? We already have four equivalence predicates (EQ, EQL, EQUAL, EQUALP), but they don't do all the things people want (or sometimes expect). Many of us in X3J13 believe that EQUAL was a big mistake in Lisp. Trees of conses generally represent some higher-level data structure, and it would probably have been better to force programmers to define higher-level comparison functions for them; EQUAL is generally a lazy solution. It's too late to fix EQUAL. But we didn't want to make the same mistake in CLOS by adding a copier. I did some design a couple of years ago on generic functions COPY-OBJECT and EQUAL-OBJECT. They solve the above shallow/deep issue by taking parameters that indicate how to recurse. In particular, there was a type specifier parameter that indicated which types should be copied recursively. Type-specific keyword arguments could be passed in, which could be used to further parametrize the way individual types are copied (for instance, :LIST T indicates that conses should be copied with COPY-LIST rather than COPY-TREE). -- Barry Margolin, Thinking Machines Corp. barmar@think.com {uunet,harvard}!think!barmar
ray@cme.nist.gov (Steve Ray) (11/28/90)
My understanding is that in general this is not a trivially solvable problem. For example, what if an object has a slot which contains another object? And what if that second object refers (directly or indirectly) back to the first? How should you resolve such cycles, in order to avoid infinite recursion, in a general fashion. Back in the old days of Flavors, I remember using the :fasd-init option to tell an object which slots to write out, which is one way of getting around this. If there is some elegant way around this, I'd like to know too! -- Steven R. Ray National Institute of Standards and Technology Building 220, Room A127 Gaithersburg, MD 20899 ray@cme.nist.gov (301) 975-3524