Hacker News new | ask | show | jobs
by AnimalMuppet 2779 days ago
It seems to me that, if you were to write that in Java, these would just be regular functions returning arrays of Strings or something similar. There would be a similar shortening of the source code. (It still wouldn't be as short, of course, but the same shortening would take place.)

Am I missing something? What's the special macro-ness here that is different from regular functions?

3 comments

Another key point is that most if not all of the replacements are done at compile time, therefore the final code only makes minimal function calls.
One difference is flow control. When you call a function, all the arguments are evaluated before being passed into the function. If you want to delay evaluation, you have to wrap the argument values in a function. When you call a macro, the text forms get passed with no evaluation. Say Clojure forgot to ship with the boolean "or". "or" should evaluate its arguments one at a time (to allow for short circuiting) and return the first non-false value. You could do this with functions, but you have the source-level overhead of manually wrapping everything, and performance overhead of defining and passing an anonymous function for each argument. With a macro, at compile time you just translate the "or" macro into a simpler form that uses "if". This is how Clojure actually implements "or":

    (defmacro or
      "Evaluates exprs one at a time, from left to right. If a form
      returns a logical true value, or returns that value and doesn't
      evaluate any of the other expressions, otherwise it returns the
      value of the last expression. (or) returns nil."
      {:added "1.0"}
      ([] nil)
      ([x] x)
      ([x & next]
          `(let [or# ~x]
             (if or# or# (or ~@next)))))
Also check this http://lists.warhead.org.uk/pipermail/iwe/2005-July/000130.h...
The amount of effort it takes to write a "shortener". Yes, you could do this in java, most likely. However, it would take a ton of effort and likely still not cover as many cases as the easy to write lisp would.

As an example, I have the beginnings of something like that in javascript at http://taeric.github.io/DancingLinks.html (in the appendix. Functions "div, table, etc.") I've done similar in java before to get the same basic structure that I could run in any c like language. I still miss the flexibility of lisp.

edit: to see another example of mine showing some of the advantage of the "macroness" see http://taeric.github.io/CodeAsData.html and see how little code it took to make a tree walker in lisp. (Not just the tree walker, but indeed, the tree.)