This email contains a proposal for a way to get rid of at-least the following forms from the (ns) declaration:
- :refer-clojure
- :use
- :import
See below...
> The namespace declaration is too complex. The existence of ":use" is not
> what causes this.
I agree that it is not the *sole* cause, but I do believe that it is a
significant part of the problem.
> can you please therefore explain why you think a breaking change
> to ns is a good thing to remove something that we are still going to be
> able to do, but in a more verbose way.
The 'ns' declaration is complex because there are too many ways to do
essentially the same thing. "use" is one of those ways that is completely
unnecessary and creates unnecessary complexity.
Clojure's documentation also contributes to this problem, but in some ways it's
a victim of the poor design of the 'ns' declaration. Just look at this monster:
user=> (doc ns)
-------------------------
clojure.core/ns
([name docstring? attr-map? references*])
Macro
Sets *ns* to the namespace named by name (unevaluated), creating it
if needed. references can be zero or more of: (:refer-clojure ...)
(:require ...) (:use ...) (:import ...) (:load ...) (:gen-class)
with the syntax of refer-clojure/require/use/import/load/gen-class
respectively, except the arguments are unevaluated and need not be
quoted. (:gen-class ...), when supplied, defaults to :name
corresponding to the ns name, :main true, :impl-ns same as ns, and
:init-impl-ns true. All options of gen-class are
supported. The :gen-class directive is ignored when not
compiling. If :gen-class is not supplied, when compiled only an
nsname__init.class will be generated. If :refer-clojure is not used, a
default (refer 'clojure) is used. Use of ns is preferred to
individual calls to in-ns/require/use/import:
(ns foo.bar
(:refer-clojure :exclude [ancestors printf])
(:require (clojure.contrib sql combinatorics))
(:use (my.lib this that))
(:import (java.util Date Timer Random)
(java.sql Connection Statement)))
The above does not explain completely how to use 'ns'. You have to read the
documentation for the syntax of all of the other forms its supports.
Deprecating :use would be a significant step in reducing the complexity of the
'ns' declaration, and improving the readability of Clojure's code. It would be
one less piece to the monster.
There's a great quote by I don't remember who (Apple-related?), that to create
something truly great, you have to keep removing all the unnecessary bits till
there's nothing unnecessary left to remove. Something like that (if anyone
knows the quote I'm talking about, please share).
This complexity isn't necessary.
Perhaps I'm mistaken, but I don't see why with a little bit of compiler
intelligence, we can't convert this:
(ns one.fresh-server
(:refer-clojure :exclude [ancestors printf])
(:use core.matrix
[ring.adapter.jetty :only (run-jetty)]
[ring.middleware.file :only (wrap-file)]
[ring.middleware.file-info :only (wrap-file-info)]
[ring.middleware.stacktrace :only (wrap-stacktrace)]
[ring.util.response :only (file-response)])
(:require [one.reload :as reload]
[one.middleware :as middleware]
[net.cgrand.enlive-html :as html])
(:import (org.apache.maven.artifact.resolver ArtifactResolver)
(java.io File))))
Into this:
(ns one.fresh-server
(:require [clojure.core :refer [ancestors printf]]
[core.matrix :refer :all]
[ring.adapter.jetty :refer [run-jetty]]
[ring.middleware.file :refer [wrap-file]]
[ring.middleware.file-info :refer [wrap-file-info]]
[ring.middleware.stacktrace :refer [wrap-stacktrace]]
[ring.util.response :refer [file-response]]
[one.reload :as-ns]
[one.middleware :as-ns]
[net.cgrand.enlive-html :as html]
[org.apache.maven.artifact.resolver.ArtifactResolver :as-class]
[java.io.File :as-class]))
Ta da!
There we've removed the unnecessary :use, :import, and :refer-clojure forms,
and added :as-ns and :as-class shortcuts. Require now supports both Java
Classes and Clojure Namespaces.
We've removed practically all the complexity! The only complexity remaining are
the keyword-options to available in the :require clauses, but we already had
those before.
> Please also explain at the same time, why (use 'core.matrix) remains
> clear and why this should not change to "(require 'core.matrix :refer
> :all)".
I must have missed this part of the thread. I did not say it shouldn't maybe
someone else did. I'm for deprecating "use" completely, while retaining its
abilities through "require".
- Greg
--
Please do not email me anything that you are not comfortable also sharing with
the NSA.
On Aug 5, 2013, at 10:52 AM, Phillip Lord <[email protected]> wrote:
> Greg <[email protected]> writes:
>>> It's pretty ugly to use aliases for numerical code, e.g. with core.matrix,
>>> e.g.
>>
>> Agreed. It's nice that :require :refer :all is available for such instances,
>> isn't it?
>
> Which leads to the crux of the question.
>
> Given that the functionality is there, and that you agree that it is
> useful, can you please therefore explain why you think a breaking change
> to ns is a good thing to remove something that we are still going to be
> able to do, but in a more verbose way.
>
> Please also explain at the same time, why (use 'core.matrix) remains
> clear and why this should not change to "(require 'core.matrix :refer
> :all)".
>
>
> The namespace declaration is too complex. The existence of ":use" is not
> what causes this.
>
> Phil
>
> --
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to [email protected]
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from this group, send email to
> [email protected]
> 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 [email protected].
> For more options, visit https://groups.google.com/groups/opt_out.
>
>
signature.asc
Description: Message signed with OpenPGP using GPGMail
