Archived

This topic is now archived and is closed to further replies.

Brobanx

Calling all Common Lisp experts...

Recommended Posts

Brobanx    136
Is there any way to turn a string into a symbol? What I want to be able to do is make a macro where I can write (mymacro foobar), and the macro will create a variable called "prefix-foobar". I''ve tried doing weird stuff like (defmacro mymacro (x) (setq `(make-symbol (+ "prefix-" (symbol-name ,x))) 0)) to no avail.

Share this post


Link to post
Share on other sites
Nekhmet    132

Short answer: (intern "string")

Long answer: common lisp contains a hash table mapping strings to the equivalent symbols. The "intern" function looks inside a the hash table for the specified symbol, and if it doesn''t find it, it creates a new symbol. The result is that the first time you call "intern" with a given string, it creates a new symbol. The second time, it simply returns the symbol you created the first time. You can also have symbols which are "uninterned." An uninterned symbol is one which is not indexed in the hash table. Since it is not indexed, you cannot look it up by name. This has interesting consequences. Let''s say you type some commands at the prompt:

> (setq x (make-symbol "foo"))
--> puts an uninterned symbol into the variable x.
> (setq y ''foo)
--> you typed the string "(setq y ''foo)". The command-line parser tries to parse this string. In the process of parsing, it calls (intern "foo"). The intern function tries to find "foo" in the hash-table, but it finds nothing, because make-symbol didn''t put the symbol it created into the hash-table. When intern doesn''t find the symbol, it creates one. So in this example, intern creates a second symbol, also named "foo". This second symbol is in the hash table. The net result: x contains an uninterned symbol named "foo", y contains an interned symbol named "foo".

If you want to know more about this, read up on packages.

- Josh


Share this post


Link to post
Share on other sites
Brobanx    136
Ok, let''s say I have a string ("foobar"), and I want a variable of that name to use in my program... I cannot get this to work at all.

(setq (intern "foobar") 0)

for instance... it doesn''t create a variable foobar with a value 0, it says "(intern "foobar") is not a symbol."

I want it to be able to interpret it as a symbol, so I can manipulate strings and get variable / function names accordingly, so I can have macros that declare functions and variables for me... a lot like how defstruct makes the make- style functions.

Share this post


Link to post
Share on other sites
SiCrane    11839
Your use of setq in a macro probably justifies the use of ` and , so that the macro expands properly. As in
(defmacro mymacro (var) `(setq ,(intern var) 0))

However, intern may not return the symbol that you expect. (intern "foobar") may not be the same as the symbol FOOBAR. Perhaps you want to give read-from-string a whirl?

(defmacro mymacro (var) `(setq ,(values (read-from-string var)) 0))

Share this post


Link to post
Share on other sites
Nekhmet    132

In C, you can say:

foo=5;

but you can''t say:

intern("foo") = 5;

that''s just not legal C syntax. Lisp has a similar rule:

(setq foo 5)

is legal

(setq (intern "foo") 5)

is just not legal lisp syntax. In C, you can put a variable to the left of the equal sign. You can''t put a function call to the left of an equal sign. In Lisp, you can put a variable name in the second place of setq. You can''t put a function call in the second place.

Bigger picture. Try this macro, and go from there:

(defmacro setq-prefix (x y)
`(setq ,(intern (+ "PREFIX-" (symbol-name x))) ,y))

(setq-prefix foo 5) -> macroexpands to (setq prefix-foo 5)
(setq-prefix bar 3) -> macroexpands to (setq prefix-bar 3)



Share this post


Link to post
Share on other sites
Brobanx    136
Thanks for the helpful replies everyone! It turns out I needed to use read-from-string to get this to work properly... So the code I was looking for was

(defmacro mymacro (x) `(setq ,(read-from-string (string-concat "prefix-" (symbol-name x))) 0))

Share this post


Link to post
Share on other sites