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