Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!swrinde!elroy.jpl.nasa.gov!sdd.hp.com!think.com!barmar From: barmar@think.com (Barry Margolin) Newsgroups: comp.lang.lisp Subject: Re: Question about INTERN Message-ID: <1991Jan30.225106.26561@Think.COM> Date: 30 Jan 91 22:51:06 GMT References: <1991Jan29.055536.1523@magnus.ircc.ohio-state.edu> <5783@idunno.Princeton.EDU> <4037@skye.ed.ac.uk> Sender: news@Think.COM Organization: Thinking Machines Corporation, Cambridge MA, USA Lines: 58 In article <4037@skye.ed.ac.uk> jeff@aiai.UUCP (Jeff Dalton) writes: >In article <5783@idunno.Princeton.EDU> eliot@phoenix.Princeton.EDU (Eliot Handelman) writes: >>The problem is that TYPE-OF doesn't guarantee returning the most specific >>type of an object, so if this used to work and now doesn't it's almost >>certainly because your two TYPE-OF's aren't behaving consistently. > >I agree that this is likely to be the right explanation. However... I disagree, although I don't have any good explanation. After doing (setq my-house any-house), (type-of my-house) and (type-of any-house) should return the same value. TYPE-OF doesn't know what variable was used in the original form, it just sees the object, and it's the same object in both cases. To the original poster: when you post a question about an error you've gotten, it's always a good idea to specify what the error message said. Also, it would be very helpful if you would indent your program properly so that the rest of us don't have a hard time reading it. Also, a few coding style suggestions: it's usually more correct to use (typep ) than (eq (type-of ) ), for the reasons that have been mentioned in previous responses (it's also more concise to use a specialized type-checking predicate such as SYMBOLP when it's available); use EQ or EQL when you know that you don't need the generality of EQUAL (when I read (EQUAL ...) it forces me to think about why EQUAL was used, whereas EQ is a very simple operation); use SETQ rather than SETF when setting variables (again, seeing the more general operator forces the reader to stop and think, although I suspect many people out there would disagree with me on this particular point, and I sometimes wish the Common Lisp designers had had the guts to get rid of SETQ); use SYMBOL-VALUE rather than EVAL when you know that the argument is a symbol (it's usually more (and never less) efficient, and states your intent more clearly -- in general, EVAL should only be used as a last resort); don't use PROG unless you're using the features of at least two of the special forms it combines (LET, BLOCK, and TAGBODY). With all this in mind, here's a suggested rewrite of your functions: (defun get-slot-value (obj slot) "Return the value of the specified slot in obj. Assumes it is a structure whose accessors use the default naming scheme." (when (symbolp obj) (setq obj (symbol-value obj))) (eval `(,(intern (format nil "~a-~a" (type-of obj) slot)) ',obj))) (defun put-slot-value (obj slot value) "Fills in the value of the specified slot in obj. Assumes it is a structure whose accessors use the default naming scheme." (when (symbolp obj) (setq obj (symbol-value obj))) (eval `(setf (,(intern (format nil "~a-~a" (type-of obj) slot)) ',obj) ',value))) -- Barry Margolin, Thinking Machines Corp. barmar@think.com {uunet,harvard}!think!barmar