NOTE: core of macro
macro is all about delay, let give a form control the computation, for example
t 2 3 if
The above program is easy to understand once you know the computation of factor is based on stack and concat. Then you know it means if true, return 2, else return 3. But we cannot write like that, alternatively, we can write like this
t [ 2 ] [ 3 ] if
Because computation in branch can have side effect, for example
t "a" . "b" . if
Ignore form problem, assuming if
can figure out our branches are
"a" .
and "b" .
, we will have problem that code actually put and
take stack twice. However, expectation is it only push "a"
and pop it,
now, delay shows its value
t [ "a" . ] [ "b" . ] if
[]
is not called delay, but its purpose is. The code wrapped in []
won't get evaluated immediately, if
makes decision about do that or
not. Go to LISP, we have same idea
(define-macro (when t e) (if (eval t) (eval e) (void)))
The form defined from define-macro
won't compute arguments when get
them, in the definition of it, eval
make sure when we do these
computations. Nothing different from what we see in factor, this is the
core of macro: a form controls computations.