On Mon, May 30, 2011 at 12:47 AM, iamcreasy <quazir...@gmail.com> wrote:
>> Sort of. You can create a macro with defmacro, which like a special
>> form controls the evaluation of its arguments instead of the arguments
>> being evaluated first and the function only getting the results.
>> Things like -> and defn are macros:
>
> That means, the difference of composite form and special form, is the
> order / sequence of evaluation of arguments? right?
> Composite form can be a function(list) or some other supported data
> structures(Vector, map and set). Special form which looks a lot like a
> funciton, is NOT a funciton / list / composite form at all.

I'd use "composite form" for anything that, in source code, is not an
atom -- a list, vector, set, or map. Others may use it differently.
The book you have seems to use it to mean just lists.

> This also means, what is written on the book about special form
> "Special forms are a particular type of composite form. For most
> purposes, they are used very similarly to
> a function call. The difference is that the first form of a special
> form is not a function defined
> somewhere, but a special system form that’s built into Clojure."
>
> is badly written or wrong, right?

No.

> Its not about being special form as a composite form, they are
> different to begin with.

Not really.

> Its not about being 'built into clojure', its about how they work.

It's both.

>> 5. (foo bar baz) with foo not a special operator: the subform foo is
>> looked up at compile time and if it's a macro, macro expansion is
>> performed. The transformed code is then evaluated per these rules.
>
> I didn't understand this one.Is it about user defined function?

No, macros.

>> 6. (foo bar baz) with foo not a special operator or a macro. At
>> compile time, code is generated to evaluate foo, bar, and baz at
>> runtime and then apply foo as a function to the arguments bar and baz.
>
> I didn't understand this point too. An example would help.

(def foo 42)

Since 'def is a special operator, this is a special form and it has
special evaluation rules. It ends up interning a Var named 'foo in the
current namespace with the value 42.

(defn bar [] 42)

Since 'defn is not a special operator, the compiler checks the
namespace for any Var visible in it named 'defn. It finds that
'clojure.core/defn is referred, and uses that. The object in that Var
proves to be a macro, so the compiler expands it by calling it as a
function with the rest of the form, unevaluated, as arguments. This
produces something resembling

(def bar (fn bar [] 42))

and this is a 'def special form, which ends up interning a Var named
'bar in the current namespace whose value is a function object which,
when called with no arguments, returns the number 42.

(bar)

Since 'bar is not a special operator, the compiler checks the
namespace for any Var visible in it named 'bar. It finds that the
current namespace itself contains a Var named 'bar and uses that. The
object in that Var proves to be a function, so the compiler converts
this form into bytecode that calls the function. At runtime, when this
executes, the function returns the number 42.

>> (def bar baz)   bar var interned              baz eval'd, bar set
>> (macro x y)     macro is expanded             expansion is eval'd
>
> Arn't they same? def is written withing clojure and when needed its
> expanded.

Not really. Special forms have special evaluation rules. The bytecode
emitted can, in theory, be anything, and things can be done at compile
time. In the case of def, a Var is interned as soon as the compiler
even sees the form. If you didn't already have def you might be able
to recreate it as a macro using some interop calls on *ns* to intern a
Var. On the other hand if you didn't already have try you would not be
able to recreate that with a macro at all. No combination of functions
and macros compiles to bytecode that includes an exception handler
unless it contains the try special form after all macroexpansion.

>> 'def is definitely a symbol.
>
> If def is a symbol then it should evaluated to somthing?like, when I
> write 'print' and press return key, I get
>
> #<core$print clojure.core$print@4b455d1c>
>
> but, in case of def, i get the following 'Error',
>
> #<CompilerException java.lang.Exception: Unable to resolve symbol: def
> in this context (NO_SOURCE_FILE:0)>
>
> Isn't this concludes def is not a symbol cause its returning an error.

No; 'def is a symbol but it's not bound to anything in the current
namespace so you get the "unable to resolve" message. Meanwhile,
'print is bound to a function object from clojure.core. When you type
print at the REPL it evaluates to the function object, which prints
the way you saw. And if you quote, typing either 'def or 'print, you
get the symbol itself back. If you (def def 42) and evaluate def
you'll get 42 instead of the "unable to resolve" message. But (def
...) won't throw a "cannot cast Integer to IFn" message the way (42
...) would, because the symbol 'def in operator position is always
treated as a special operator rather than looked up. This is the other
thing that would be different if def were a macro; if def were a macro
you could shadow it locally with 42, and you'd get "cannot cast
Integer to IFn" from a subsequent (def ...) form.

> From you explanation what i got that, built in macros are called
> special form and I can also create my custom macros, which will be
> called special forms. is it right?

Not really. Special forms and macros aren't the same, though they're
similar in that they do some of their stuff at compile time and can't
be passed to higher-order functions. Particularly significant is that
a special operator in operator position effectively shadows all
functions and macros that may have been given the same name, though
you can still get at the latter by namespace-qualifying them or
assigning them to locals and then calling the local or both.

-- 
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