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.
> 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.
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.
> 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:
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:
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
(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.
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.
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.