> 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. 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? Its not about being special form as a composite form, they are different to begin with. Its not about being 'built into clojure', its about how they work. > 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? > 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 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. > '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. >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? Your second post is a little over my head :s On May 26, 8:58 am, Ken Wesson <kwess...@gmail.com> wrote: > On Wed, May 25, 2011 at 10:15 PM, iamcreasy <quazir...@gmail.com> wrote: > > 1st question, > > Is the form word is a typo here? Isn't the word will be item? If not, > > is def a form? That means, this code contains 3 forms. :-s > > Technically, anything that can be evaluated is a form. A composite > form is something like a literal list, vector, set, or map. The > literal list case is treated as an operator and arguments; the other > three just evaluate to vectors, sets, or maps, respectively, whose > members are the evaluations of the nested forms, so: > > + => the + function > (+ 1 2) => 3 > [+ 1 2] => a vector of the + function, 1, and 2. > [(+ 1 2)] => [3] > #{(+ 1 2) 4} => #{3 4} > {:a (+ 1 2)} => {:a 3} > > > 2nd question, > > Is a composite form is a special form only when, the first item of a > > list is something that is only predefined withing Clojure? If yes, > > then is it possible to create custom special form? > > 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: > > (-> 3 > (+ 1) > (* 2)) > > adds 1 to 3, then doubles, yielding 8. This couldn't work with a > function, as it would get arguments 3, 1, and 2 as (+ 1) would > evaluate, first, to 1, and (* 2) to 2. It wouldn't know what to do > with 3, 1, or 2 -- whether to add 1 and then multiply by 2, or > subtract 1 and then add 2, or what. The macro, however, operates on > the *forms* and gets 3, (+ 1), and (* 2) and combines the first two > into (+ 3 1) and that and the third into (* (+ 3 1) 2) by inserting > each form into the next one after the operator and before everything > else. > > (defn foo [a b] (+ (* a a) (* b b))) > > also cannot be a normal function call. If it were there would be > several errors: foo undefined (most likely), also a and b undefined, > so the first argument foo could not be evaluated, nor could the second > [a b], nor could the third (+ (* a a) (* b b)). But instead it works > to generate a function definition. It's a macro that expands to a (def > ...) form, in fact. > > > But, at the beginning the writer said, there are four basic varieties > > of forms. > > > 1. Literal, > > 2. Symbol, > > 3. Composite form and > > 4. Special form. > > I'd say it's a bit more complicated than that. We have six things that > are evaluated somewhat differently: > > 1. nil, true, false, numbers, strings, regexps, keywords ... evaluate > to themselves. > > 2. symbols are looked up when evaluated to find a local or global var > value they evaluate to. > > 3. Set, vector, and map literals have subforms evaluated, then > evaluate to a set, vector, or map with the subforms replaced by their > evaluated values. > > 4. (foo bar baz), if foo is a special operator like def, is a special > form and is evaluated according to the built-in rules for that form. > > 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. > > 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. > > The latter three can, of course, have zero or more arguments, not just > two, and generalize appropriately. > > 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 > > For special forms other than def, the behavior varies; (if bar baz > quux) for example compiles to a conditional test and branch and at run > time bar is eval'd, then the test and possibly the branch occurs, and > either baz or quux is eval'd. > > > According to the definition of Symbols from the book, its not a > > symbol. > > 'def is definitely a symbol. (No pun intended.) However (def ...) is > recognized as a special form by the compiler. Note that: > > def symbol > (def ...) special form > > You can actually create variables named def and the like. If you > reference them in other than operator position, it works: > > => (defn def [x] (+ x 2)) > #'user/def > => (map def [1 2 3 4 5]) > (3 4 5 6 7) > > In operator position, though, you get the special form unless you > qualify the name: > > => (def quux 42) > #'user/quux > => (user/def quux) > 44 > > If you define it locally, you can't use it in operator position at > all, unless you rename it: > > => (let [def (fn [x y] (+ x y 2)) > a def] > (println (def foo 42)) > (println (a foo 42))) > #'user/foo > 86 > nil > > The second let binding gives the local def another name, a, that can > be used to invoke it. It ends up using the foo that was def'd the line > before as one of its arguments. The same thing can be used if a > function argument or a loop binding is named def, and for any other > special operator's name besides def. > > But although it can be done it is generally best to avoid naming any > variable with the name of a special form, and especially any function, > or anything you might want to call like a function, such as a map or a > keyword. > > You also can't use 'nil, 'true, or 'false as names this way, or at all > easily. The reader turns "nil", "true", and "false" into literal nil, > true, and false objects, not symbols: > > => (def nil 42) > #<CompilerException java.lang.Exception: First argument to def must be > a Symbol (NO_SOURCE_FILE:1)> > > You can work around that by using eval when you need the name > unqualified, but please just pick some other name instead: > > => (eval `(def ~(symbol "nil") 42)) > #'user/nil > > You can use it qualified without difficulty: > > => user/nil > 42 > > -- > 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