Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uwm.edu!zaphod.mps.ohio-state.edu!think.com!barmar From: barmar@think.com (Barry Margolin) Newsgroups: comp.lang.lisp Subject: Re: Question about INTERN Message-ID: <1991Jan31.174839.20943@Think.COM> Date: 31 Jan 91 17:48:39 GMT References: <4037@skye.ed.ac.uk> <1991Jan30.225106.26561@Think.COM> Sender: news@Think.COM Organization: Thinking Machines Corporation, Cambridge MA, USA Lines: 65 In article alms@cambridge.apple.com (Andrew L. M. Shalit) writes: >In article <1991Jan30.225106.26561@Think.COM> barmar@think.com (Barry Margolin) writes: >Two more suggestions: replace FORMAT with CONCATENATE. This will >ensure that you don't get screwed by *print-case*. Good point. I've never really liked Common Lisp's CONCATENATE (my guess is that 95% of the sequences that are concatenated are lists (which already have APPEND) and strings (in my Symbolics-specific code I prefer STRING-APPEND)). Also, in this case it is clumsy because of the need to use SYMBOL-NAME to convert the symbol to a string. > Also, you can >replace the EVAL with a FUNCALL (going by your "smaller hammer for a >smaller job" theory). You're right for the GET-SLOT-VALUE case, but unfortunately not SET-SLOT-VALUE (I realize you weren't talking about this case, I'm just amplifying). In this case, there's some enhanced readability from implementing both GET and SET in similar fashion. > It might also be a good idea to pass a package >argument to INTERN. All these together give us: > > > (defun get-slot-value (obj slot) > (when (symbolp obj) > (setq obj (symbol-value obj))) > (funcall (intern (concatenate 'string > (string (type-of obj)) > "-" > (string slot)) > (symbol-package slot)) ;just a guess! > obj)) I actually considered supplying the package argument. Unfortunately, there really is no *right* way to do this, which is why it's usually wrong to try to construct function names using INTERN at runtime. The package of the slot argument to {GET,SET}-SLOT-VALUE is not necessarily the package that the structure was defined in, especially when inheritance is involved. Consider: (defstruct personal-inventory car house) (setq my-inv (make-personal-inventory :car :oldsmobile :house :condo)) (get-slot-value my-inv 'car) Error: Undefined function LISP::PERSONAL-INVENTORY-CAR or on a Symbolics Error: Attempt to intern BARMAR in locked package COMMON-LISP. This is because CAR is inherited from the LISP package. It would probably be safer to use (symbol-package (type-of obj)), but that can also have similar problems (although not involving the LISP package, if the program obeys the rules against redefining built-in Common Lisp symbols, as described on p.260 of CLtL2). -- Barry Margolin, Thinking Machines Corp. barmar@think.com {uunet,harvard}!think!barmar