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

Reply via email to