> I got a very basic question about the concept of "special form". What
> is correct, multiple selections allowed:
>
> [ ] A special form is what can be implemented by a macro.
Wrong. You cannot implement a Lisp-like language with just macros and
functions. At some point the operations defined by macros and
functions must be reduced to fundamental operations that are handled
directly by the compiler.
Example: if and cond. You can implement either one in terms of the
other one as a macro, but you cannot implement *both* as macros.
> [ ] Every macro gives a special form.
Wrong. A macro rewrites a form to another form. A special form is
interpreted directly by the compiler.
There is also a technical difference: a macro is the value of a name,
which is looked up in the context of the macro call. Constructs like
macrolet (clojure.contrib.macro-utils) permit local macro definitions,
for example. A special form is named by a symbol whose interpretation
cannot be overridden in any way.
> [ ] Only a macro that doesn't evaluate some of its arguments gives a
> special form.
Wrong as well. The distinction between macros and special forms is a
matter of implementation, not of evaluating arguments.
> [ ] A special form is always built in, and cannot be implemented in
> the language itself.
True for a minimalist language implementation. An implementation may
choose to use more special forms than strictly necessary for
performance reasons.
> [ ] The concept of special form doesnt have anything to do with
> eagerness or lazyness.
True.
Konrad.
> Hello Konrad, many thanks, that clarifies it!
>
> So, in "A special form is always built in, and cannot be implemented
> in the language itself." the first part is true, the second is not.
> Like most lisps have a bilt in list-reverse for speed reasons.
> In that case, this build in thing is a special form that can also be
> implemented in the language (only slow).
> Right?
Right.
> "A special form is named by a symbol whose interpretation
> cannot be overridden in any way."
>
> This explains the problem from another thread (that made me ask this
> question in the first place):
>
> user=> (def do println)
> #'user/do
>
> ; this uses the special form
> user=> (do "huhu" "plop")
> "plop"
>
> ; while this uses println
> user=> ((var do) "huhu" "hello")
> huhu hello
> nil
Yes, that illustrates the handling of special forms nicely. Note that
it is somewhat specific to Clojure. Other Lisps handle the mapping
from symbols to functions/macros/special forms differently.
One more variant is helpful:
user=> (user/do "huhu" "hello")
huhu hello
nil
This illustrates that special forms need to be identified by an
unqualified symbol in the operator position.
Another detail that is good to know is that syntax-quote (`) knows
about special forms and treats their symbols specially even if they
are not in the operator position:
user=> (declare do foo)
#'user/foo
user=> `do
do
user=> `foo
user/foo
Konrad.
> I got a very basic question about the concept of "special form". What
> is correct, multiple selections allowed:
>
> [ ] A special form is what can be implemented by a macro.
Wrong. Macros cannot remove the need for special-forms, at least not in a real interpreter. In a metacircular implementation, you can replace special-forms with calls to the base-level implementation. For instance, if you evaluate 'if' at base-level, then you can use it to define 'cond' at base-level.
> [ ] Every macro gives a special form.
They can all be reduced to a number of expressions that cannot be implemented by neither macros nor functions.
These expressions can be evaluated using normal functions if you have lazy evaluation of arguments. So, if you have lazy-eval, there's no need for special-forms.
> [ ] Only a macro that doesn't evaluate some of its arguments gives a
> special form.
You could say that.
> [ ] A special form is always built in, and cannot be implemented in
> the language itself.
Unless you have lazy-eval.
> [ ] Special forms are exactly the things that can be called, but dont
> evaluate all of their arguments. (Macros and build-ins, at least for
> eager languages.)
>
> [ ] The concept of special form doesnt have anything to do with
> eagerness or lazyness.
Wrong. It has everything to do with laziness. If you have one, you don't need the other.
Please note that, the concept of special-forms is a compromise and I don't think anyone would want to have them. A language designer has to make a choice as to whether to have special forms or not. If they don't want special-forms, then they should provide lazy evaluation of arguments.
Some introduce functional parameters in order to provide lazy evaluation of arguments but that choice has its own trade-offs since it introduces a kind of dynamic scoping.
Kind regards,
SinDoc
Oh, I meant:
... then you can use it to define 'cond' at *meta*-level.
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
On Mon, May 31, 2010 at 10:21:14AM -0700, Quzanti wrote:
> Are you sure that always works?
>
> I think I am misunderstanding Halloway's Taxonomy of Macro's chapter
>
> defstruct is written as a macro and Stuart then comments
>
> "This macro looks so simple that you may be tempted to try to write it
> as a function. You won't be able to because def is a special form. You
> must generate def at macro time; you cannot make 'dynamic' calls to
> def at runtime"
It works sometimes. Of course you can redef a Var via function.
(defn foo [y] (def x y))
(foo 5)
However, you cannot define arbitrary Vars.
(defn bar [x y] (def x y))
(bar 'c 5)
This does *not* define Var named c. So can't really make 'dynamic'
calls to def at runtime. Just as Stuart writes.
Sincerely
Meikel
Hey alux,
> what an interesting discussion! Whoo! ;-)
>
> Many thanks four your comment.
>
>> So, if you have lazy-eval, there's no need for special-forms.
>
> This is obviousely correct for if / cond.
>
> Looking into the other special forms ( http://clojure.org/special_forms
> ), I wouldnt know how to implement all of them. Certainly there is,
> unknownst to me, a bunch of literature about (sets of) primitives that
> cannot e replaced - literature hints anybody?
> (Well, thats probably a nice set of exercises :)
If you're interested in programming languages, I encourage you to study SICP [1]. In chapter four, you can see variations of Scheme implemented in a metacircular way. One of these variations is a lazy evaluator (4.2 [2]). Please note that the lazy evaluator does NOT have special-forms at all.
Kind ragards,
SinDoc
[1] http://mitpress.mit.edu/sicp/full-text/book/book.html
[2] http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-27.html#%_sec_4.2
>> So, if you have lazy-eval, there's no need for special-forms.
>
> This is obviousely correct for if / cond.
If you define special forms as in Common Lisp (that's something I
learned from this discussion), yes. If you define special forms as I
think Clojure does (in fact, I can't find any definition, just a
list), then it's not true. With lazy evaluation, "if" could become a
plain function, but it would still have to be a built-in function that
one could not express in the language itself, unless some other choice
primitive or a suitable data structure exists. The notion of a
primitive operation always remains.
> Looking into the other special forms ( http://clojure.org/
> special_forms
> ), I wouldnt know how to implement all of them. Certainly there is,
> unknownst to me, a bunch of literature about (sets of) primitives that
> cannot e replaced - literature hints anybody?
For Lisp-like languages, the best starting point is SICP (http://mitpress.mit.edu/sicp/full-text/book/book.html
). For a more in-depth treatment of implementation issues, I'd
continue with Christian Queinnec's "Lisp in Small Pieces" (http://pagesperso-systeme.lip6.fr/Christian.Queinnec/WWW/LiSP.html
).
Konrad.
> In a lazy lisp if and cond can be plain functions. But to define plain
> functions, or in any case somewhere, I need a special form.
> Is it that what you mean?
Not quite, though it's true as well. What I meant is that you can't
define if/cond as a function in a language that doesn't already have a
choice function. Condition testing is a primitive operation that is
ultimately realized in hardware. So primitives always exist,
independently of laziness.
Konrad.
> no special form at all? Cool, I'll have a look.
>
> Chapter 4.1 and 4.2 actually sit on my desk already since yesterday -
> I just didnt read it. I hope I get a chance in the next days.
If you have the time and motivation, go for it. Please note that, the wizard book had better be _studied_ rather than _read_. Good luck!
SinDoc