Hacker News new | ask | show | jobs
by LandR 2496 days ago
In the example we wanted to be able to call (1 + 2) and have it evaluate to 3.

   (defn swap [x]
      (list (second x) (first x) (last x)))

   (swap (1 + 2))
   =>Exception! 1 isn't a function.
Clojure tried to evaluate it's argument to swap, and the argument was (1 + 2), which is a function call, where the function is 1 and the arguments are + and 2.

So we quoted it in the function call by putting ' in front of the list '(1 + 2):

    (swap '(1 + 2))
    => (+ 1 2)
Here, we stll didn't get 3 as our output... We got (+ 1 2), which is a list. Because the function returned a list, it didn't return code! It might look like code, but it's not code! It's a list.

So if I was to

   (+ (swap '(1 + 2)) (swap '(3 + 4)))
   => Crashes! Can't convert  alist to a number.
Because what it actually runs is

   (+ '(+ 1 2) '(+ 3 4))
Whereas with the macro

   (+ (swap (1 + 2)) (swap (3 + 4)))
   => 10
Works because the macro gets expanded BEFORE compile time, and our swap code gets replaced out with the code the macro generates!

    (swap (1 + 2))
actually compiles as:

    (+ 1 2)
SO at runtime, that will be 3.