From: Tamas K Papp
Subject: keyword to symbol in package
Date: 
Message-ID: <6gln7aFgcbpjU1@mid.individual.net>
Hi,

I have a function that replaces a given slots of an instance with given 
values.  The slot-value pairs are in a flat list, eg

(modify-style style :a 2 :b 3)

will replace style's slot a with 2, slot b with 3.  I am using keywords 
because this function will be exported from a package.  To make a slot 
name interned in the package from keywords, I am using 

(find-symbol (symbol-name slot) :cl-2d)

as in

(defun modify-style (style &rest slot-value-pairs)
  (iter
    (for s-v-pair :on slot-value-pairs :by #'cddr)
    (for (slot value) := s-v-pair)
    (for slot-in-package := (find-symbol (symbol-name slot) :cl-2d))
    (unless slot-in-package
      (error "~a is not a valid symbol in cl-2d" slot))
    (unless value
      (error "you did not specify a value for ~a" slot))
    (setf (slot-value style slot-in-package) value))
  style)

The question is: is this the way to do this?  Or is it possible to get 
the symbol cl-2d:foo from :foo without converting to a string first?

Thanks,

Tamas

From: Marco Antoniotti
Subject: Re: keyword to symbol in package
Date: 
Message-ID: <a34e2100-5482-49e8-9a51-b2629b3d9418@k13g2000hse.googlegroups.com>
On Aug 15, 11:55 am, Tamas K Papp <······@gmail.com> wrote:
> Hi,
>
> I have a function that replaces a given slots of an instance with given
> values.  The slot-value pairs are in a flat list, eg
>
> (modify-style style :a 2 :b 3)
>
> will replace style's slot a with 2, slot b with 3.  I am using keywords
> because this function will be exported from a package.  To make a slot
> name interned in the package from keywords, I am using
>
> (find-symbol (symbol-name slot) :cl-2d)
>
> as in
>
> (defun modify-style (style &rest slot-value-pairs)
>   (iter
>     (for s-v-pair :on slot-value-pairs :by #'cddr)
>     (for (slot value) := s-v-pair)
>     (for slot-in-package := (find-symbol (symbol-name slot) :cl-2d))
>     (unless slot-in-package
>       (error "~a is not a valid symbol in cl-2d" slot))
>     (unless value
>       (error "you did not specify a value for ~a" slot))
>     (setf (slot-value style slot-in-package) value))
>   style)
>
> The question is: is this the way to do this?  Or is it possible to get
> the symbol cl-2d:foo from :foo without converting to a string first?

Looks ok to me.  You are not "converting to a string" BTW.  You are
just accessing the symbol name.  Note that, as you wrote it, the
function would also work as

     (modify-style style 'cl-2d:a 42)

The only extra test I'd do would be to check that the slot name were
really external in the package.  FIND-SYMBOL gives you that
information.

Cheers
--
Marco
From: Tamas K Papp
Subject: Re: keyword to symbol in package
Date: 
Message-ID: <6glr7nFgcbpjU2@mid.individual.net>
On Fri, 15 Aug 2008 09:43:10 -0700, Marco Antoniotti wrote:

> On Aug 15, 11:55 am, Tamas K Papp <······@gmail.com> wrote:
>> Hi,
>>
>> I have a function that replaces a given slots of an instance with given
>> values.  The slot-value pairs are in a flat list, eg
>>
>> (modify-style style :a 2 :b 3)
>>
>> will replace style's slot a with 2, slot b with 3.  I am using keywords
>> because this function will be exported from a package.  To make a slot
>> name interned in the package from keywords, I am using
>>
>> (find-symbol (symbol-name slot) :cl-2d)
>>
>> as in
>>
>> (defun modify-style (style &rest slot-value-pairs)
>>   (iter
>>     (for s-v-pair :on slot-value-pairs :by #'cddr) (for (slot value)
>>     := s-v-pair)
>>     (for slot-in-package := (find-symbol (symbol-name slot) :cl-2d))
>>     (unless slot-in-package
>>       (error "~a is not a valid symbol in cl-2d" slot))
>>     (unless value
>>       (error "you did not specify a value for ~a" slot))
>>     (setf (slot-value style slot-in-package) value))
>>   style)
>>
>> The question is: is this the way to do this?  Or is it possible to get
>> the symbol cl-2d:foo from :foo without converting to a string first?
> 
> Looks ok to me.  You are not "converting to a string" BTW.  You are just
> accessing the symbol name.  Note that, as you wrote it, the function
> would also work as
> 
>      (modify-style style 'cl-2d:a 42)
> 
> The only extra test I'd do would be to check that the slot name were
> really external in the package.  FIND-SYMBOL gives you that information.

Thanks Marco.  But I thought symbol-name returned a string, so a string 
must be involved somewhere.  This somehow seems inelegant, but maybe I 
need to adjust my thinking.

Tamas
From: Barry Margolin
Subject: Re: keyword to symbol in package
Date: 
Message-ID: <barmar-5AA537.22205215082008@newsgroups.comcast.net>
In article <··············@mid.individual.net>,
 Tamas K Papp <······@gmail.com> wrote:

> Thanks Marco.  But I thought symbol-name returned a string, so a string 
> must be involved somewhere.  This somehow seems inelegant, but maybe I 
> need to adjust my thinking.

Yes, it returns a string.  But it doesn't have to create a new string to 
do it.  A symbol is likely to be implemented internally something like:

(defstruct symbol
  name
  value
  function
  plist
  package)

and SYMBOL-NAME simply reads what's in the NAME slot.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Rob Warnock
Subject: Re: keyword to symbol in package
Date: 
Message-ID: <9q-dnZqCUpACJTvVnZ2dnUVZ_qjinZ2d@speakeasy.net>
Barry Margolin  <······@alum.mit.edu> wrote:
+---------------
|  Tamas K Papp <······@gmail.com> wrote:
| > Thanks Marco.  But I thought symbol-name returned a string,
| > so a string  must be involved somewhere.  ...
| 
| Yes, it returns a string.  But it doesn't have to create a new string to 
| do it.  A symbol is likely to be implemented internally something like:
|   (defstruct symbol name value function plist package)
| and SYMBOL-NAME simply reads what's in the NAME slot.
+---------------

Yup, hence this word of warning from the CLHS:

    Function SYMBOL-NAME
    Syntax:
    symbol-name SYMBOL => NAME
    ...
    SYMBOL-NAME returns the NAME of SYMBOL.
    The consequences are undefined if NAME is ever modified.
    ...

Why is this restiction there? Probably because [in almost every
conceivable Common Lisp implementation] the symbol name is used
as a key in the internal hash table implementing its home package,
and the CLHS has a similar caveat about hash table keys:

    18.1.2 Modifying Hash Table Keys
    ...
    If an object O1 is used as a key in a hash table H and is then
    visibly modified with regard to the equivalence test of H, then
    the consequences are unspecified if O1, or any object O2 equivalent
    to O1 under the equivalence test (either before or after the
    modification), is used as a key in further operations on H.
    The consequences of using O1 as a key are unspecified even if
    O1 is visibly modified and then later modified again in such
    a way as to undo the visible modification.
    ...

So be careful not to modify the result of SYMBOL-NAME or pass it to
any functions that *might* modify it, or "undefined/unspecified
consequences" might ensue.

[Cue Kenny to list some examples of "the consequences are undefined"...]


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Michael Weber
Subject: Re: keyword to symbol in package
Date: 
Message-ID: <105fd720-c9f7-4a04-91e5-15b78b9737db@a70g2000hsh.googlegroups.com>
On Aug 15, 5:55 pm, Tamas K Papp <······@gmail.com> wrote:
> Hi,
>
> I have a function that replaces a given slots of an instance with given
> values.  The slot-value pairs are in a flat list, eg
>
> (modify-style style :a 2 :b 3)
>
> will replace style's slot a with 2, slot b with 3.  I am using keywords
> because this function will be exported from a package.  
[...]
> The question is: is this the way to do this?  Or is it possible to get
> the symbol cl-2d:foo from :foo without converting to a string first?

Is there a reason not to use

(defun modify-style (style &rest initargs)
  (apply #'reinitialize-instance style initargs))

You would have to document the use of REINITIALIZE-INSTANCE