At the risk of continuing an already long thread on the namespace declaration,
I want to present my proposal for changing the namespace declaration. Unlike
Greg's proposal, it is not about changing the syntax, but fundamentally
changes the nature of the declaration.

One of the  things about the current namespace declaration is that it
is very complex, but has a lot of functionality. We can require, refer and
use. We can take a complete list and specify subsets (clojure.core :exclude
[partition]) We can specify standard prefixes (clojure.core match logic). We
can specify aliases (clojure.core.match :as m). And we can do lots of similar
stuff with imports for Java classes also. Hence, the namespace macro has got 
very complex.

The irony of this is that a lot of the complexity is effectively to enable the
manipulation of lists in a declarative way; surely this is something that we
could just use clojure to do.

So, the idea is that the ns form would change to take only two directives.
:require and :import (I'm ignoring things like :gen-class which would remain
untouched). Currently these things take lists. My proposal is, instead, that
they take closures that evaluate to a list. These lists could have a
relatively simple structure. So for require an item like 

      clojure.core/partition  would mean "require clojure.core/partition"
      [clojure.core/partition :as c/parition] 
                             would mean "require clojure.core/partition but 
                              call it c/partition"
      [clojure.core/partition :use] 
                              would mean "require clojure.core/partition, but 
                              call it partition"

Of course, producing these lists would be painful manually, but now that ns
macro takes closures, we can automate these things. To do this, we create a
new namespace (clojure.core.namespace) with useful functions (or macros
anyway, so we can use symbols). So

(all clojure.core)

would expand to something like....

(vals (ns-publics 'clojure.core))

while

(only clojure.core map filter conj) 

would expand to something like

(for [k [map filter conj]]
     (symbol (concat "clojure.core" (name k))))

If we want "use" functionality we do define 

(use nnn)

expanding to

(for [k nnn]
   [k :use])

so

(use (all clojure.core))

would do the equivalent of (:use [clojure.core])

Now, if you want to do wildcard, or regular expression support, it can be
added *without* changing the ns macro. The same can be done for the import
declaration. 

This allows us to do imaginative things. What about loading import statements
from a file? Why would this be useful? Well, we have discussed wildcard import
statements before. but it noted that it requires crawling paths. We could do
something like

   (:import (from-dep [net.sourceforge.owlapi/owlapi-api] 
                 OWLObject OWLRestriction))

What this would mean is "from the dependency owlapi-api import OWLObject and
OWLRestriction whatever their packages are". In terms of implementation,
"from" would read a header file which enumerates all the classes in the
dependency given -- the file name would be a transformation of the dependency.
This file would be generated by leiningen only when necessary (after a
dependency was introduced or updated), and outside of the actually clojure
process. The "from-dep" macro would need no knowledge of maven dependencies,
only how to syntactically transform the dependency to a file name.

Now, I can see a significant bootstrap problem -- functions that we want to
use in the namespace macro might not have been required yet. Ideally, I think,
we would want clojure.core and clojure.core.namespace to be automatically used
within the ns declaration. So, I don't quite know how this would be
implemented. Also from a tool creator point of view, the namespace declaration
becomes unparsable because it's extensible -- this would be eased by having a
an "expand-ns" macro which evaluates the ns macro using the same logic into a
normalised long hand form. Tool creaters could use clojure to interogate the ns
declaration. 

But the key point here is that we now have a fully extensible namespace
declaration where we are using clojure to manipulate the lists that we need.
The namespace form itself becomes relatively simple. And any complexity that
we need can be provided by additional functions, each of which can provide
better documentation than we currently have.

-- 
-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to