http://dev.clojure.org/display/design/Compiler+in+Clojure
On Sat, Apr 23, 2011 at 3:37 AM, Simon Katz <nomisk...@gmail.com> wrote: > Thanks -- interesting, especially the bit about the design notes on a > compiler rewrite. > > On Thu, Apr 21, 2011 at 22:23, Kevin Downey <redc...@gmail.com> wrote: >> >> 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 > > -- > 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