1

A function to add one and one:

(defn one-plus-one [] (list + 1 1))

when called returns:

(#object[clojure.core$_PLUS_ 0x47fa7bd5 "clojure.core$_PLUS_@47fa7bd5"] 1 1)

The same function body wrapped in a macro:

(defmacro one-plus-one [] (list + 1 1))

when called returns:

2

Why does Clojure expect macros to return expressions that can be evaluated?

Edit

The answers to the possible duplicate question tells how a macro is different from a function. But does not answer the why. Metaphorically, I know that an object left from an altitude drops vertically to hit the ground. My question is why does it drop vertically?

Community
  • 1
  • 1
ardsrk
  • 2,407
  • 2
  • 21
  • 33
  • 4
    Possible duplicate of [What is the difference between the defn and defmacro?](http://stackoverflow.com/questions/3667403/what-is-the-difference-between-the-defn-and-defmacro) – Brad Koch Jul 06 '16 at 14:16
  • 4
    you should read more about macros i guess. You can think of macro call as a code that replaces itself with macro's content at compilation. So for macro one-plus-one you imagine that `(one-plus-one)` puts `(+ 1 1)` into your source code, and then it is evaluated together the rest of the source code. – leetwinski Jul 06 '16 at 15:05
  • 1
    Re the edit, and quoting from the [linked question](http://stackoverflow.com/a/3672068/425313), functions transform values, and macros transform code into other code. – Brad Koch Jul 06 '16 at 15:19
  • 1
    Your function example is just returning a list construct, which is what you defined it to do. Your macro expands to the code `(+ 1 1)`, and when that code is evaluated the result is 2. You can see the intermediate by running `(macroexpand '(one-plus-one))`. – Brad Koch Jul 06 '16 at 15:21
  • 1
    Regarding your edit: what exactly is your question? Are you asking why macros are useful? See [these](http://stackoverflow.com/q/267862/5044950) [two](http://programmers.stackexchange.com/q/124930) questions. Are you asking about the difference between functions and macros? See the linked duplicate. Are you asking why Rich Hickey decided to include macros as a feature in Clojure? We can't say for sure what all his reasoning was behind that decision, but the [rationale](http://clojure.org/about/rationale#_lisp_is_a_good_thing) talks about it. So your question is either a duplicate or off-topic. – Sam Estep Jul 06 '16 at 15:51
  • 3
    "Why does Clojure expect macros to return expressions that can be evaluated?" Because that's the point of having macros. Your question sounds as if you're asking "Why do macros behave like macros?" I think you really mean to ask one of the questions that Sam Estep mentioned, all of which are about reasonable things to wonder about. – Mars Jul 06 '16 at 17:33

1 Answers1

2

Let's just start with one thing many people know so well they forget to think about it explicitly when explaining macros, which causes others to be confused when learning to think about macros:

-----------> macros are functions <-------------

They are very often used to take lists of things that look like code, and are very often expected to return lists that can actually be run as code.

The difference between a macro and a function is not what it does (fundamentally), but when it does it. macros run while the code is "loading" and the value they return is run when the program runs.

when you write it as a macro it does two steps:

  • run the function to produce a list
  • run that returned list as code to produce a value

when you write it as a function it does one step:

  • run the function to produce a list

Then it stops.

The return value is diferent because the macro version takes that extra step of running the returned value as code.

code is data ... data is code ... yay lisp!

Arthur Ulfeldt
  • 90,827
  • 27
  • 201
  • 284
  • I have been applying similar thought process to understanding macros. In the REPL process macros sit between Read and Eval. That is why the return value of a macro is evaluated because "read" has already happened. Functions on the other hand are evaluated and it's return value is meant to be fed to the reader. I may be wrong. I am still thinking. – ardsrk Jul 08 '16 at 17:43
  • On more thought, the return value of a function is meant to be printed or the execution process loops back and the return value is input to the "read" step. – ardsrk Jul 08 '16 at 17:51
  • @ardsrk yep you get it. it loops back to the read stage and if it's still a macro on the second pass then it loops back again for a third pass. Just keeps going around until there are no macros left. then the final fully formed code actually makes it into the finished program. – Arthur Ulfeldt Jul 08 '16 at 18:05
  • You make an interesting point. Please elaborate on your comment about the second pass and further. I am thinking, since a function can return a function it can also return a macro... – ardsrk Jul 08 '16 at 18:19
  • yes, thats correct: If the expression (list usually) it returns is a function call `(when ...)` and the function is marked as a macro, then it loops again. If the function is not a macro then it stops looping and returns that as the final code/expression. macros are functions with some extra metadata that says "I am a macro" thats the only difference that makes them a macro. run `(meta #'clojure.core/when)` and look at the `:macro` key – Arthur Ulfeldt Jul 08 '16 at 18:24