tags:

views:

72

answers:

3

i have a simple clojure syntax problem (bc i am new to the language). for both examples i have a list lst of (1 2 3 4):

in Lisp i can write:

=>`(first of list is ,(first lst))
(first of list is 1)

in Clojure, if i write the same thing (with the language translation of , to ~ as i THOUGHT i read somewhere) i get:

=>'(first of list is ~(first lst))
(first of list is (clojure.core/unquote (first lst)))

i was hoping i can do what i want to in Clojure as well, and that i just have the syntax wrong. all the examples i find though have functions first and use a ` (backtick). i dont want to call a function like:

`(my-function ~(first lst))

i just want to return '(some list with ,(first lst) replaced in it)

can i do such a thing in Clojure?

EDIT: i gave a poor example seeing as my ACTUAL problem dealt with strings. let me try another example...

=>(def color-lst '(red green blue))

what i wanted to return was:

=>`(the color i want is ~(first color-lst))

this yeilded all the strange returns i saw. the other way to do this is

=>(format "the color i want is %s" (first color-lst))

this is how i solved my problem.

+2  A: 

It's slightly unclear to me what you mean by "first of list is" in your code:

'(first of list is ,(first lst))

But if you meant by that just a placeholder for the beginning of the list, then the following should work fine (make sure to use backtick!):

`(1 2 3 ~(first [1 2]))
=> (1 2 3 1)

Alternatively, using quote will result in the following (which seems to be your problem):

'(1 2 3 ~(first [1 2]))
=> (1 2 3 (clojure.core/unquote (first [1 2]))) 
unignorant
ok, now im getting somewhere. that DOES work (just tried it). "first of list is" is just a sentence in my above code. so perhaps i am going about this the wrong way? when the backtick list contains numbers it works, but not when it contains words. i think the problem may be that '(this is a list) and `(this is a list) evaluate to the same thing in Lisp... but NOT in Clojure. could this be it?
Toddeman
it seems that the problem you are having is using quote (') rather than backtick (`). Backtick should work the same way with a list of strings.
unignorant
evaluating '(this is a list) yeilds (this is a list) as id expect. evaluating `(this is a list) yeilds (user/this user/is user/a clojure.core/list) which is not what i expected, but thats bc im not using the lang correctly :(
Toddeman
ok, in '(this is a list) clojure is treating the elements of that list as variables, not strings. The difference between quote and backtick is that backtick namespaces everything to the current namespace, whereas quote does not. That's why you see "clojure.core/list" in one, and just "list" in the other. Try changing the current namespace (eg. (ns my-namespace)) and you'll see "my-namespace/list" returned by backtick instead.
unignorant
thanks unignorant, your original statement was what led me to my solution
Toddeman
A: 

found another way. perhaps the whole time i was just not doing things the 'Clojure' way?

(formate "first of list is %d" (first lst)) yeilds what i was looking for.

i think it was partly my fault in the problem description, i gave a bad example. it seems the problem arose bc i was using strings (possibly improperly?) in the list. that and 'first' is also an acceptable function call. all of that confused the issue i believe.

Toddeman
i think the confusion was actually that you were *not* using strings in the original example list ;-)
unignorant
+4  A: 

Even if your problem is solved, there are some fundamental differences between CL and Clojure worth mentioning:

The main difference concerning symbols in backquotes between CL and Clojure is, that Clojure resolves quasiquoted symbols; yielding a namespace qualified symbol (take a look at the reader section of the Clojure docs):

user> `foo
user/foo

So, in CL:

CL-USER> (let ((list '(foo bar baz)))
            `(first is ,(first list)))
(FIRST IS FOO)

But in Clojure:

user> (let [lst '(foo bar baz)]
        `(first is ~(first lst)))
(clojure.core/first user/is foo)

In order to get a non-qualified symbol in Clojure (within backquotes), you'd have to use something like this:

user> `~'foo
foo

So, to get the same result as the CL version (ignoring readtable-case), you'd have to use:

user> (let [lst '(foo bar baz)]
        `(~'first ~'is ~(first lst)))
(first is foo)
danlei
hey, thats exactly it! ive moved on to another problem since then, but i think i will go back now and replace with this. this is exactly what i was looking for, i just couldnt reason out the correct quote/backtick/tilde combination. thank you.
Toddeman
You're welcome. Since symbols aren't first-class citizens in most programming languages learned/used nowadays, they're a concept one has to grow accustomed to.
danlei