Thank you very much! It was just the 'intern' that I was missing. I will try and figure out why (make-symbol) makes something different than (intern) and thats also different than just 'symbol, and of cours #'func-symbol. (whew!)
> > I am trying to make a macro which will defun a function whose name is > > constructed from a macro parameter, e.g.
> > (define-struct person (name)) > > --> defuns a function called make-person
> Your choice of names is a little misleading: Common Lisp already > has defstruct, which as one of its effects creates a constructor > function (or was it method? I don't remember offhand) with a > make- -style name, so there is a risk that somebody reading your > code could get mixed up on which function you are talking about.
Thanks, but all that is beside the point in my case-- I'm just trying to figure how the macros work.
> - you could also use backquote to make your macros more readable
gotcha. 6 vs half-dozen.
> - what are you trying to achieve with calling symbol-function? > That returns a function object, normally defun is used with a > symbol as its first parameter.
e.g. if the name passed in is 'balloon, I want the result function to be called make-balloon.
> - intern might be better than make-symbol in this case
This is the solution I am seeking, thanks! (And to Mr. Joswig)
> - you'll also get interesting results with mixed-case names, > remember that CL usually converts symbol names to uppercase when > reading them.
Ok, I'll keep that in mind.
> > Perhaps a related confusion is: What is the difference between 'foo and > > :foo
> I am trying to make a macro which will defun a function whose name is > constructed from a macro parameter, e.g.
> (define-struct person (name)) > --> defuns a function called make-person
Your choice of names is a little misleading: Common Lisp already has defstruct, which as one of its effects creates a constructor function (or was it method? I don't remember offhand) with a make- -style name, so there is a risk that somebody reading your code could get mixed up on which function you are talking about.
- you could also use backquote to make your macros more readable
- what are you trying to achieve with calling symbol-function? That returns a function object, normally defun is used with a symbol as its first parameter.
- intern might be better than make-symbol in this case
- you'll also get interesting results with mixed-case names, remember that CL usually converts symbol names to uppercase when reading them.
> Perhaps a related confusion is: What is the difference between 'foo and > :foo
In article <397E51AB.10D59...@mastnet.net>, John Clonts <jclo...@mastnet.net> wrote:
>Thank you very much! It was just the 'intern' that I was missing. I >will try and figure out why (make-symbol) makes something different than >(intern) and thats also different than just 'symbol, and of cours >#'func-symbol. (whew!)
MAKE-SYMBOL and INTERN both create symbols. The latter also interns the symbol it created; if a symbol isn't interned, you won't be able to access it by typing its name.
#'func-symbol evaluates to the function that FUNC-SYMBOL is bound to. Since DEFUN requires its first parameter to be a function name, not a function object, it makes no sense to put that in the macro expansion.
-- Barry Margolin, bar...@genuity.net Genuity, Burlington, MA *** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups. Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
John Clonts <joh...@my-deja.com> writes: > I am trying to make a macro which will defun a function whose name is > constructed from a macro parameter, e.g.
> (define-struct person (name)) > --> defuns a function called make-person
> But the problem for now is that the (symbol-function ....) expression > result is apparently not suitable for the defun.
Correct in your analysis. Defun wants to have a symbol as the second element of its list. Defun itself takes care of setting the SYMBOL-FUNCTION slot of the symbol, so in normal everyday Common Lisp work you don't actually use this. (Nor SYMBOL-VALUE either). I realize that coming from Scheme having the separate value and function namespaces may be a little more complicated, but it's not as bad as you are making it.
Anyway, you most likely don't want to use MAKE-SYMBOL, since that creates an uninterned symbol. You want to use INTERN instead. The problem with an uninterned symbol is that you can't reference it by name, only by keeping a binding to it. INTERN creates a symbol (if necessary) and stores an association between the symbol name and the symbol object. This association is stored in a data structure called a package (of which there are several in lisp -- see below for an example) so that the reader can map symbol names to symbol objects.
Another issue to be aware of is that the reader normally converts input into uppercase:
(symbol-name 'foo) => "FOO"
but make-symbol and intern do not:
(symbol-name (intern "foo")) => "foo"
so if you concatenate the string "make-" to the symbol name of 'FOO you would end up with a symbol that will most likely print as:
|make-FOO|
which is distinct from the symbol 'make-foo (which is the same as the symbol 'MAKE-FOO). You would then need to reference your created function as:
(|make-FOO| ...)
Of course, if you uppercase the string, then it wouldn't be a problem.
What can also help you in debugging macros is the use of the MACROEXPAND and MACROEXPAND-1 functions, which will show you what the macro expands into. Together with the pretty printer PPRINT, you can see what the system is doing.
BTW, if you want to get serious about writing macros, it would save you lots of effort and frustration to learn the backquote syntax. This allows a much clearer (to me at least) view of what kinds of structures you are creating, since you don't have all those calls to LIST cluttering things up.
Normally the way I write a macro is to start with the end result, namely the form I want to have the macro produce, and then I backquote it and then add commas to the variable parts of the structure. (Then I worry about variable capture and multiple evaluation of arguments and fix those up).
> Perhaps a related confusion is: What is the difference between 'foo and > :foo
Try:
(symbol-package 'foo) (symbol-package :foo)
-- Thomas A. Russ, USC/Information Sciences Institute t...@isi.edu
> To avoid exposing the case-ness of symbols, I prefer (symbol-name 'make-).
One can use it that way - usually I use strings, because I don't want to create arbitrary symbols in a package. For example I'll always write (in-package "FOO") and never (in-package 'foo). I also really *want* to specify the case-ness of a symbol.
* Rainer Joswig <rainer.jos...@ision.net> | One can use it that way - usually I use strings, because I don't | want to create arbitrary symbols in a package.
You can limit the effect to compile-time with #.(symbol-name 'x).
| For example I'll always write (in-package "FOO") and never | (in-package 'foo).
I use (in-package :foo).
| I also really *want* to specify the case-ness of a symbol.
I have a cat, so I know that when she digs her very sharp claws into my chest or stomach it's really a sign of affection, but I don't see any reason for programming languages to show affection with pain.
#:Erik -- If this is not what you expected, please alter your expectations.
> * Rainer Joswig <rainer.jos...@ision.net> > | One can use it that way - usually I use strings, because I don't > | want to create arbitrary symbols in a package.
> You can limit the effect to compile-time with #.(symbol-name 'x).
> | For example I'll always write (in-package "FOO") and never > | (in-package 'foo).
> I use (in-package :foo).
You can get both benefits this way:
(in-package #:foo)
It is tedious, but less tedious than the compile-time symbol-name.
> > * Rainer Joswig <rainer.jos...@ision.net> > > | One can use it that way - usually I use strings, because I don't > > | want to create arbitrary symbols in a package.
> > You can limit the effect to compile-time with #.(symbol-name 'x).
> > | For example I'll always write (in-package "FOO") and never > > | (in-package 'foo).
> > I use (in-package :foo).
> You can get both benefits this way:
> (in-package #:foo)
> It is tedious, but less tedious than the compile-time symbol-name.
(in-package #:foo) has the problem that #:foo does not self-evaluate. The reason people like "FOO" and :FOO is that they are cltl1-compatible.
because it has the benefits of Erik's version and smh's version combined. That is, it both doesn't expose symbol case and it's backward compatible to cltl1 and it gets gc'd quickly.
Heh.
Just kidding.
I rather like (in-package "FOO") because I think it's good for people to be reminded periodically that package names are conventionally uppercase, and also because I like the idea that literal constants stand out from code. But that's probably just because I'm getting old and haven't grown up on full-color text editors to show me distinctions between code and constants.