News for hackers. Stuff that matters.
Re:Project for bringing macros to Scala by michaelochurch on Wednesday November 09, 2011 @11:22AM (#3216086)
The best way to learn macros is to learn a Lisp. Macros are easy to grok in Lisps. Regarding languages, I'd pick Clojure since you already know Java. In Lisp, you write ASTs directly. Syntax is very lightweight. For example, 3 + 4 * 5 is written as (+ 3 (* 4 5))-- the form compilers in other languages translate it into. The prefix notation and parentheses make parsing unambiguous; you don't have to worry about left vs. right associativity or order of operations.

The evaluation strategy for Lisp functions is to evaluate each of the inputs before making the function call. In the example above, (* 4 5) is evaluated first before the call to the function + even begins; once you have the intermediate form (+ 3 20) where all the parameters are fully-evaluated, the function call happens.

Why are macros important? Let's say that you want to write a short-circuit AND. You can't do that as a function. For example, (and false (/ 1 0)) will return false (never evaluating the right-hand expression) if you have short-circuit AND but it will raise an error (division by zero) if you don't. If that were a function, that call would (undesirably) fail. So what this means is that you can't write the short-circuiting AND as a function. You need something else that operates on expression forms, not values. In practice, it's a macro whose behavior is approximately like so:

(and <X> <Y>) => (if <X> <Y> false)

This is a transformation of code that happens during compilation, not a run-time function call.

It's worth noting that IF is not a function or a macro. It's a "special form" provided by the language. The evaluation of if-forms is not like the evaluation of function forms; some branches are never evaluated. It requires special-case handling.

That's one use for macros: writing control-flow primitives. There's a lot more to them as well: code generation to eliminate boiler-plate, DSL creation. Common Lisp, for example, has an object system built on macros, and a (controversial) LOOP macro that is its own DSL for expressing iterations, allowing idioms like (loop for i from 4 downto 1 collect (* i i)), which would return (16 9 4 1).

Macros can be very useful. They're pretty much essential because of how Lisp works, so every Lisper ends up writing a few, often to substantial benefit. That said, macros can also be abused to make write-only code. You have to be careful with them, and the maxim, "Never use a macro when a function will do", is certainly worth heeding.

Re:Project for bringing macros to Scala by HnNoPassMailer on Friday November 11, 2011 @05:21AM (#3224116)
Thanks. The first time an esoteric language actually seems interesting to learn ;)