suribe wrote:
Now, I'm having a lot of trouble getting it done. The problem is that I can't see a way to access the symbol name (the 'x' in this case) and later use it as a keyword parameter for the make-3d-point function (as ':x').
Is there a way to do something like that?
I tried:
Code: Select all
(intern (concatenate 'string ":" (symbol-name (second '(versor x)))))
|:X|
but I need :X, not |:X|, as in:
And, in a more general sense, am I doing this the right way? Or should I do the 3 function variant? Or something else? Maybe ditch structures, or use them other way?!
OK, taking your points in a sort of backwards order- no, you probably shouldn't be using a macro for this. Macros are very powerful, but there's no real reason to use one here. Those three functions take up six lines. And if you want a shorthand for making unit vectors a normal function will do fine. I'm tempted to wax philosophical here, but that would certainly lead to excess typing on my part, and that wouldn't be in the spirit of your question, so I'll just say that macros should only be used to save typing when you need their unique characteristics toward that end. In this case you can write a normal function named versor that does (almost) exactly what you want this macro to do. You just need some form of conditional- there are a few you could use. Don't use macros where it is just as easy to use normal procedures. The only thing you get from a macro here is the ability to write (versor x) instead of (versor 'x) or (versor :x). Not only is that a frivolous use of macros, I find it a bit jarring... it betrays my expectations.
But, you also raise some other questions, so...
first off, some bits from the repl:
Code: Select all
(intern "x" 'keyword) =>
:|x|
:EXTERNAL
(intern "X" 'keyword) =>
:X
:EXTERNAL
(eq :x (intern "x" 'keyword)) =>
NIL
(eq :x (intern "X" 'keyword)) =>
T
(intern ":X") =>
|:X|
NIL
(intern "X" 'keyword)
:X
:EXTERNAL
(eq :x :X) =>
T
(eq (intern "x" 'keyword) (intern "X" 'keyword)) =>
NIL
(eq (intern ":X") (intern "X" 'keyword)) =>
NIL
(intern ":X" 'keyword)=>
:|:X|
NIL
This is with the defaults for the reader- the results would be different if you played with them a bit. You should read up on the way that the reader deals with case because it would make a long post by itself. CL is _not_ case-insensitive.... Also note that there's a big difference between interning a symbol in the keyword package and interning a symbol that starts with a colon in your current package (or some other package).
Anyway, if some of that is Greek to you, don't feel bad. There are some aspects of CL that are a bit difficult to follow at first. I think the problem here is that you're getting a bit ahead of yourself (and I don't mean to patronize you here- CL is a really big complicated language that takes some time to understand, and on top of that it is very different from most of the languages in common use these days.)
The thing is that there's almost always a simple way to do things in CL, as well as a complicated way. So I'd suggest sticking with the stuff you understand really thoroughly while also reading about things like the keyword package and the reader. You'll find, I think, that CL is as capable a language as most others even without the bells and whistles.
If you have specific questions about any of the stuff above feel free to ask, and I'll be happy to answer them if I can (and if I can't someone else will be able to, I'm sure), or point you at the relevant docs, or both.