On Feb 10, 2009, at 10:04 AM, Rich Hickey wrote:


On Feb 10, 9:45 am, "Stephen C. Gilardi" <squee...@mac.com> wrote:
I came across this when updating the wikibook concepts page, Libraries
section, to be correct for current Clojure behavior.

In an early implementation of the code that handles libs, the resource
(file) for lib a.b.c was at the path "a/b/c/c.clj" within classpath.
At that time it was natural to consider "a/b/c/" as the lib's directory.

Later, the resource for the library a.b.c changed to the path "a/b/
c.clj" and the lib's directory became "a/b/".

I think the lib handling code should be changed such that the
directory associated with lib a.b.c is (again) "a/b/c/".

The advantage of this comes into focus most sharply in a ":load"
clause within "ns".

Here's the updated example from the wikibook:

       (ns example.ourlib
         (:load "ourlib/add1"
                "ourlib/otherfunc"
                "ourlib/morefuncs"))

With the change I'm proposing, this would become:

       (ns example.ourlib
         (:load "add1"
                "otherfunc"
                "morefuncs"))

Currently core.clj ends with 3 load calls to load in more pieces of
clojure.core that were each big enough to warrant a separate file.

The directory structure in src/clj/clojure is (in part):

       src/clj/clojure/
               core.clj
               core_print.clj
               core_proxy.clj
               genclass.clj

With the proposed change, this would become:

       src/clj/clojure/
               core/
                       core_print.clj
                       core_proxy.clj
                       genclass.clj
               core.clj

or, perhaps removing the "core_" prefixes:

       src/clj/clojure/
               core/
                       print.clj
                       proxy.clj
                       genclass.clj
               core.clj

There is also at least one lib in clojure-contrib that would need to
be updated.

I welcome discussion of this proposed change with the goal of entering
an issue and providing a patch. In the patch, I would also update the
doc string for clojure/require to reflect current Clojure behavior.


I think this needs more clarification as to what is meant by a lib/
root directory.  The lib .clj itself is not in this directory, but is
its same-named sibling.

Good point. Here's the current (doc load):

clojure.core/load
([& paths])
Loads Clojure code from resources in classpath. A path is interpreted as
  classpath-relative if it begins with a slash or relative to the root
  directory for the current namespace otherwise.

The phrase "root directory for the current namespace" (which I wrote long ago) is something that probably deserves more explanation and/or an example. Note that "load" is the only place this "root directory" concept is used.

Here's a shot at an updated version that fits with this proposal:

clojure.core/load
([& paths])
Loads Clojure code from resources in classpath. A path is interpreted as classpath-relative if it begins with a slash or relative to the directory associated with current namespace otherwise. The path to the directory
  associated with a namespace is derived from the namespace name by
translating dots to slashes and hyphens to underscores. For example, the directory associated with namespace a.b-c.d is "<classpath>/a/b_c/ d/".

Also, it creates potential overlap between hierarchical namespaces,
e.g. a.b.c and a.b.c.d, where the resources of the former would be
siblings of the root .clj of the latter. Seems confusing at first
glance.

We already have this overlap. It seems to me that it is inherent in any hierarchical layout. It's already the case that looking at a ".clj" file within classpath, one doesn't know without looking inside it whether it's a lib or whether it's a piece of a lib that's loaded by ":load". Even after looking inside it, we can't distinguish whether it's a file that's loaded by a :load clause within an "ns" form, or a file somebody plans to load explicitly using a classpath-relative path.

I don't think this proposal makes this uncertainty any worse and it has the advantage I outlined of keeping things that are all logically together (pieces of a namespace that happen to be in separate files) physically together (all in a directory that's easily associated with the namespace). Also for :load vs load uncertainty, it becomes much easier to check whether it will be loaded by :load" by giving us an obvious place to look for the "ns" form that :loads it.

--Steve

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to