Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can one safely ignore the difference between a macro and a built-in?

I'm starting out with Clojure, which is also my first lisp. There's obviously a lot to take in, and in an attempt to lessen the cognitive load, I try to find the parts which I can safely ignore (for now).

Can one safely treat forms with macros and forms with built-ins the same, or are there pitfalls that will spring up later?

In other words, will I ever run into a situation where I need to know that (defn f1 []) expands to

(def f1 (.withMeta (clojure.core/fn f1 ([])) (.meta (var f1))))
like image 615
JimB Avatar asked Feb 25 '11 17:02

JimB


2 Answers

Macros in general compose very differently. Macros are not "first class citizens": you can't pass them to map etc., you can't store them in variables and you can't apply them to a list of arguments. Initially you don't need to worry about these because they will obviously not work: a subtle, hard-to-detect error would be a lot more troubling. If you try to run

(map if [true false true false] [1 2 3 4] [-1 -2 -3 -4])

the fact that if is not a function will become very apparent. Just keep in mind that macros are not functions and you should be just fine :)

PS: macros are (fn (fn (fn :-D) :^P) :O)

like image 165
Arthur Ulfeldt Avatar answered Sep 21 '22 23:09

Arthur Ulfeldt


In almost all cases you can completely ignore the distinction. (and in fact you have, since fn isn't a built in either - it's a macro expanding to fn*)

The only exception I've come across is that macros and built-ins behave differently if you try to redefine them. Just don't redefine any existing functionality and you'll be fine treating them the same.

like image 45
amalloy Avatar answered Sep 21 '22 23:09

amalloy