From: robbie carlton
Subject: programmatically generating symbols
Date: 
Message-ID: <32b5ef05.0406080357.63da116a@posting.google.com>
Hi. I've written a macro which expands into a function definition, but
I want to be able to construct the name of this function by
concatenating an already existing symbol with a string ("p"). I tried
this (note, it's a method because I want to be able to do it the other
way round as well: string+symbol)

(defmethod conc-sym ((sym symbol) (str string))
    (intern (concatenate 'string (string sym) str)))

however, when I go (conc-sym 'my "func") I get

|MYfunc|

with the pipes. Is there anyway around this/a better way to do the
whole thing?

From: Howard Ding <······@hading.dnsalias.com>
Subject: Re: programmatically generating symbols
Date: 
Message-ID: <m3pt8agsni.fsf@frisell.localdomain>
··············@hotmail.com (robbie carlton) writes:

> Hi. I've written a macro which expands into a function definition, but
> I want to be able to construct the name of this function by
> concatenating an already existing symbol with a string ("p"). I tried
> this (note, it's a method because I want to be able to do it the other
> way round as well: string+symbol)
> 
> (defmethod conc-sym ((sym symbol) (str string))
>     (intern (concatenate 'string (string sym) str)))
> 
> however, when I go (conc-sym 'my "func") I get
> 
> |MYfunc|
> 
> with the pipes. Is there anyway around this/a better way to do the
> whole thing?

What are you trying to work around?  It's doing what you ask it to.
If you want to get the symbol MYFUNC, you could call it with "FUNC" as
the string.  If you always want it to capitalize the string part, use
string-upcase on it.

-- 
Howard Ding
<······@hading.dnsalias.com>
From: robbie carlton
Subject: Re: programmatically generating symbols
Date: 
Message-ID: <32b5ef05.0406080953.17180c00@posting.google.com>
Howard Ding wrote 

> What are you trying to work around?  It's doing what you ask it to.

My problem was the |pipes|, not the CASE. I wanted myfunc, not
|myfunc|. sorry I wasn't clearer.
From: Howard Ding <······@hading.dnsalias.com>
Subject: Re: programmatically generating symbols
Date: 
Message-ID: <m3d649hq39.fsf@frisell.localdomain>
··············@hotmail.com (robbie carlton) writes:

> Howard Ding wrote 
> 
> > What are you trying to work around?  It's doing what you ask it to.
> 
> My problem was the |pipes|, not the CASE. I wanted myfunc, not
> |myfunc|. sorry I wasn't clearer.

You might want to look at section 2.3.6 of the Hyperspec.  To keep
print-read consistency, the printer has to _print_ |MYfunc|, because
reading just myfunc will give the symbol with name "MYFUNC".  However,
|MYfunc| _is_ the symbol you want - the one named "MYfunc".  (Please
forgive the non-precision of this explanation.)

CL-USER> (intern (concatenate 'string (string 'my) "func"))
|MYfunc|
NIL
CL-USER> (symbol-name *)
"MYfunc"
CL-USER> (find-symbol "MYfunc")
|MYfunc|
:INTERNAL
CL-USER> (eq '|MYfunc| 'my\f\u\n\c)
T
CL-USER> (eq '|MYfunc| 'MY\f\u\n\c)
T

and so forth.  It may be that what you are not getting is how the
printer and reader work and how they're supposed to interact.

-- 
Howard Ding
<······@hading.dnsalias.com>
From: Matthew Danish
Subject: Re: programmatically generating symbols
Date: 
Message-ID: <Pine.LNX.4.58-035.0406081408010.3752@unix45.andrew.cmu.edu>
On Tue, 8 Jun 2004, robbie carlton wrote:
> Howard Ding wrote
>
> > What are you trying to work around?  It's doing what you ask it to.
>
> My problem was the |pipes|, not the CASE. I wanted myfunc, not
> |myfunc|. sorry I wasn't clearer.

(read-from-string "myfunc")
(read-from-string "|myfunc|")

Compare the results of these two in the default settings of an *ANSI
COMPLIANT* implementation of Common Lisp.  Then you will know why the
pipes are emitted, and what that has to do with the case of the
characters.
From: Karl A. Krueger
Subject: Re: programmatically generating symbols
Date: 
Message-ID: <ca4vlh$k96$1@baldur.whoi.edu>
robbie carlton <··············@hotmail.com> wrote:
> Howard Ding wrote 
> 
>> What are you trying to work around?  It's doing what you ask it to.
> 
> My problem was the |pipes|, not the CASE. I wanted myfunc, not
> |myfunc|. sorry I wasn't clearer.

You -have- myfunc.  The vertical bars are just a form of quoting.  They
are not part of the symbol's name, no more than the string "foo" starts
and ends with double-quote characters.

> '|myfunc|
|myfunc|
> (symbol-name '|myfunc|)
"myfunc"

-- 
Karl A. Krueger <········@example.edu>
Woods Hole Oceanographic Institution
Email address is spamtrapped.  s/example/whoi/
"Outlook not so good." -- Magic 8-Ball Software Reviews
From: larry
Subject: Re: programmatically generating symbols
Date: 
Message-ID: <7b8f89d6.0406081021.538e9a69@posting.google.com>
······@hading.dnsalias.com (Howard Ding <······@hading.dnsalias.com>) wrote in message news:<··············@frisell.localdomain>...
> ··············@hotmail.com (robbie carlton) writes:
> 
> > Hi. I've written a macro which expands into a function definition, but
> > I want to be able to construct the name of this function by
> > concatenating an already existing symbol with a string ("p"). I tried
> > this (note, it's a method because I want to be able to do it the other
> > way round as well: string+symbol)
> > 
> > (defmethod conc-sym ((sym symbol) (str string))
> >     (intern (concatenate 'string (string sym) str)))
> > 
> > however, when I go (conc-sym 'my "func") I get
> > 
> > |MYfunc|
> > 
> > with the pipes. Is there anyway around this/a better way to do the
> > whole thing?
> 
> What are you trying to work around?  It's doing what you ask it to.
> If you want to get the symbol MYFUNC, you could call it with "FUNC" as
> the string.  If you always want it to capitalize the string part, use
> string-upcase on it.


I think he doesn't want the pipe symbols "|" around the symbol name.
The reason you're getting the pipe symbols is because you have lower
case letters in your symbol name. If you did (conc-sym 'my "FUNC") you
would get

MYFUNC  

without the pipe symbols.
From: Peter Seibel
Subject: Re: programmatically generating symbols
Date: 
Message-ID: <m31xkqytyq.fsf@javamonkey.com>
··············@hotmail.com (robbie carlton) writes:

> Hi. I've written a macro which expands into a function definition, but
> I want to be able to construct the name of this function by
> concatenating an already existing symbol with a string ("p"). I tried
> this (note, it's a method because I want to be able to do it the other
> way round as well: string+symbol)
>
> (defmethod conc-sym ((sym symbol) (str string))
>     (intern (concatenate 'string (string sym) str)))
>
> however, when I go (conc-sym 'my "func") I get
>
> |MYfunc|
>
> with the pipes. Is there anyway around this/a better way to do the
> whole thing?

A couple thoughts. Your problem, as others have pointed out, is that
if you want an all uppercase symbol name (like you'd get from the
reader in the default readtable settings) you want to upcase the
string part. You could avoid having to write separate methods for
string+symbol and symbol+string by writing something like this:

  (defun conc-sym (a b)
    (intern (format nil ··@:(~a~a~)" a b)))

However there's still a tricky bit about this kind of symbol
creation--what package is the symbol created in? As you used it,
INTERN will use the current value of *PACKAGE*. But that can lead to
the new symbol being in a different package than the symbol argument
which may or may not be what you want.

-Peter


-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Pascal Costanza
Subject: Re: programmatically generating symbols
Date: 
Message-ID: <ca4m9l$rda$1@f1node01.rhrz.uni-bonn.de>
robbie carlton wrote:

> Hi. I've written a macro which expands into a function definition, but
> I want to be able to construct the name of this function by
> concatenating an already existing symbol with a string ("p"). I tried
> this (note, it's a method because I want to be able to do it the other
> way round as well: string+symbol)
> 
> (defmethod conc-sym ((sym symbol) (str string))
>     (intern (concatenate 'string (string sym) str)))
> 
> however, when I go (conc-sym 'my "func") I get
> 
> |MYfunc|
> 
> with the pipes. Is there anyway around this/a better way to do the
> whole thing?

By default, Common Lisp uses uppercase letters for symbol names 
internally. So when you type in symbol names with lower (or mixed) case 
letters they get converted to upper case before being interned. When 
they are printed they may be converted to lower case again, according to 
the value of *print-case*.

On the other hand, when you programmatically create symbols (intern, 
make-symbol, gensym, gentemp) with explicit strings the case of the 
letters in the given string is preserved. The pipes occur in the output 
in order to indicate that the case of the letters in the symbol is 
exactly as printed. So, for example some-package::|symbol| may represent 
a different symbol than some-package::symbol. (You can also use the 
pipes for typing in symbols.)

The fact that upper case letters are used internally might seem strange, 
and is AFAICS just a historical accident. However, it doesn't really 
matter much because this only hits you when you want to fiddle with 
internals.

As a meta-comment, the need to fiddle with internals is a "bad smell". 
It might be a better idea to let the user of your macro define the name 
of the function that's about to be generated. This requires the user of 
your macro to type more, but lowers the risk of surprises, for example 
because of potential accidental name clashes.


Pascal

-- 
ECOOP 2004 Workshops - Oslo, Norway
*1st European Lisp and Scheme Workshop, June 13*
http://www.cs.uni-bonn.de/~costanza/lisp-ecoop/
*2nd Post-Java Workshop, June 14*
http://prog.vub.ac.be/~wdmeuter/PostJava04/
From: Marco Baringer
Subject: Re: programmatically generating symbols
Date: 
Message-ID: <m2pt89vrgf.fsf@convey.it>
Pascal Costanza <········@web.de> writes:

> As a meta-comment, the need to fiddle with internals is a "bad
> smell". It might be a better idea to let the user of your macro define
> the name of the function that's about to be generated. This requires
> the user of your macro to type more, but lowers the risk of surprises,
> for example because of potential accidental name clashes.

since you brough it up :). I have a macro called defclass-struct which
expands to a defclass but has defstruct's syntax (and in particular
takes the :conc-name and :predicate arguments). Something like this:

(defclass-struct (foo (:conc-name foo.)) ()
  a)

Should define an acessor called FOO.A, my question is, what package
should FOO.A be in. I have basically three options:

1) the symbol-package of FOO (the class name)

2) the symbol-package of FOO. (the conc name)

3) the symbol-package of A. (the accessor)

4) the value of *package* at macro expansion time.

What would surprise people the least? I could settle for just emitting
a warning when something "weird" happens, like when FOO. and FOO.A
would be in different packages.

NB: I do not want to get into a debate over whether defclass-struct is
a good idea or not.

-- 
-Marco
Ring the bells that still can ring.
Forget your perfect offering.
There is a crack in everything.
That's how the light gets in.
     -Leonard Cohen
From: robbie carlton
Subject: Re: programmatically generating symbols
Date: 
Message-ID: <32b5ef05.0406081432.2d197d43@posting.google.com>
Marco Baringer <··@bese.it> wrote in message news:<··············@convey.it>...
> Pascal Costanza <········@web.de> writes

terribly sorry everyone. I've just gone and checked, and you're right.
My problem isn't with the pipes. I'm actually trying to do almost the
exact thing that Marco Baringer has

>I have a macro called defclass-struct which
>expands to a defclass but has defstruct's syntax 

except I didn't think to give the user the chance to specify a
predicate. (This is purely an exercise. I know this kind of thing is
already out there). So, my real problem comes here:

(defmacro def-predicate (funcname)
    `(defun ,(intern (concatenate 'string (string funcname) "p")) ()
        (
         ...))) 

when I try to use this macro, it returns the symbol I'm looking for
(funcname+p), but when I try to call the function, I get an "unbound"
error. Is this because the definition is local to the macro? I didn't
think they worked that way. How would I achieve what I'm trying to
achieve (defining a function in a macro)? I saw Thomas Schilling wrote
>(defun make-function (class-name ...)
>   "Return the definition of the make-* function for class-name"
>   `(defun ,(intern (concatenate 'string "MAKE-"
>                                 (symbol-name class-name)))
>       ...)

but I don't understand how this would work. When would the definition
get evaluated? Would you have to expilictly compile/eval? I thought
that was naughty.
From: Peter Seibel
Subject: Re: programmatically generating symbols
Date: 
Message-ID: <m3aczdy5yc.fsf@javamonkey.com>
··············@hotmail.com (robbie carlton) writes:

> So, my real problem comes here:
>
> (defmacro def-predicate (funcname)
>     `(defun ,(intern (concatenate 'string (string funcname) "p")) ()
>         (
>          ...))) 
>
> when I try to use this macro, it returns the symbol I'm looking for
> (funcname+p), but when I try to call the function, I get an "unbound"
> error. Is this because the definition is local to the macro?

No. The problem is that you've created a function with a name like:
|FOOp| where again the pipes are just "quotation" marks to show that
the case is exactly as shown, i.e. uppercase "FOO" lowercase "p". But
you're calling it like:

  (foop whatever)

and the Lisp reader (still being set to the default readtable-case) is
reading the "foop" as |FOOP|, i.e. all uppercase. Since symbols are
case sensitive you are indeed calling a function that doesn't exist as
the error message is telling you.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: robbie carlton
Subject: Re: programmatically generating symbols
Date: 
Message-ID: <32b5ef05.0406090100.1252e8fe@posting.google.com>
Hooray! It works. I had got it into my head that case didn't matter in
CL, so I could not work out what was wrong. I capitalised the P, and
now it works. Cheers everyone.
From: Thomas Schilling
Subject: Re: programmatically generating symbols
Date: 
Message-ID: <opr9bdk9httrs3c0@news.CIS.DFN.DE>
robbie carlton wrote:
  achieve (defining a function in a macro)? I saw Thomas Schilling wrote
>> (defun make-function (class-name ...)
>>   "Return the definition of the make-* function for class-name"
>>   `(defun ,(intern (concatenate 'string "MAKE-"
>>                                 (symbol-name class-name)))
>>       ...)
>
> but I don't understand how this would work. When would the definition
> get evaluated? Would you have to expilictly compile/eval? I thought
> that was naughty.

Oh, that's simple: I just call the function inside my macro :)

(defmacro define-my-class (name ...)
   ...
   `(locally
      (defclass ,name ...)
     ,(make-function name ...)))

So it simply inserts the definition into the macro and is thus evaluated 
with the macro. (Just some refactoring ;)

-ts
-- 
      ,,
     \../   /  <<< The LISP Effect
    |_\\ _==__
__ | |bb|   | _________________________________________________
From: Thomas Schilling
Subject: Re: programmatically generating symbols
Date: 
Message-ID: <opr9ag9nuitrs3c0@news.CIS.DFN.DE>
Marco Baringer <··@bese.it> wrote:

> (defclass-struct (foo (:conc-name foo.)) ()
>   a)
>
> Should define an acessor called FOO.A, my question is, what package
> should FOO.A be in. I have basically three options:
>
> 1) the symbol-package of FOO (the class name)
>
> 2) the symbol-package of FOO. (the conc name)
>
> 3) the symbol-package of A. (the accessor)
>
> 4) the value of *package* at macro expansion time.
>
> What would surprise people the least? I could settle for just emitting
> a warning when something "weird" happens, like when FOO. and FOO.A
> would be in different packages.

I've just written a macro to resemble a foreign class system with clos. I 
(for now) chose the simple case (4). i.e.:

(defun make-function (class-name ...)
   "Return the definition of the make-* function for class-name"
   `(defun ,(intern (concatenate 'string "MAKE-"
                                 (symbol-name class-name)))
       ...)

So it uses *package*, cause I think the utility functions should be in the 
same package as the class. (BTW, isn't 1-4 the same in most cases?)

If anyone has other arguments I'd like to know them.

-ts
-- 
      ,,
     \../   /  <<< The LISP Effect
    |_\\ _==__
__ | |bb|   | _________________________________________________
From: Pascal Costanza
Subject: Re: programmatically generating symbols
Date: 
Message-ID: <ca53bh$2eg$1@newsreader2.netcologne.de>
Marco Baringer wrote:
> since you brough it up :). I have a macro called defclass-struct which
> expands to a defclass but has defstruct's syntax (and in particular
> takes the :conc-name and :predicate arguments). Something like this:
> 
> (defclass-struct (foo (:conc-name foo.)) ()
>   a)
> 
> Should define an acessor called FOO.A, my question is, what package
> should FOO.A be in. I have basically three options:
> 
> 1) the symbol-package of FOO (the class name)
> 
> 2) the symbol-package of FOO. (the conc name)
> 
> 3) the symbol-package of A. (the accessor)
> 
> 4) the value of *package* at macro expansion time.
> 
> What would surprise people the least? I could settle for just emitting
> a warning when something "weird" happens, like when FOO. and FOO.A
> would be in different packages.

I think it would be least surprising if the macro behaves the same as 
defstruct does - at least, this would best fit with the idea to use 
defclass-struct during development and then switch to defstruct for 
deployment. This would mean option 4. However, warnings for corner cases 
are probably a good idea.


Pascal

-- 
1st European Lisp and Scheme Workshop
June 13 - Oslo, Norway - co-located with ECOOP 2004
http://www.cs.uni-bonn.de/~costanza/lisp-ecoop/
From: Marco Antoniotti
Subject: Re: programmatically generating symbols
Date: 
Message-ID: <PyFxc.8$2i5.5436@typhoon.nyu.edu>
What better time to point all of you to the DEFINER project in 
common-lisp.net? :)

Cheers

marco




Marco Baringer wrote:
> Pascal Costanza <········@web.de> writes:
> 
> 
>>As a meta-comment, the need to fiddle with internals is a "bad
>>smell". It might be a better idea to let the user of your macro define
>>the name of the function that's about to be generated. This requires
>>the user of your macro to type more, but lowers the risk of surprises,
>>for example because of potential accidental name clashes.
> 
> 
> since you brough it up :). I have a macro called defclass-struct which
> expands to a defclass but has defstruct's syntax (and in particular
> takes the :conc-name and :predicate arguments). Something like this:
> 
> (defclass-struct (foo (:conc-name foo.)) ()
>   a)
> 
> Should define an acessor called FOO.A, my question is, what package
> should FOO.A be in. I have basically three options:
> 
> 1) the symbol-package of FOO (the class name)
> 
> 2) the symbol-package of FOO. (the conc name)
> 
> 3) the symbol-package of A. (the accessor)
> 
> 4) the value of *package* at macro expansion time.
> 
> What would surprise people the least? I could settle for just emitting
> a warning when something "weird" happens, like when FOO. and FOO.A
> would be in different packages.
> 
> NB: I do not want to get into a debate over whether defclass-struct is
> a good idea or not.
> 
From: Thomas A. Russ
Subject: Re: programmatically generating symbols
Date: 
Message-ID: <ymin039rhir.fsf@sevak.isi.edu>
··············@hotmail.com (robbie carlton) writes:

> 
> Hi. I've written a macro which expands into a function definition, but
> I want to be able to construct the name of this function by
> concatenating an already existing symbol with a string ("p"). I tried
> this (note, it's a method because I want to be able to do it the other
> way round as well: string+symbol)
> 
> (defmethod conc-sym ((sym symbol) (str string))
>     (intern (concatenate 'string (string sym) str)))

A more direct way to handle both types of arguments in arbitrary
combinations takes advantage of the fact that the STRING function
applied to a string argument just returns the string:

(defun conc-sym (a b)
   (intern (concatenate 'string (string a) (string b))))

But, then again, why stop at two arguments?  You could easily write

(defun conc-sym (&rest args)
  (intern (apply #'concatenate 'string (mapcar #'string args))))

and handle an arbitrary number.

-- 
Thomas A. Russ,  USC/Information Sciences Institute