Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is do a special form?

In Clojure, why is do a special form, instead of a function implemented like this?

(defn do [& exprs]
  (last exprs))
like image 855
Sam Estep Avatar asked Oct 27 '15 17:10

Sam Estep


People also ask

What is a special form in programming?

A special form is a primitive function specially marked so that its arguments are not all evaluated. Most special forms define control structures or perform variable bindings—things which functions cannot do. Each special form has its own rules for which arguments are evaluated and which are used without evaluation.

Is lambda a special form?

Lambda is the name of a special form that generates procedures.

Is cond a special form?

What makes cond a special form is that its arguments are evaluated lazily whereas functions in Scheme or Common Lisp evaluate their arguments eagerly. Save this answer. Show activity on this post. As already answered, all arguments to a call to some function f are evaluated before the result of applying f is computed.


1 Answers

Basic sequential execution semantics

fn (well, fn*) actually reuses the logic behind do, as do other forms with bodies – let*, letfn*, try. Since there are several of these, it makes sense to have them reuse the basic "evaluate expressions in sequence" logic; and since this in itself is useful to user code outside the context of the more complex special form, it makes sense to expose it as do.

Were fn* the basic special form instead, sequentially evaluating expressions would involve making a function call – the overhead of that would not be acceptable for this sort of low-level facility.

(On the other hand, replacing the other special forms with macros wrapping their bodies in implicit dos wouldn't introduce any overhead. In the context of the Clojure compiler as it stands, however, it wouldn't be a huge win either – on this point at least it's fairly DRY already.)

Top-level do

Additionally, top-level dos are treated specially by the compiler in that

(do
  (foo)
  (bar))

is equivalent at top level (and only at top level) to

(foo)
(bar)

– that is, to the individual expressions written out separately. This allows macros to output (code equivalent to) multiple top-level expressions.

It wouldn't be impossible to interpret top-level calls to some special function in this way, but using a special form for this purpose is significantly cleaner.

like image 82
Michał Marczyk Avatar answered Sep 29 '22 20:09

Michał Marczyk