the current compiler doesn't namespace qualify special forms (forms which are built into the compiler) but somethings that the documentation lists as "special forms" are infact macros defined in clojure.core based on the real special forms provided by the compiler. macros are namespace qualified so unless you use the fully qualified name(clojure.core/let) or :use/use them then they aren't available. this difference is kind of unfortunate, and the design notes on a compiler rewrite mention changing things so the forms directly supported by the compiler are also namespace qualified and live in clojure.core
On Thu, Apr 21, 2011 at 12:24 PM, Simon Katz <nomisk...@gmail.com> wrote: > Hi. > > (In case it makes a difference, I'm using Clojure 1.2.) > > If one creates a new namespace using in-ns, the new namespace > does not refer to clojure.core, as explained at > http://clojure.org/namespaces. > > I noticed one can use certain special forms in a namespace > created using in-ns, but not others: > _________________________________________ > | > | user> (in-ns 'my-new-ns) > | #<Namespace my-new-ns> > | > | my-new-ns> (quote a) > | a > | > | my-new-ns> (def x 42) > | #'my-new-ns/x > | > | my-new-ns> (let [a 42] a) > | ;; Evaluation aborted. Unable to resolve symbol: let in this context > | > | my-new-ns> (fn [] 42) > | ;; Evaluation aborted. Unable to resolve symbol: fn in this context > |_________________________________________ > > That puzzled me. > > In the process of trying to understand, I came across a mention > of clojure.lang.Compiler/specials (a map with symbols as its keys) > at > http://stackoverflow.com/questions/3159836/is-there-a-way-to-get-a-collection-of-clojure-special-forms-programatically > _________________________________________ > | > | user> (keys clojure.lang.Compiler/specials) > | ;; => (deftype* new quote & var set! monitor-enter recur . > | case* clojure.core/import* reify* do fn* throw > | monitor-exit letfn* finally let* loop* try catch if > | def) > |_________________________________________ > > So it seems that there are two kinds of special symbol. I'll > refer to them as implementation specials and documented specials: > - implementation specials > those that are keys in the clojure.lang.Compiler/specials > map > - documented specials > those that are documented as being special at > http://clojure.org/special_forms. > (Note that some symbols are of both kinds.) > > I assume that documented specials that are not implementation > specials are implemented as macros. (And the post I mentioned > above at stackoverflow.com says so.) > > Here's some investigation of these two kinds of special symbol: > _________________________________________ > | > | user> (def implementation-specials > | (keys clojure.lang.Compiler/specials)) > | #'user/implementation-specials > | > | user> (def documented-specials > | '(def if do let quote var fn loop recur throw try > | monitor-enter monitor-exit . new set!)) > | #'user/documented-specials > | > | user> (defn symbol-info [symbol] > | [(special-symbol? symbol) > | (= (resolve symbol) nil) > | symbol]) > | #'user/symbol-info > | > | user> (pprint (map symbol-info implementation-specials)) > | ([true true deftype*] > | [true true new] > | [true true quote] > | [true true &] > | [true true var] > | [true true set!] > | [true true monitor-enter] > | [true true recur] > | [true true .] > | [true true case*] > | [true true clojure.core/import*] > | [true true reify*] > | [true true do] > | [true true fn*] > | [true true throw] > | [true true monitor-exit] > | [true true letfn*] > | [true true finally] > | [true true let*] > | [true true loop*] > | [true true try] > | [true true catch] > | [true true if] > | [true true def]) > | nil > | > | user> (pprint (map symbol-info documented-specials)) > | ([true true def] > | [true true if] > | [true true do] > | [false false let] > | [true true quote] > | [true true var] > | [false false fn] > | [false false loop] > | [true true recur] > | [true true throw] > | [true true try] > | [true true monitor-enter] > | [true true monitor-exit] > | [true true .] > | [true true new] > | [true true set!]) > | nil > |_________________________________________ > > There are a few interesting things here: > > - special-symbol? returns true for implementation specials > (actually not surprising when you look at the implementation > of special-symbol?, but perhaps surprising if you have only > read http://clojure.org/namespaces and the documentation of > special-symbol? which says "Returns true if [the argument] > names a special form"). > > - Calling resolve on an implementation special gives nil. > > - In a namespace created using in-ns (such as my-new-ns above) > one is able to make use of implementation specials. > Implementation specials seem to bypass the normal > resolution process: > - defn is not an implementation special: > user> (resolve 'defn) > #'clojure.core/defn > - def is an implementation special: > user> (resolve 'def) > nil > > Well, that's probably enough wittering. > > Any comments? > > And my main question... > Is any of this stuff documented? (Perhaps there's other related > stuff that it would be good to know.) > > Simon > > -- > 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 -- And what is good, Phaedrus, And what is not good— Need we ask anyone to tell us these things? -- 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