murtaza52
murtaza52

Reputation: 47441

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

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?

Upvotes: 11

Views: 263

Answers (3)

Jeremy
Jeremy

Reputation: 22415

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.

Upvotes: 10

gombiuda
gombiuda

Reputation: 54

The quote before name is used to keep the symbol from qualifying.

If you don't know what is qualifying, please refer to Reader.

In addition, you can use macroexpand for macro debugging.

And if you want to know more about macros, I recommend you to read On Lisp. Maybe it's a little difficult, but that let you know how macro works.

Upvotes: 1

octopusgrabbus
octopusgrabbus

Reputation: 10685

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.

Upvotes: 2

Related Questions