In Clojure, why is do a special form, instead of a function implemented like this?
(defn do [& exprs]
(last exprs))
In Clojure, why is do a special form, instead of a function implemented like this?
(defn do [& exprs]
(last exprs))
Copyright © 2021 Jogjafile Inc.
Basic sequential execution semantics
fn(well,fn*) actually reuses the logic behinddo, 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 asdo.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
doAdditionally, top-level
dos are treated specially by the compiler in thatis equivalent at top level (and only at top level) to
– 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.