Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what does ~' imply when added as a prefix to a variable in macro

Tags:

clojure

Given the macro below -

(defmacro defhello [fn-name body]   `(defn ~fn-name [~'name] ~body))

and a function defined when called as -

(defhello greeting (str "Hello" name))

and called as

(greeting "Joe")

, will return

Hello Joe

I do not understand the usage of ~' in front of the name parameter? What does it do? Don't quote (') and unquote (~) cancel each other? What happens when they are used together? Why not just write name without them?

like image 944
murtaza52 Avatar asked Sep 10 '12 12:09

murtaza52


2 Answers

In short, the ~ evaluates the expression in the syntax-quoted form just like it does for ~fn-name. In this case, the expression to evaluate is 'name, in which the result is the unqualified symbol name.

However, lets break this down one piece at a time.

If you only had the unqualified symbol name, it would be evaluated to clojure.core/name at runtime1. This would result in an incorrect defn form and cause a compiler exception.

(defn greeting [clojure.core/name] (str "Hello" name)) 

If you only had the quoted unqualified symbol 'name, it would still be evaluated at runtime. The difference is that it would expand to (quote clojure.core/name). Again, this would result in an incorrect defn form and cause a compiler exception.

(defn greeting [(quote clojure.core/name)] (str "Hello" name))

Finally, by using ~'name, you will have the quoted form evaluated at compile-time, resulting in the unqualified symbol name, leaving you with a proper defn form.

(defn greeting [name] (str "Hello" name))

1 - This is true for this example because it assumes another name function does not exist.

like image 118
Jeremy Avatar answered Sep 23 '22 06:09

Jeremy


As I understand it, you quote the function definition, so it will not be evaluated when the macro is defined. You use the unquote operator ~, to evaluate name in the definition. If name were a kind of list ~@ (unquote splice) would evaluate the elements of a list without the surrounding brackets.

like image 25
octopusgrabbus Avatar answered Sep 23 '22 06:09

octopusgrabbus