On Wed, May 25, 2011 at 10:58 PM, Ken Wesson <kwess...@gmail.com> wrote:
> Different things happen at compile and run time in each case:
>
> Thing           Compile                       Run
> literal         inserted into bytecode        recalled from memory
> symbol          var resolved, deref compiled  var is deref'd
> (def bar baz)   bar var interned              baz eval'd, bar set
> (macro x y)     macro is expanded             expansion is eval'd
> (func bar baz)  fn-calling code compiled      func called with args

Actually, I didn't include in there the literal set, vector, and map
case. There, the compiler emits code to evaluate the subforms and pass
them to the appropriate constructor to produce the set, vector, or
map; the runtime does the evaluation and construction. When the
collection literal has no non-self-evaluating nested forms, though,
it's possible the compiler optimizes this by simply emitting code to
retrieve the literal collection from memory somewhere.

There's also the subform evaluation matter:

Thing           Subforms evaluated when?
[foo bar baz]   at runtime, as arguments to vector constructor
#{foo bar}      at runtime, as arguments to set constructor
{foo bar}       at runtime, as arguments to map constructor
(def foo bar)   foo isn't eval'd; bar eval'd to assign foo
(macro foo bar) at runtime, as decided by macro
(func foo bar)  at runtime, before func called

Different special forms differ; e.g.

(if foo bar baz)

results in foo evaluated, and then either bar or baz depending on the
truthiness of whatever foo evaluated to.

Macros generally splice their argument forms into their expansion in
some manner, and the nature of that expansion determines what gets
called when. For example if -?> is defined to be a null-safe threading
macro, which acts like -> except that if any of the intermediate
results is nil it stops and evaluates to nil, then:

(-?> {:a 3}
  (:b)
  (+ 17))

will never evaluate the (+ something 17) clause because the result of
(:b {:a 3}) is nil.

The macro would expand this into something like:

(let [x {:a 3}]
  (if x
    (let [y (:b x)]
      (if y
        (+ y 17)))))

and then the rules for the special form (if ...) end up causing the (+
y 17) to not be evaluated.

-- 
Protege: What is this seething mass of parentheses?!
Master: Your father's Lisp REPL. This is the language of a true
hacker. Not as clumsy or random as C++; a language for a more
civilized age.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to