(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.You could do `(defn swap [the-list] ((second the-list) (first the-list)))` (which would invoke the second item as a function on the first item). It comes down to is the list a literal list as a parameter to something or is the first item a function to be invoked.
So (+ 1 2) first evaluates 1 and 2, which each evaluate to themselves and thus can't be simplified any further. They are then passed into '+'.
in (+ 1 (* 2 3)) the + is a function and the arguments are 1 and (* 2 3). 1 evaluates to itself. Evaluating (* 2 3) starts by evaluating 2 and 3, then applying them to '*' resulting in 6. So if we displayed an intermediate step, our form would now look like (+ 1 6), finally evaluating to 7.
To prevent the form (f a b c) from being treated as a function call, you can "quote" it by prefixing with a single quote (aka tick): '(f a b c). The evaluator now knows we intend that to just be data and not to evaluate it.
The exception to evaluating (f a b c) as a function call is if 'f' is a macro. In that case, the arguments a b and c are not evaluated and instead are passed into the macro as data.
Where this comes into play is if you want to programmatically change the code around before it's executed, and particularly where the arguments have side effects when they are evaluated (changing the state of something, like adding data to a database).
(defun swap (x y) (y x))
Then you can call it like:
(swap (2 3)) => (3 2)