Can we please deprecate the :use directive ?

906 views
Skip to first unread message

Greg

unread,
Jul 23, 2013, 11:50:50 AM7/23/13
to clo...@googlegroups.com
I think I read somewhere that :use is no longer encouraged, but I could be mistaken.

From what I've read, it seems like most people agree that Clojure has too many ways of including/importing/referencing/requiring/using things:

http://blog.8thlight.com/colin-jones/2010/12/05/clojure-libs-and-namespaces-require-use-import-and-ns.html

The above gives a very nice explanation of all the various difference, but it also acknowledges their complexity.

Since :use uses :require, and since :require can do everything that :use can, can we simplify Clojure programming a bit for newcomers by deprecating the use of :use? The situation in ClojureScript is even worse because it adds :require-macros on top of all the other ways of including files.

Ideally, it would be awesome if there was just a single directive for everything, but perhaps there's some complicated low-level reason why that's not possible. :-\

Thoughts?

Thanks,
Greg

P.S. If this has already been brought up you have my sincere apologies.

--
Please do not email me anything that you are not comfortable also sharing with the NSA.

Jozef Wagner

unread,
Jul 23, 2013, 2:17:02 PM7/23/13
to clo...@googlegroups.com
+1, :use is IMO an antipattern. 

I hate it mainly in blogs, where they explain some new API. They :use like 3 namespaces and you have to guess which fn is from which ns :)

JW

Gary Trakhman

unread,
Jul 23, 2013, 2:27:40 PM7/23/13
to clo...@googlegroups.com
We should scour clojuresphere for uses of 'use' and automatically post github issues to the projects of interest, and redefine the ns macro to issue a warning with use.  

Does anyone actually like 'use'? 

Require is always more evident.


--
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Lee Spector

unread,
Jul 23, 2013, 2:38:56 PM7/23/13
to clo...@googlegroups.com

On Jul 23, 2013, at 2:27 PM, Gary Trakhman wrote:

> We should scour clojuresphere for uses of 'use' and automatically post github issues to the projects of interest, and redefine the ns macro to issue a warning with use.
>
> Does anyone actually like 'use'?
>
> Require is always more evident.

I like it and I use it regularly, mainly, I guess, when all of the namespaces are my own and I know there are no conflicts. I split things into namespaces to keep the project organized, etc., but I don't want to have to qualify everything everywhere.

-Lee

Softaddicts

unread,
Jul 23, 2013, 2:45:41 PM7/23/13
to clo...@googlegroups.com
We have production code using it.
It's easy to say that it's a bad pattern after the fact.

We have been using it in a disciplined way.
It simplifies our life in the REPL we have some tools we want to see included
automatically each time we switch to a name space.

Anything else aside from clojure.core is required using an alias.
This minimized name clashes to zero so far.

This is easily spottable in the ns macro declarations and is not a source of
confusion for us.

We have less manipulations to do in the REPL when attaching to the live app
with these "defaults" included.

I do not mind about the deprecation warning as a first step.
However I would like some breathing space before it gets removed entirely.
It's just another to do on top of the pile of work we have these times...

Luc P.


> We should scour clojuresphere for uses of 'use' and automatically post
> github issues to the projects of interest, and redefine the ns macro to
> issue a warning with use.
>
> Does anyone actually like 'use'?
>
> Require is always more evident.
>
>
> On Tue, Jul 23, 2013 at 2:17 PM, Jozef Wagner <jozef....@gmail.com>wrote:
>
> > +1, :use is IMO an antipattern.
> >
> > I hate it mainly in blogs, where they explain some new API. They :use like
> > 3 namespaces and you have to guess which fn is from which ns :)
> >
> > JW
> >
> >
> > On Tuesday, July 23, 2013 5:50:50 PM UTC+2, Greg Slepak wrote:
> >>
> >> I think I read somewhere that :use is no longer encouraged, but I could
> >> be mistaken.
> >>
> >> From what I've read, it seems like most people agree that Clojure has too
> >> many ways of including/importing/**referencing/requiring/using things:
> >>
> >> http://blog.8thlight.com/**colin-jones/2010/12/05/**
> >> clojure-libs-and-namespaces-**require-use-import-and-ns.html<http://blog.8thlight.com/colin-jones/2010/12/05/clojure-libs-and-namespaces-require-use-import-and-ns.html>
--
Softaddicts<lprefo...@softaddicts.ca> sent by ibisMail from my ipad!

Steven Degutis

unread,
Jul 23, 2013, 2:46:54 PM7/23/13
to clo...@googlegroups.com
For much the same reason, I've been using :require with :as and a one-or-two-letter alias, so I can do x/whatever. Generally works well.


Sean Corfield

unread,
Jul 23, 2013, 3:04:14 PM7/23/13
to clo...@googlegroups.com
We only have :use in a couple of "legacy" tests and two scratch
projects. We've switched from :use to :require .. :refer :all for
situations where :use used to make sense (primarily in a test ns where
we want to just refer in all of the ns being tested). We have a
handful of places where we :refer :all elsewhere because the code
reads better without ns aliases all over the place and we bring in a
lot of functions.

Certainly in blogs and documentation, :require .. :as short alias
seems a better approach for teaching / explaining things but I'm sure
I'm guilty of :use in earlier blog posts about Clojure (... checking
... yup, three blog posts from early 2012 contain :use, mostly with
:only, so those should be updated to use :require / :refer instead).

Sean
--
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/

"Perfection is the enemy of the good."
-- Gustave Flaubert, French realist novelist (1821-1880)

Gary Trakhman

unread,
Jul 23, 2013, 3:06:23 PM7/23/13
to clo...@googlegroups.com
Yea, I have a single namespace with project-specific common utilities which I refer to as u/some-util-function.  For me, it's a bit scary to have implicit symbols in scope.  A typo can make a local binding refer to something that might not exist in production, or at least not what's intended. Conversely, I don't want extra code in my project that has nothing to do with the project.  Seems useful to enforce a separation of the artifact from the tools that made it, more-so for a lib that other things depend on than a production app.

The 'user' namespace can cover the use-case of convenience functions?

Or, you can add those symbols dynamically at run-time when you need to with something like: 

or some aggregated (require ..) calls.

Cedric Greevey

unread,
Jul 23, 2013, 3:08:33 PM7/23/13
to clo...@googlegroups.com
:use...:only doesn't strike me as especially problematic, since it documents the specific symbols it's importing and from where.

Gary Trakhman

unread,
Jul 23, 2013, 3:26:17 PM7/23/13
to clo...@googlegroups.com
What's problematic about it is that it's slightly easier to do the wrong thing.  It seems insignificant, but 98% of times you use use, it's going to be wrong.  Also, 'use only' means I have to change my calling NS twice in different parts of the emacs buffer any time I change a function name in the called namespace.

Shantanu Kumar

unread,
Jul 23, 2013, 3:42:39 PM7/23/13
to clo...@googlegroups.com
One of the main issues I have faced with :use is, understanding a non-trivial codebase becomes very difficult and almost always requires Emacs Meta-dot.

I'd vote for deprecating :use.

Shantanu

Lee Spector

unread,
Jul 23, 2013, 3:57:00 PM7/23/13
to clo...@googlegroups.com

On Jul 23, 2013, at 3:06 PM, Gary Trakhman wrote:

> Yea, I have a single namespace with project-specific common utilities which I refer to as u/some-util-function. For me, it's a bit scary to have implicit symbols in scope. A typo can make a local binding refer to something that might not exist in production, or at least not what's intended. Conversely, I don't want extra code in my project that has nothing to do with the project. Seems useful to enforce a separation of the artifact from the tools that made it, more-so for a lib that other things depend on than a production app.
>
> The 'user' namespace can cover the use-case of convenience functions?
>
> Or, you can add those symbols dynamically at run-time when you need to with something like:
> https://github.com/flatland/useful/blob/develop/src/flatland/useful/ns.clj#L26
>
> or some aggregated (require ..) calls.
>

I'm sure I'm coming from a minority perspective on this, but for the kind of work I do it's often more important to be able to quickly sketch out and test ideas, without any ceremony about which functions come from where, than it is to ensure safety in a "production" environment which is really just me running it right now.

In fact I'd sometimes like to go the other way and use everything in a whole directory subtree, or even to get rid of "using" altogether and have the runtime system find the function wherever it can (within reason :-) and let me know if it can't or if there's a conflict.

I do understand that there are a great many programming contexts in which it would be foolish and dangerous to manage references so loosely and implicitly and dynamically. In fact it's a bad idea in some of my work too, so I'm slightly more disciplined than this some of the time.

But my point is just that different users will have different priorities, and from where I sit, at least, it'd be nice to keep :use.

-Lee

Cedric Greevey

unread,
Jul 23, 2013, 4:20:28 PM7/23/13
to clo...@googlegroups.com
On Tue, Jul 23, 2013 at 3:26 PM, Gary Trakhman <gary.t...@gmail.com> wrote:
What's problematic about it is that it's slightly easier to do the wrong thing.  It seems insignificant, but 98% of times you use use, it's going to be wrong.  Also, 'use only' means I have to change my calling NS twice in different parts of the emacs buffer any time I change a function name in the called namespace.


On Tue, Jul 23, 2013 at 3:08 PM, Cedric Greevey <cgre...@gmail.com> wrote:
:use...:only doesn't strike me as especially problematic, since it documents the specific symbols it's importing and from where.

Is it "wrong" 98% of the times you use ":use...:only"?

And if you change the name of the function "fnname" where it's defined, yeah you'll have to change "fnname" wherever it's used as well, whether those uses say "fnname" or "mylib.core/fnname" or "m/fnname" or even "(:require [mylib.core :refer :rename {fnname othername}])".

Of course, the latter suggests the question of whether it's "wrong" to use :require ... :refer :only as well. :)

Sean Corfield

unread,
Jul 23, 2013, 4:25:52 PM7/23/13
to clo...@googlegroups.com
On Tue, Jul 23, 2013 at 12:57 PM, Lee Spector <lspe...@hampshire.edu> wrote:
> I'm sure I'm coming from a minority perspective on this, but for the kind of work I do it's often more important to be able to quickly sketch out and test ideas, without any ceremony about which functions come from where, than it is to ensure safety in a "production" environment which is really just me running it right now.
>
> In fact I'd sometimes like to go the other way and use everything in a whole directory subtree, or even to get rid of "using" altogether and have the runtime system find the function wherever it can (within reason :-) and let me know if it can't or if there's a conflict.
>
> I do understand that there are a great many programming contexts in which it would be foolish and dangerous to manage references so loosely and implicitly and dynamically. In fact it's a bad idea in some of my work too, so I'm slightly more disciplined than this some of the time.
>
> But my point is just that different users will have different priorities, and from where I sit, at least, it'd be nice to keep :use.

Well, you can always use (require '[some.ns :refer :all]) instead of
(use 'some.ns) but I recognize the former is a lot more typing.

Certainly in the REPL, working in the user ns, I can see a good
argument for (use 'some.ns) while you're evolving a solution, but I
think :use in the ns macro should be deprecated (i.e., :use should at
some point go away but perhaps the use function should stay for
REPL-based exploration?).

Tightening up the ns macro so it issues warning for undocumented
constructs would also be a good idea:

(ns some.ns
(require [foo.bar :as f])) ;; supported and works, but really should
be :require instead!

Softaddicts

unread,
Jul 23, 2013, 4:37:53 PM7/23/13
to clo...@googlegroups.com
None of what has been said so far makes me believe that our usage of
"use" is "bad". It's like a rope, you can use it for useful purposes or you can
hang yourself. You use it at your own taste and will.

Lack of discipline does not constitute for me a reason to trash a feature as scarce
as his usefulness seems to be.

:refer :all can be used as badly as :use.

I am not convinced that removing a facade and leaving the feature available
through a backdoor makes life better for anyone. :use is easily searchable and
quite obvious. Not sure about spotting :refer :all in 15 name space require
clauses.

You will simply end up say "do not use refer all" instead
of warning against using use.

Gee, What a lot of "use"s in this thread :)

Luc P.
> --
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>
>

Gary Trakhman

unread,
Jul 23, 2013, 4:43:23 PM7/23/13
to clo...@googlegroups.com
I think what we're proposing is not about removing the capability to do 'use'.  That will remain, it's clojure after all.  You could also implement it yourself easily enough.  The issue is whether it's worthwhile to have it as a core function, without some kind of notice that better things exist.

For instance, we have defrecords now, no one's going to reach for defstruct because records are documented and promoted more thoroughly.  But 'use' is more pervasive, and also 'easier'.  As the language grows, it'll be good for newcomers to have less things to think about, so deprecation is a way to counter bad inertia.  

The damage of 'use' is also less visible on the small scale, so that's why it's hard to make an argument about it.  :require is proportionately more verbose for an effect.  Use's verbosity is inversely proportional to its effect, so it takes extra effort to limit its effects. 

A limited scope by default is what I mean by 'good', for similar reasons that clojure goes with 'immutability by default'.



 -Lee

Stefan Kamphausen

unread,
Jul 23, 2013, 4:50:34 PM7/23/13
to clo...@googlegroups.com


On Tuesday, July 23, 2013 9:42:39 PM UTC+2, Shantanu Kumar wrote:
One of the main issues I have faced with :use is, understanding a non-trivial codebase becomes very difficult and almost always requires Emacs Meta-dot.

which is particularly annoying when you read code on a blog (as mentioned by the OP) or on paper
 

I'd vote for deprecating :use.

inc

It complects require and refer ;-)

stefan

Ben Wolfson

unread,
Jul 23, 2013, 4:53:52 PM7/23/13
to clo...@googlegroups.com
On Tue, Jul 23, 2013 at 1:50 PM, Stefan Kamphausen <ska...@gmail.com> wrote:

It complects require and refer ;-)

How so?

--
Ben Wolfson
"Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure." [Larousse, "Drink" entry]

Sean Corfield

unread,
Jul 23, 2013, 4:55:12 PM7/23/13
to clo...@googlegroups.com
On Tue, Jul 23, 2013 at 1:53 PM, Ben Wolfson <wol...@gmail.com> wrote:
> On Tue, Jul 23, 2013 at 1:50 PM, Stefan Kamphausen <ska...@gmail.com>
> wrote:
>> It complects require and refer ;-)
> How so?

Because use = require + refer (essentially).

Lee Spector

unread,
Jul 23, 2013, 5:00:00 PM7/23/13
to clo...@googlegroups.com

On Jul 23, 2013, at 4:43 PM, Gary Trakhman wrote:
>
> For instance, we have defrecords now, no one's going to reach for defstruct because records are documented and promoted more thoroughly.

FWIW I'm even a contrarian on defstruct :-! although I've switched to records anyway on account of speed.


On Jul 23, 2013, at 4:55 PM, Sean Corfield wrote:
>
> Because use = require + refer (essentially).


Is using :refer :all semantically identical to using :use? Or does "essentially" have a gap here?

If it's identical then I guess I don't care much either way, although I'd prefer to stick with the shorter thing that's already in my code.

-Lee


Laurent PETIT

unread,
Jul 23, 2013, 5:06:58 PM7/23/13
to clo...@googlegroups.com
It's not as if *some* (cough cough) parts of Clojure were'nt
opinionated, right? :-)

Having in the (ns) macro the possibility to use :use, to use :require,
to use :refer-clojure, to use :require-macros can be daunting, and not
only for newcomers!

And not to mention that the vast majority of the docstring for ns
talks about :gen-class defaults !

And all this choice for only historical reasons is not opinionated
enough for my taste!

I'd be willing too, to deprecate a couple things:

:use :all in favor of :require :all
:use :only in favor of :require :only

Let's be opinionated! :-D

I think that's the only subset that has a chance to pass without
having to gather a commitee at the next Clojure-conj ;-)


2013/7/23 Softaddicts <lprefo...@softaddicts.ca>:

Ben Wolfson

unread,
Jul 23, 2013, 5:13:11 PM7/23/13
to clo...@googlegroups.com
On Tue, Jul 23, 2013 at 1:55 PM, Sean Corfield <seanco...@gmail.com> wrote:
On Tue, Jul 23, 2013 at 1:53 PM, Ben Wolfson <wol...@gmail.com> wrote:
> On Tue, Jul 23, 2013 at 1:50 PM, Stefan Kamphausen <ska...@gmail.com>
> wrote:
>> It complects require and refer ;-)
> How so?

Because use = require + refer (essentially).

If that's all that's required for one thing to complect two others, clojure's rife with the stuff. if-let complects if and let. Destructuring assignment complects assignment and getting values from a data structure (as the macroexpansion of (let [[a b] x]) demonstrates. split-with complects take-while and drop-while. let complects lambda abstraction and function application. Etc. I had assumed that "a complects b and c" on the one hand meant more than "a can be expressed using b and c" and on the other was a criticism.

Softaddicts

unread,
Jul 23, 2013, 5:21:25 PM7/23/13
to clo...@googlegroups.com
Maybe we need an simpler alternative to the ns macro without all
these complex options :)

With a short name like ns-stop-banging-your-head-on-the-wall :)

Or the reverse, ns-make-your-life-more-chaotic...

:)

Luc P.

Laurent PETIT

unread,
Jul 23, 2013, 5:24:52 PM7/23/13
to clo...@googlegroups.com
2013/7/23 Softaddicts <lprefo...@softaddicts.ca>:
> Maybe we need an simpler alternative to the ns macro without all
> these complex options :)
>
> With a short name like ns-stop-banging-your-head-on-the-wall :)

would violate the "rule" use often => short name ;-)

>
> Or the reverse, ns-make-your-life-more-chaotic...

Deal :-D

Stefan Kamphausen

unread,
Jul 23, 2013, 6:04:40 PM7/23/13
to clo...@googlegroups.com


On Tuesday, July 23, 2013 11:13:11 PM UTC+2, Ben wrote:
On Tue, Jul 23, 2013 at 1:55 PM, Sean Corfield <seanco...@gmail.com> wrote:
On Tue, Jul 23, 2013 at 1:53 PM, Ben Wolfson <wol...@gmail.com> wrote:
> On Tue, Jul 23, 2013 at 1:50 PM, Stefan Kamphausen <ska...@gmail.com>
> wrote:
>> It complects require and refer ;-)
> How so?

Because use = require + refer (essentially).

If that's all that's required for one thing to complect two others, clojure's rife with the stuff. if-let complects if and let. Destructuring assignment complects assignment and getting values from a data structure (as the macroexpansion of (let [[a b] x]) demonstrates. split-with complects take-while and drop-while. let complects lambda abstraction and function application. Etc. I had assumed that "a complects b and c" on the one hand meant more than "a can be expressed using b and c" and on the other was a criticism.


you're right.  I did not think a lot before writing the above.  Please, don't take it too seriously.


Kind regards,
Stefan

Sean Corfield

unread,
Jul 23, 2013, 6:07:16 PM7/23/13
to clo...@googlegroups.com
On Tue, Jul 23, 2013 at 2:13 PM, Ben Wolfson <wol...@gmail.com> wrote:
> If that's all that's required for one thing to complect two others,
> clojure's rife with the stuff. if-let complects if and let. Destructuring
> assignment complects assignment and getting values from a data structure (as
> the macroexpansion of (let [[a b] x]) demonstrates.

Those examples provide an overall simplification for common
constructs. As the 'use' docstring says, it is "Like 'require, but
also refers to each lib's namespace using clojure.core/refer." so it
explicitly combines two already somewhat complex operations.

When we added :refer to 'require' we also complected things but we
improved expressiveness and we allowed the overall 'ns' construct to
be more uniform and consistent so I think, on balance, that was a win
(and I certainly like having one construct - :require - in my ns
declarations rather than a mix of :use and :require). We probably
should have taken that opportunity to deprecate :use at the same time
but as I recall, :refer was added very late in the cycle and arguing
over deprecating :use would have detracted from the discussion of the
utility of adding :refer to :require in the first place.

John Gabriele

unread,
Jul 23, 2013, 9:21:58 PM7/23/13
to clo...@googlegroups.com
On Tuesday, July 23, 2013 11:50:50 AM UTC-4, Greg Slepak wrote:
I think I read somewhere that :use is no longer encouraged, but I could be mistaken.

From what I've read, it seems like most people agree that Clojure has too many ways of including/importing/referencing/requiring/using things:

http://blog.8thlight.com/colin-jones/2010/12/05/clojure-libs-and-namespaces-require-use-import-and-ns.html

The above gives a very nice explanation of all the various difference, but it also acknowledges their complexity.

Since :use uses :require, and since :require can do everything that :use can, can we simplify Clojure programming a bit for newcomers by deprecating the use of :use? The situation in ClojureScript is even worse because it adds :require-macros on top of all the other ways of including files.

Ideally, it would be awesome if there was just a single directive for everything, but perhaps there's some complicated low-level reason why that's not possible. :-\

Thoughts?


I find that use of `:use` makes code more difficult to read.

Names from clojure.core are written without the namespace; everything else I expect to see a namespace in front to provide context.

Yes, I also write dates like YYYY-MM-DD. :)

-- John

Ye He

unread,
Jul 24, 2013, 2:35:37 AM7/24/13
to clo...@googlegroups.com
Well, obviously :use can't be replaced by (require :refer). According to DRY, I strongly agree the deprecation of :use. But that doesn't mean interpreter shouldn't support it right now since we have legacy code base. However, we could come to an agreement to less use of :use. It's trivial to obey the rule with the help of some automation tools like Slamhound https://github.com/technomancy/slamhound which generates namespace import for you (of course, without :use). So why bother to use :use? My own experience when encountering the situation that I have to guess where a function belongs to is that I run Slamhound once and get a better ns declaration, then if I'm not allowed to change the code base, I revert it back.


On Wednesday, July 24, 2013 1:50:50 AM UTC+10, Greg Slepak wrote:
I think I read somewhere that :use is no longer encouraged, but I could be mistaken.

From what I've read, it seems like most people agree that Clojure has too many ways of including/importing/referencing/requiring/using things:

http://blog.8thlight.com/colin-jones/2010/12/05/clojure-libs-and-namespaces-require-use-import-and-ns.html

The above gives a very nice explanation of all the various difference, but it also acknowledges their complexity.

Since :use uses :require, and since :require can do everything that :use can, can we simplify Clojure programming a bit for newcomers by deprecating the use of :use? The situation in ClojureScript is even worse because it adds :require-macros on top of all the other ways of including files.

Ideally, it would be awesome if there was just a single directive for everything, but perhaps there's some complicated low-level reason why that's not possible. :-\

Thoughts?

Baishampayan Ghose

unread,
Jul 24, 2013, 2:40:57 AM7/24/13
to Clojure Group
Lee,

For that use-case, you can always use something like (:require the-ns
:refer :all).

Regards,
BG
> --
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>



--
Baishampayan Ghose
b.ghose at gmail.com

Michael Klishin

unread,
Jul 24, 2013, 2:45:56 AM7/24/13
to clo...@googlegroups.com

2013/7/24 Ye He <htt...@gmail.com>

Well, obviously :use can't be replaced by (require :refer).

Are you sure? require with :refer :all does exactly what :use does as far as I know.
 
According to DRY, I strongly agree the deprecation of :use. But that doesn't mean interpreter shouldn't support it right now since we have legacy code base. However, we could come to an agreement to less use of :use.

Ye He

unread,
Jul 24, 2013, 2:50:44 AM7/24/13
to clo...@googlegroups.com

Sorry, It's a typo. What I mean is it can be replaced. But you can't force people not to use :use without :only, and the tool I mentioned will replace that kind of misuses.

-- 
Regards,
Ye He
--
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+u...@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 a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/i2VzAlT6oqM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.

Michael Klishin

unread,
Jul 24, 2013, 2:54:24 AM7/24/13
to clo...@googlegroups.com
2013/7/24 Ye He <htt...@gmail.com>

But you can't force people not to use :use without :only, and the tool I mentioned will replace that kind of misuses.

I'd start by adding a scary warning to the compiler first,
and then remove support for :use in a couple of versions.

David Powell

unread,
Jul 24, 2013, 6:41:45 AM7/24/13
to clo...@googlegroups.com
I usually :use clojure.pprint and clojure.repl.  Nobody was hurt.

For everything else, I use :require/as.

-- 
Dave



On Tue, Jul 23, 2013 at 7:27 PM, Gary Trakhman <gary.t...@gmail.com> wrote:
We should scour clojuresphere for uses of 'use' and automatically post github issues to the projects of interest, and redefine the ns macro to issue a warning with use.  

Does anyone actually like 'use'? 

Require is always more evident.
On Tue, Jul 23, 2013 at 2:17 PM, Jozef Wagner <jozef....@gmail.com> wrote:
+1, :use is IMO an antipattern. 

I hate it mainly in blogs, where they explain some new API. They :use like 3 namespaces and you have to guess which fn is from which ns :)

JW


On Tuesday, July 23, 2013 5:50:50 PM UTC+2, Greg Slepak wrote:
I think I read somewhere that :use is no longer encouraged, but I could be mistaken.

From what I've read, it seems like most people agree that Clojure has too many ways of including/importing/referencing/requiring/using things:

http://blog.8thlight.com/colin-jones/2010/12/05/clojure-libs-and-namespaces-require-use-import-and-ns.html

The above gives a very nice explanation of all the various difference, but it also acknowledges their complexity.

Since :use uses :require, and since :require can do everything that :use can, can we simplify Clojure programming a bit for newcomers by deprecating the use of :use? The situation in ClojureScript is even worse because it adds :require-macros on top of all the other ways of including files.

Ideally, it would be awesome if there was just a single directive for everything, but perhaps there's some complicated low-level reason why that's not possible. :-\

Thoughts?

Thanks,
Greg

P.S. If this has already been brought up you have my sincere apologies.

--
Please do not email me anything that you are not comfortable also sharing with the NSA.

--
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.
 
 

--
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com.

Lee Spector

unread,
Jul 24, 2013, 8:12:48 AM7/24/13
to clo...@googlegroups.com

On Jul 24, 2013, at 2:40 AM, Baishampayan Ghose wrote:
>
> For that use-case, you can always use something like (:require the-ns
> :refer :all).

Thanks for the clarity BG.

I guess if/when it becomes necessary I'll convert all of my (:use the-ns) to (:require the-ns :use :all), although I don't really see why it's helpful to anyone to make me and other :use users do this.

-Lee

Phillip Lord

unread,
Jul 24, 2013, 8:15:53 AM7/24/13
to clo...@googlegroups.com

I use 'use' yes.

Take, for instance, this code. It uses my own library to generate a
series of logical statements (about pizza's -- there is a reason, daft
though it sounds).

https://github.com/phillord/tawny-pizza/blob/master/src/pizza/pizza.clj

It isn't until around the 300th line that I first use any of the
clojure.core functions (ignoring the 'ns' directive which obviously
comes first). Quite often when I use this library, I have to use
refer-clojure to switch the implicit clojure.core use off, because it
gets in the way; I would do the same thing with java.lang if I could but
as far as I can tell those symbols are there regardless of what I do.

I would defend this usage of use. I do not want to namespace qualify the
tawny.owl library; why should I do this when I have hundreds of calls to
this library and about 5 to clojure.core?

I'm happy for you to tell me why I am wrong on this. From this thread, I
understand I could achieve the same thing with :require and more typing;
this is not the point; pulling in one namespace into another sometimes
makes sense.

Phil



Gary Trakhman <gary.t...@gmail.com> writes:

> We should scour clojuresphere for uses of 'use' and automatically post
> github issues to the projects of interest, and redefine the ns macro to
> issue a warning with use.
>
> Does anyone actually like 'use'?
>
> Require is always more evident.
>
>
> On Tue, Jul 23, 2013 at 2:17 PM, Jozef Wagner <jozef....@gmail.com>wrote:
>
>> +1, :use is IMO an antipattern.
>>
>> I hate it mainly in blogs, where they explain some new API. They :use like
>> 3 namespaces and you have to guess which fn is from which ns :)
>>
>> JW
>>
>>
>> On Tuesday, July 23, 2013 5:50:50 PM UTC+2, Greg Slepak wrote:
>>>
>>> I think I read somewhere that :use is no longer encouraged, but I could
>>> be mistaken.
>>>
>>> From what I've read, it seems like most people agree that Clojure has too
>>> many ways of including/importing/**referencing/requiring/using things:
>>>
>>> http://blog.8thlight.com/**colin-jones/2010/12/05/**
>>> clojure-libs-and-namespaces-**require-use-import-and-ns.html<http://blog.8thlight.com/colin-jones/2010/12/05/clojure-libs-and-namespaces-require-use-import-and-ns.html>
Phillip Lord, Phone: +44 (0) 191 222 7827
Lecturer in Bioinformatics, Email: philli...@newcastle.ac.uk
School of Computing Science, http://homepages.cs.ncl.ac.uk/phillip.lord
Room 914 Claremont Tower, skype: russet_apples
Newcastle University, twitter: phillord
NE1 7RU

Laurent PETIT

unread,
Jul 24, 2013, 9:35:41 AM7/24/13
to clo...@googlegroups.com
2013/7/24 Lee Spector <lspe...@hampshire.edu>:

> I don't really see why it's helpful to anyone to make me and other :use users do this.

Lee, you were in the past really brilliant at showing me whre I
couldn't see, anymore, how difficult to grasp some Counterclockwise
features were.
This is what is called "curse of knowledge", I guess.

Having both :use and :require :refer :all falls under this definition,
I guess. You (and to some extent me) can easily play with both forms.
But why both forms ? That's curse of knowledge in action, because this
will make no sense at all for newcomers, and there's no good reason
for having both, except historical ones.

Lee Spector

unread,
Jul 24, 2013, 10:11:50 AM7/24/13
to clo...@googlegroups.com

On Jul 24, 2013, at 9:35 AM, Laurent PETIT wrote:
> You (and to some extent me) can easily play with both forms.
> But why both forms ? That's curse of knowledge in action, because this
> will make no sense at all for newcomers, and there's no good reason
> for having both, except historical ones.

Ah -- that I get. I hereby retract my grumbling :-).

-Lee

Takahiro Hozumi

unread,
Jul 24, 2013, 10:17:39 AM7/24/13
to clo...@googlegroups.com
> I hate it mainly in blogs, where they explain some new API. They :use like 3 namespaces and you have to guess which fn is from which ns :)

Agree.
Code is read much more often than it is written, so omitting a few character is not effective time-saving.
I also don't like :refer :all.
I think it should be considered hack rather than official feature.

On Wednesday, July 24, 2013 3:17:02 AM UTC+9, Jozef Wagner wrote:
+1, :use is IMO an antipattern. 

I hate it mainly in blogs, where they explain some new API. They :use like 3 namespaces and you have to guess which fn is from which ns :)

JW

On Tuesday, July 23, 2013 5:50:50 PM UTC+2, Greg Slepak wrote:
I think I read somewhere that :use is no longer encouraged, but I could be mistaken.

From what I've read, it seems like most people agree that Clojure has too many ways of including/importing/referencing/requiring/using things:

Softaddicts

unread,
Jul 24, 2013, 11:49:44 AM7/24/13
to clo...@googlegroups.com
I disagree, when I use tracing fns and other useful REPL tools,
I like to have them included without having to prefix them with an alias.

It's not a hack it's a feature and you are free to use it or not.
If code writers do not care about code readers it's a choice, maybe bad but
that decision is not yours to take. It's theirs in their own context.

Now this thread has slowly shifted to "can we streamline how we express this
feature" to "lets forbid this feature to be used". If ends up creating such
"policies" enforced by the language, it's the wrong route.

My answer to such proposals is a definite "no". This a red line to me that should
not be crossed.

Luc P.
> --
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>
>
--

Alex Baranosky

unread,
Jul 24, 2013, 12:16:54 PM7/24/13
to clo...@googlegroups.com
+1 for scary compiler deprecation warning for 1.6.0, then removing :use in the 1.7.0 release.

Alex Baranosky

unread,
Jul 24, 2013, 12:18:07 PM7/24/13
to clo...@googlegroups.com
If anyone needs help removing all their uses, Slamhound (https://github.com/technomancy/slamhound) does a decent, though not perfect, job of automating this.

Steven Degutis

unread,
Jul 24, 2013, 12:42:31 PM7/24/13
to clo...@googlegroups.com
If our votes count for anything, then I'd like to add +1 for getting rid of :use, and strongly discouraging :refer :all.

dennis zhuang

unread,
Jul 24, 2013, 12:45:14 PM7/24/13
to Clojure
I am using ':use' for my own namespaces.I know it's discouraged, but if i can control my own code,why not? Compiler can give me warnings and i process all warnings carefully.



2013/7/25 Steven Degutis <sbde...@gmail.com>



--
庄晓丹
Email:        killm...@gmail.com xzh...@avos.com
Site:           http://fnil.net
Twitter:      @killme2008


Phil Hagelberg

unread,
Jul 24, 2013, 12:50:23 PM7/24/13
to clo...@googlegroups.com
I can confirm that the point of adding :refer support to :require was to deprecate :use; I suggested this to Rich at the 2011 Conj when he mentioned the ns macro is too complicated, and he agreed it would be a good idea to enhance :require so that it would make :use unnecessary in order to reduce conceptual overhead. I submitted a patch, and it was applied for 1.4.0.

As far as I recall, this discussion was only around :use clauses in the ns macro. I think the clojure.core/use function is still very useful in the repl for things like tracing and pprint and don't foresee it going anywhere.

My assumption from our discussion would be that a warning would be added in a near release when :use was detected in the ns macro, and that it would be removed for Clojure 2.0 when backwards-incompatible changes are OK. But that's just my own guess; I don't know if Rich has any plans to do this.

-Phil

Softaddicts

unread,
Jul 24, 2013, 1:08:41 PM7/24/13
to clo...@googlegroups.com
This is quite decent.

Luc

Lee Spector

unread,
Jul 24, 2013, 1:14:28 PM7/24/13
to clo...@googlegroups.com

On Jul 24, 2013, at 12:45 PM, dennis zhuang wrote:
> I am using ':use' for my own namespaces.I know it's discouraged, but if i can control my own code,why not? Compiler can give me warnings and i process all warnings carefully.

I agree. But I do now see that it's really just about as good, and better for other reasons, to use :require :refer :all instead.

However, if the language then starts hassling me about using :require :refer :all then that will really rain on my parade. I don't want to have to jump through hoops to get different parts of my projects to see each other. Clojure already requires more of this than I'd prefer -- e.g. no way to require a whole subdirectory with a wildcard (and I understand this is unlikely to happen) -- and it'd be a drag to have to maintain lists of every function name everywhere.

-Lee

Alex Baranosky

unread,
Jul 24, 2013, 1:22:22 PM7/24/13
to clo...@googlegroups.com
Imo, as soon as you have to maintain other peoples' code that heavily uses naked use, require starts to look a whole lot nicer.

Softaddicts

unread,
Jul 24, 2013, 2:21:44 PM7/24/13
to clo...@googlegroups.com
Too much is the same as not enough.

People can choose to which extend they want to hang themselves, how thick the
rope they "use" should be and the height from which they will throw themselves to
insure a fast and painless deliverance, hopefully by breaking their neck
as fast as possible :)

There is significant risk to get hit by a car if you cross on foot a highway yet in some
countries people do this daily. Why bother about it ? You could preach about
safety for years in these countries without seeing a noticeable change.

Live and let die...

Personal tastes are just that... personal tastes.

Context should prevail over any dogma == pragmatism.

Luc P.

Cedric Greevey

unread,
Jul 24, 2013, 3:26:48 PM7/24/13
to clo...@googlegroups.com
On Wed, Jul 24, 2013 at 12:50 PM, Phil Hagelberg <ph...@hagelb.org> wrote:
My assumption from our discussion would be that a warning would be added in a near release when :use was detected in the ns macro, and that it would be removed for Clojure 2.0 when backwards-incompatible changes are OK.

You mean, the backwards-incompatible changes between Clojure 1.2 and Clojure 1.3 (ex: (factorial 100) blowing up with ArithmeticException in the latter but not the former) were *not* OK? :)

Philippe Guillebert

unread,
Jul 25, 2013, 5:07:20 AM7/25/13
to clo...@googlegroups.com
Hi list,

Just a thought, I usually limit my usage of (:use) to DSL-like functions, like for instance cascalog :
  (?<- (stdout) [?a ?b] (generator :> ?a ?b))

Without a use, or (:require :refer :all), this would become very cumbersome to read :

(cascalog/?<- (cascalog/stdout) [?a ?b] (generator :> ?a ?b))

The same applies to SQL DSLs like korma.

So, IMHO there are cases where (:use) simplifies things.

--
Philippe Guillebert


Mikera

unread,
Jul 25, 2013, 6:55:04 AM7/25/13
to clo...@googlegroups.com
On Tuesday, 23 July 2013 21:55:12 UTC+1, Sean Corfield wrote:
On Tue, Jul 23, 2013 at 1:53 PM, Ben Wolfson <wol...@gmail.com> wrote:
> On Tue, Jul 23, 2013 at 1:50 PM, Stefan Kamphausen <ska...@gmail.com>
> wrote:
>> It complects require and refer ;-)
> How so?

Because use = require + refer (essentially).

That's more like "composing" rather than"complecting" IMHO.

Composing is perfectly good practice: once you've made things "simple" (require and refer) then it's perfectly legitimate to compose them again in order to make things "easy" for users (use). Clojure does this all over the place in the name of user convenience (e.g. empty? = not + seq ).

Laurent PETIT

unread,
Jul 25, 2013, 7:09:15 AM7/25/13
to clo...@googlegroups.com
2013/7/25 Philippe Guillebert <philippe....@gmail.com>:
Again, it's not about getting rid of (:use) functionality, but rather
let everything be declared through (:require), and deprecating the use
of :use

(:use foo :only [a b c]) will become (:require foo :refer [a b c])
(:use foo) will become (:require foo :refer :all)

This will save lots of time and frustration among people trying to
remember why (:use :only) somewhere, why (:require :refer :all)
somewhere else, etc.

This is, IMHO, and it seems that Phil & other agree with that, the
simplest thing that has a chance to work, and maximizes cost/benefit
ratio.

>
>
>
> --
>
> Philippe Guillebert

Mikera

unread,
Jul 25, 2013, 7:23:39 AM7/25/13
to clo...@googlegroups.com
On Tuesday, 23 July 2013 16:50:50 UTC+1, Greg Slepak wrote:
I think I read somewhere that :use is no longer encouraged, but I could be mistaken.

From what I've read, it seems like most people agree that Clojure has too many ways of including/importing/referencing/requiring/using things:

http://blog.8thlight.com/colin-jones/2010/12/05/clojure-libs-and-namespaces-require-use-import-and-ns.html

The above gives a very nice explanation of all the various difference, but it also acknowledges their complexity.

Since :use uses :require, and since :require can do everything that :use can, can we simplify Clojure programming a bit for newcomers by deprecating the use of :use? The situation in ClojureScript is even worse because it adds :require-macros on top of all the other ways of including files.

Ideally, it would be awesome if there was just a single directive for everything, but perhaps there's some complicated low-level reason why that's not possible. :-\

Thoughts?

Thanks,
Greg

I don't think :use should be deprecated. Reasons:
- It's already out there in a lot of production code (most important reason!)
- It's a convenient feature: it saves typing out :require [.... :refer :all]. Not that this matters much in ns declarations, but it would annoy me when :use was perfectly functional for this case.
- It's consistent with "use", which is a very helpful short command for setting up a REPL session quickly. And saving typing definitely *does* matter in REPL sessions.
- There's no technical/logical problem with it (it's just a simple composition of require + refer)
- I personally find it a helpful pattern : often I want an entire namespace available, and I don't want to be manually requiring specific functions every time I need something new from the namespace. That's just pointless boilerplate to maintain.

I guess removing it would be a slight simplification to the already-complicated ns syntax, but to me that is vastly outweighed by the above.

If people want to write code-style tools that auto-convert :use into equivalent :require clauses then that is obviously fine. I wouldn't use such tools myself, but I'm all for people having flexibility to determine their own coding style.

But let's not get into the habit of making breaking changes that remove useful features without very good reasons.
 

Mikera

unread,
Jul 25, 2013, 7:51:12 AM7/25/13
to clo...@googlegroups.com
On Tuesday, 23 July 2013 19:17:02 UTC+1, Jozef Wagner wrote:
+1, :use is IMO an antipattern. 

I hate it mainly in blogs, where they explain some new API. They :use like 3 namespaces and you have to guess which fn is from which ns :)

Hmmm perhaps I'm guilty of this.

But I find code much more readable when it isn't full of aliases and I assume many other readers do too. Aliases IMHO add noise that distracts from the logic that you are trying to express.

Personally, it has never particularly bothered me which namespace a function is from while reading a blog post. I might need to know at some point in the future, but by then I'll actually be coding in an editor or a REPL, and then my editor/REPL will tell me.


Moritz Ulrich

unread,
Jul 25, 2013, 8:31:07 AM7/25/13
to clo...@googlegroups.com
> --

Just use (:require [foo.bar.cascalog :refer :all]).


--
Moritz Ulrich

Phillip Lord

unread,
Jul 25, 2013, 11:32:12 AM7/25/13
to clo...@googlegroups.com
Laurent PETIT <lauren...@gmail.com> writes:
> (:use foo :only [a b c]) will become (:require foo :refer [a b c])
> (:use foo) will become (:require foo :refer :all)

The same logic could suggest we remove "or" because we can express it
with "and" and "not".

> This will save lots of time and frustration among people trying to
> remember why (:use :only) somewhere, why (:require :refer :all)
> somewhere else, etc.

And cause frustration for people who find typing

(:require clojure.test :refer :all)

when they used to type

(:use clojure.test)

To me, the discussion seems to be confused; I understand why making an
implementation simpler is important. But removing a simple declaration
to replace it with a more complex one doesn't seem to make things
simpler to me.


Phil

Gary Trakhman

unread,
Jul 25, 2013, 11:43:45 AM7/25/13
to clo...@googlegroups.com
You could also do (use 'clojure.test) below the ns form.  One thing that generally annoys me with 'ns' is that people feel it's some magical thing that has to be in the head of every file, like java imports, but it's really just a macro.

It just goes to show that conventions are important.  

Curiously, and off-topic, why does core.clj have an 'ns' form and then proceeds to define the ns macro?


Nicola Mometto

unread,
Jul 25, 2013, 11:48:17 AM7/25/13
to clo...@googlegroups.com

Gary Trakhman writes:

> You could also do (use 'clojure.test) below the ns form. One thing that
> generally annoys me with 'ns' is that people feel it's some magical thing
> that has to be in the head of every file, like java imports, but it's
> really just a macro.
>
> It just goes to show that conventions are important.
>
> Curiously, and off-topic, why does core.clj have an 'ns' form and then
> proceeds to define the ns macro?

The ns form used when loading core.clj the first time is bootNamespace
from clojure.lang.RT
> --

Steven Degutis

unread,
Jul 25, 2013, 11:57:40 AM7/25/13
to clo...@googlegroups.com
I think that's a good thing. I like to think of (ns) like a magical thing that has to be at the head of every file. It gives me consistency and predictability. It lets me not have to think. I almost wish it were just some magical required thing.

-Steven

Laurent PETIT

unread,
Jul 25, 2013, 12:07:53 PM7/25/13
to clo...@googlegroups.com
2013/7/25 Phillip Lord <philli...@newcastle.ac.uk>:
> Laurent PETIT <lauren...@gmail.com> writes:
>> (:use foo :only [a b c]) will become (:require foo :refer [a b c])
>> (:use foo) will become (:require foo :refer :all)
>
> The same logic could suggest we remove "or" because we can express it
> with "and" and "not".

Except nobody complains about "or", "and" or "not" ;-)

>
>> This will save lots of time and frustration among people trying to
>> remember why (:use :only) somewhere, why (:require :refer :all)
>> somewhere else, etc.
>
> And cause frustration for people who find typing
>
> (:require clojure.test :refer :all)
>
> when they used to type
>
> (:use clojure.test)

Code is read more often than written.
Clojure makes default choices "easy", and non default choices "harder"
for a reason: to guide people.

It's like the mantra "if you find it hard to write, you may be doing
it wrong (though it's still possible to do)".

Also, for the REPL, there will still be the (use 'clojure.tests) call
that you can use in your REPL bootstrapping code.

> To me, the discussion seems to be confused; I understand why making an
> implementation simpler is important. But removing a simple declaration
> to replace it with a more complex one doesn't seem to make things
> simpler to me.

I don't think I'm confused, AFAIC: I'm not even thinking from the
implementation perspective, but from the consumer perspective.
It's also psychological: if you remove :use, even at the cost of
keeping :refer :all, that's one less top-level 'ns directive to
remember.


I agree that it is micro-optimization, but this counts too, noticeably
because it's one of the first things a newcomer is confronted to when
he starts seriously with the language.

Ryan Stradling

unread,
Jul 25, 2013, 3:01:01 PM7/25/13
to clo...@googlegroups.com
+1 on Phil's "proposal"
"My assumption from our discussion would be that a warning would be added in a near release when :use was detected in the ns macro, and that it would be removed for Clojure 2.0 when backwards-incompatible changes are OK."


Thanks
Ryan

Max Gonzih

unread,
Jul 26, 2013, 5:24:29 AM7/26/13
to clo...@googlegroups.com
Totally agree. :use is anti-pattern since :require :refer :all can do the same. If you have :use in ns macro and want to make :refer :all visible just put it at the end of ns macro, separated b empty line from other :require clauses. Having 2 ways of doing so simple thing as requiring code is misleading IMHO.


On Tuesday, July 23, 2013 6:50:50 PM UTC+3, Greg Slepak wrote:
I think I read somewhere that :use is no longer encouraged, but I could be mistaken.

From what I've read, it seems like most people agree that Clojure has too many ways of including/importing/referencing/requiring/using things:

http://blog.8thlight.com/colin-jones/2010/12/05/clojure-libs-and-namespaces-require-use-import-and-ns.html

The above gives a very nice explanation of all the various difference, but it also acknowledges their complexity.

Since :use uses :require, and since :require can do everything that :use can, can we simplify Clojure programming a bit for newcomers by deprecating the use of :use? The situation in ClojureScript is even worse because it adds :require-macros on top of all the other ways of including files.

Ideally, it would be awesome if there was just a single directive for everything, but perhaps there's some complicated low-level reason why that's not possible. :-\

Thoughts?

Thanks,
Greg

Phillip Lord

unread,
Jul 26, 2013, 6:52:57 AM7/26/13
to clo...@googlegroups.com


It's different, because it doesn't necessarily eval with the ns form.
So, for example, nrepl.el has an "eval ns form" command. This would not
work with a use form.
> --

--
Phillip Lord, Phone: +44 (0) 191 222 7827
Lecturer in Bioinformatics, Email: philli...@newcastle.ac.uk
School of Computing Science, http://homepages.cs.ncl.ac.uk/phillip.lord
Room 914 Claremont Tower, skype: russet_apples
Newcastle University, twitter: phillord
NE1 7RU

Phillip Lord

unread,
Jul 26, 2013, 7:09:53 AM7/26/13
to clo...@googlegroups.com
Laurent PETIT <lauren...@gmail.com> writes:
>> The same logic could suggest we remove "or" because we can express it
>> with "and" and "not".
>
> Except nobody complains about "or", "and" or "not" ;-)

Actually, they are a right pain when writing my library, because I
wanted to use them to mean something else. some was irritating for the
same reason.


>> And cause frustration for people who find typing
>>
>> (:require clojure.test :refer :all)
>>
>> when they used to type
>>
>> (:use clojure.test)
>
> Code is read more often than written.
> Clojure makes default choices "easy", and non default choices "harder"
> for a reason: to guide people.

And again, I an struggling to see when being able to write

(deftest hello
(is true))

is a bad thing. I agree, using many namespaces is problematic, I do
often use one.

>
> It's like the mantra "if you find it hard to write, you may be doing
> it wrong (though it's still possible to do)".
>
> Also, for the REPL, there will still be the (use 'clojure.tests) call
> that you can use in your REPL bootstrapping code.
>
>> To me, the discussion seems to be confused; I understand why making an
>> implementation simpler is important. But removing a simple declaration
>> to replace it with a more complex one doesn't seem to make things
>> simpler to me.
>
> I don't think I'm confused, AFAIC: I'm not even thinking from the
> implementation perspective, but from the consumer perspective.
> It's also psychological: if you remove :use, even at the cost of
> keeping :refer :all, that's one less top-level 'ns directive to
> remember.


I said the discussion was confused not you!

So far, I have see three main reasons for removing use.

1) It offends my idea of truth and beauty: only clojure.core should be
unnamespaced.

Counter argument 1: using deftest makes life a lot easier. And I have
files which have 100s of calls to a one namespace and none to
clojure.core.

Counter argument 2: the functionality will remain anyway.

Counter argument 3: so, don't use it then.

2) ns is too complex

Counter Argument:

Yes, it is, and it does confuse newcomers. I got confused, not least
because it accepts both vectors and lists (so two syntaxes with no
difference AFAICT). So

(ns a
[:use b])

(ns a
(:use b))

are the same.

It also has short cuts: so

(:use [a.b.c]) is the same as
(:use [a.b c]), (use library "a.b.c")

(:use [a.b c]) is different from
(:use [a b c]) (first is "use a.b.c" second is "use a.b and a.c").

It's got :as which means you need nesting. and you can combine this with
aliases. And I think you can drop the brackets so:

(ns a
(:use [b]))

is the same as

(ns a
(:use b))

All of this remains. It's still going to be complex.

Don't quote me on any of the statements made here; I was trying to do it
from memory to see if I remembered correctly.

3) Removing use will make things simpler

Counter Argument:

Only for people who don't use it, and they don't use it so who cares?
For people who do use it, we now have to do (:require x :refer :all)
instead of the more simple (:use x). And does refer all support exclude?
So can I do

(:require x :refer :all :exclude [a b c])?


> I agree that it is micro-optimization, but this counts too, noticeably
> because it's one of the first things a newcomer is confronted to when
> he starts seriously with the language.

I agree that it's good to simplify things. Confused as to how this
helps.

Phil

greenh

unread,
Jul 26, 2013, 1:30:04 PM7/26/13
to clo...@googlegroups.com
A couple thoughts, my own 2-cents-worth.

First, I think I’m seeing an entirely legitimate concern being expressed by some developers that :use complicates life in their shops. Contrariwise, there’s clearly a set of developers who are in environments where :use feels very natural, and is of considerable convenience.

As someone who is generally in the latter situation, I have a hard time with notion of getting rid of :use, but I can equally well picture myself doing Clojure environments where the restriction was pertinent.  So, how about if there was a compiler option that caused :use to be flagged with a warning or error? I’d say that was entirely acceptable solution that kept everyone happy.

In general: if you’re talking about expanding the existing functionality to help solve people’s problems, I’m all for it. If you’re talking about restricting existing functionality to require conformity with your particular vision, that’s a problem.

BTW, if you insist on making the :use functionality substantially less convenient, well, I know how I respond to such things. I recall a saying from long ago in the Lisp community that “if you don’t like the syntax, write your own!”---and so I do. I’ve already dealt with several perceived nuisances in existing Clojure by writing and using my own macros. Coming up with a custom replacement for the ns macro feels a little challenging, but I dare say I’d rise to the occasion if need be. If that becomes common practice, I’d say you’ve won the conformity battle but lost the war. (Hey, maybe we should get rid of macros to prevent such heinous acts, eh? It worked for Java…)

Next, there's an "I can't tell where identifiers come from" thought. Yeah, I've felt that pain, and as I've indicated, I'm situationally sympathetic. But here's a thought: how is this different from any programming language where one file/class/module/whatever can be included by another? Might there already be technology for dealing with it---even technology that doesn't involve manually qualifying every non-local identifier?

Finally, with respect to the “it’s too hard for newcomers” line of argumentation, my reaction is: this is silly.  Do you really want to optimize Clojure for use by newcomers?  Assuming you managed such a thing, would the result still be useful to experienced programmers---who are, after all, are the main constituency for Clojure? Newcomers don’t tend to stay newcomers for very long, right?

Similarly, with respect to the “ns is too complex” meme, my response is: gimme a break. It really isn’t all that complicated, and reducing its set of options by one isn’t going to change that very much. In the overall scheme of things involving functional programming in general and Clojure in particular, this tiny spec of complexity hardly signifies.

Now, what is a problem is one of explanation---like, how to make newcomers aware of a good-enough set of recipes to get them going, or a lucid description of what the options actually are, and where they should be applied.

So, here's a suggestion: improve the documentation!! Have you looked at the docstring associated with ns? Yeeesh!  It’s all proper and correct, and about as profoundly uninformative as can be. (I’ve been doing Clojure intensively for about three years now, and just now I had a hard time even parsing it.)

In fact, I think I’d generalize on this, as a lot of the docstrings in core Clojure are, um, terse… so I’d suggest that if Clojure 2.0 is afoot, improving the documentation would be an excellent goal.

FWIW...


Howard


Gary Trakhman

unread,
Jul 26, 2013, 2:30:58 PM7/26/13
to clo...@googlegroups.com
This post takes quite a lot of things to extremes, but I think the main argument still stands.  

We need good defaults, not to totally change clojure into a newbie-friendly thing at the expense of what makes clojure special.  This proposed change fixes a pervasive pain point in many codebases because :use is easy in the small and complex in the large, and it does it by simply raising the perceived cost of 'use' slightly.

We spent time at my company on our own internal style debate over this, and I'm sure other companies do the same.  Any time I spend significant time in a namespace, I move the code over to :require, so that's already not-inconsequential effort that doesn't need to exist.

Advanced users are willing/able to do whatever it takes to make things easier for themselves, adjust to change quickly, and are likely more vocal and critical about change in the first place.  I think that the negative impact of a change will always be a bit overblown.

I guess it comes down to whether the negative impact is outweighed by the increase in clarity.  Negative impact is obvious and instant, clarity is mostly invisible and its benefits are realized over time.

People need some kind of feedback, a change in core is far-reaching with some downsides.


Phil Hagelberg

unread,
Jul 26, 2013, 5:22:47 PM7/26/13
to clo...@googlegroups.com
On Friday, July 26, 2013 10:30:04 AM UTC-7, greenh wrote:
Finally, with respect to the “it’s too hard for newcomers” line of argumentation,
> my reaction is: this is silly.  Do you really want to optimize Clojure for use by newcomers?

The original complaint was not that it's too hard for newcomers, it was was that Rich Hickey was saying every time he had to create a new namespace he couldn't remember how it worked and had to go copy from an existing example.

-Phil

Softaddicts

unread,
Jul 26, 2013, 6:10:33 PM7/26/13
to clo...@googlegroups.com
I do the same but it's because of my age and failing memory,
glad that some younger folks face the same issue :)

Luc P.


> On Friday, July 26, 2013 10:30:04 AM UTC-7, greenh wrote:
> > Finally, with respect to the “it’s too hard for newcomers” line of > argumentation,
> > my reaction is: this is silly. Do you *really* want to optimize Clojure > for use by newcomers?
> > The original complaint was not that it's too hard for newcomers, it was was > that Rich Hickey was saying every time he had to create a new namespace he > couldn't remember how it worked and had to go copy from an existing example.
> > -Phil
> > -- > -- > You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

Colin Fleming

unread,
Jul 27, 2013, 6:57:45 AM7/27/13
to clo...@googlegroups.com
From another point of view, as a tool developer if you want to accurately parse ns declarations it's extremely difficult. :use is a beast, and the number of options you can potentially combine are crazy. This is mostly due to the fact that :use combines what most people think of as :use and also everything from require (which was a surprise to me). So all of these are valid:

(ns test (:use [clojure.string :refer [trim] :only [split]]))
(ns test2 (:use [clojure.string :refer :all :only [split]]))
(ns test3 (:use [clojure.string :refer :all :exclude [split]]))
(ns test4 (:use [clojure.string :refer [trim] :exclude [trim]]))
(ns test5 (:use [clojure.string :as str :only [join] :refer [split] :exclude [trim] :rename {reverse rev}]))

Anyone care to wager what those actually do without trawling through the code? In fact, even if you trawl through the code it's far from trivial. Those are just of the top of my head, I'm sure there are weirder cases.

Ye He

unread,
Aug 3, 2013, 10:25:34 PM8/3/13
to clo...@googlegroups.com
Yesterday, I spent hours trying to figure out why some code didn't work. The code is like so:
(defn replace-symbol-in-ast-node [old new ast]
  (tree-replace (symbol old) (symbol new) ast))

I use tree-replace directly like this:
(ast/tree-replace (symbol 'a) (symbol 'c) (ast/sexp->parsley '(+ a b)))

I thought the result would the the same but I was wrong. After hours of thinking, I finally figured it out.
Guess what? The 'symbol' function in the first code snippet is not the standard 'symbol'. It actually is:
(defn symbol [sym]
  (make-node :atom (core/vector (name sym))))

It's defined in another library. But I stupidly thought it was the standard 'symbol'.
Part of this was my fault, I guess. I shouldn't have taken it for granted and guessed its meaning. But who know? 
In my opinion if we use less :use, it would easier for others to read our code and less likely to misunderstand the meaning, or at least Do Not Use those standard names.

Takahiro Hozumi

unread,
Aug 3, 2013, 10:52:09 PM8/3/13
to clo...@googlegroups.com
Hi Ye,

> or at least Do Not Use those standard names.

The following guide suggests the opposite.

> Use good names, and don't be afraid to collide with names in other namespaces. That's what the flexible namespace support is there for.

Takahiro

Softaddicts

unread,
Aug 3, 2013, 11:10:34 PM8/3/13
to clo...@googlegroups.com

You did not get a warning that "symbol" was overriding the core symbol fn ?

Luc P.

> Yesterday, I spent hours trying to figure out why some code didn't work.
> The code is like so:
> (defn replace-symbol-in-ast-node [old new ast]
> (tree-replace (symbol old) (symbol new) ast))
>
> I use tree-replace directly like this:
> (ast/tree-replace (symbol 'a) (symbol 'c) (ast/sexp->parsley '(+ a b)))
>
> I thought the result would the the same but I was wrong. After hours of
> thinking, I finally figured it out.
> Guess what? The 'symbol' function in the first code snippet is not the
> standard 'symbol'. It actually is:
> (defn symbol [sym]
> (make-node :atom (core/vector (name sym))))
>
> It's defined in another library. But I stupidly thought it was the standard
> 'symbol'.
> Part of this was my fault, I guess. I shouldn't have taken it for granted
> and guessed its meaning. But who know?
> In my opinion if we use less :use, it would easier for others to read our
> code and less likely to misunderstand the meaning, or at least *Do Not Use *those
> standard names*.*
>
>
> On Wednesday, July 24, 2013 1:50:50 AM UTC+10, Greg wrote:
> >
> > I think I read somewhere that :use is no longer encouraged, but I could be
> > mistaken.
> >
> > From what I've read, it seems like most people agree that Clojure has too
> > many ways of including/importing/referencing/requiring/using things:
> >
> >
> > http://blog.8thlight.com/colin-jones/2010/12/05/clojure-libs-and-namespaces-require-use-import-and-ns.html
> >
> > The above gives a very nice explanation of all the various difference, but
> > it also acknowledges their complexity.
> >
> > Since :use uses :require, and since :require can do everything that :use
> > can, can we simplify Clojure programming a bit for newcomers by deprecating
> > the use of :use? The situation in ClojureScript is even worse because it
> > adds :require-macros on top of all the other ways of including files.
> >
> > Ideally, it would be awesome if there was just a single directive for
> > everything, but perhaps there's some complicated low-level reason why
> > that's not possible. :-\
> >
> > Thoughts?
> >
> > Thanks,
> > Greg
> >
> > P.S. If this has already been brought up you have my sincere apologies.
> >
> > --
> > Please do not email me anything that you are not comfortable also sharing
> > with the NSA.
> >
> >
>

Ye He

unread,
Aug 3, 2013, 11:30:29 PM8/3/13
to clo...@googlegroups.com
What I mean is don't use it when you use :use.

Regards,
Ye He


--
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+u...@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 a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/i2VzAlT6oqM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.

Anthony Grimes

unread,
Aug 4, 2013, 7:09:20 PM8/4/13
to clo...@googlegroups.com
I can't think of a single good reason to not deprecate :use. :require can do everything :use could do now.

This isn't about whether or not (:use ..) without :only is bad. I'd go as far as to say that outside of test files (and sometimes not even those) and repl sessions, :use without :only is objectively bad. Not much justification you can give me that'll make it unbad. But that isn't what this is about. Deprecating :use doesn't make doing the aforementioned bad thing impossible, and :refer :all was added to require for that specific purpose. :require still lets you do bad things if you really want to. All we're doing by deprecating :use is removing cruft and making things less complicated for new people. We currently have two things, and one of them does all the things the other one does and more, yet we still have both of them.

Just my $0.02.

Korny Sietsma

unread,
Aug 5, 2013, 4:40:04 AM8/5/13
to clo...@googlegroups.com

Agree that :use should be deprecated, mostly as it's quite a barrier to folks new to the language that you need to know 3 different parts of the ns macro before you start.

However "objectively bad" is strong language indeed. ":refer :all" is vital anywhere you want a DSL - if using something like Korma, for example, you have 3 options :

1. Use :as and fill your code with ugly things like "(k/select user (k/where {:name [k/like " fred"]})

2. Use ":refer [select where like..." and almost every other symbol in Korma - might be ok if you have a perfect IDE, but still needlessly verbose

3. Use ":refer :all". It's perfectly fine, IMHO, when used responsibly.

- Korny

--
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com.

Steven Degutis

unread,
Aug 5, 2013, 4:50:34 AM8/5/13
to clo...@googlegroups.com
The only time I've seen :as lead to ugly code was when it was in a DSL that would probably have been nicer to use if it was a data-based DSL like Hiccup rather than code-based.

Phillip Lord

unread,
Aug 5, 2013, 6:35:22 AM8/5/13
to clo...@googlegroups.com
Anthony Grimes <discip...@gmail.com> writes:
> I can't think of a single good reason to not deprecate :use. :require can
> do everything :use could do now.

Wait for it, wait for it....

> This isn't about whether or not (:use ..) without :only is bad. I'd go as
> far as to say that outside of test files (and sometimes not even those) and
> repl sessions, :use without :only is objectively bad.

Yeah, you see, you can think of a single good reason, although you then
contradict yourself just to make it clear that it's not the case.

I mean, is there really any good reason why namespace qualifing
"deftest" should be necessary. Reason -- it's familiar and there are not
that many functions in clojure.test.

Another good reason, I have given before. I have written hundreds of
lines of code, with *no* calls at all to clojure.core, and lots to my
own library. Why under these circumstances is using clojure.core by
default and requiring my own library conducive to clear code?


> Not much justification you can give me that'll make it unbad. But that
> isn't what this is about. Deprecating :use doesn't make doing the
> aforementioned bad thing impossible, and :refer :all was added to
> require for that specific purpose. :require still lets you do bad
> things if you really want to. All we're doing by deprecating :use is
> removing cruft and making things less complicated for new people. We
> currently have two things, and one of them does all the things the
> other one does and more, yet we still have both of them.


Essentially, there are four things that can be done here. You can make
a function available (require), you make it usable by it's name (use),
you can make it available by it's namespace (refer), or you can make it
available to another name (aliasing).

The changes suggested do nothing toward reducing these things. As you
say, you will still able to do all of them. New people will find be
introduced to "use" in the repl and find no equivalent in the ns
directive. And lots of people will have to replace ":use" directives
with something else which does the same, but is longer.

Phil

Mikera

unread,
Aug 5, 2013, 8:13:02 AM8/5/13
to clo...@googlegroups.com
On Monday, 5 August 2013 09:40:04 UTC+1, Korny wrote:

Agree that :use should be deprecated, mostly as it's quite a barrier to folks new to the language that you need to know 3 different parts of the ns macro before you start.

I really don't think :use was ever a significant problem for newcomers: it's fairly obvious what it does if you come from another language that has similar package-importing constructs. The majority of other languages behave more like "use" than "require".

To me the things that make Clojure namespace handling a nightmare for beginners are:
- Bad error messages (no.1 problem!)
- Confusion with keywords vs. symbols (why ":use" in ns declarations vs "use" at the repl?)
- Confusion about quoting and when / where it is needed (again compared with "use" at the REPL)
- Confusion about when you should use lists vs. vectors vs symbols etc., and how this interacts with the extra magic syntax like ":as"
- Problems with circular loading of namespaces (and how this affects your code structure)
 
I count myself as someone who was quite confused by all these things initially, but I never had a problem understanding ":use" as a concept.

However "objectively bad" is strong language indeed. ":refer :all" is vital anywhere you want a DSL - if using something like Korma, for example, you have 3 options :

1. Use :as and fill your code with ugly things like "(k/select user (k/where {:name [k/like " fred"]})

2. Use ":refer [select where like..." and almost every other symbol in Korma - might be ok if you have a perfect IDE, but still needlessly verbose

3. Use ":refer :all". It's perfectly fine, IMHO, when used responsibly.

Absolutely agreed: method 3 is a decent approach for DSL scenarios. 

This is why I am in favour of keeping ":use" for such situations. There's no value in making a breaking change that removes a helpful syntactical feature (aside from wasting the time of people who like ":use", it will just make namespaces even more verbose and it will invalidate a lot of tutorials / example code which I don't think is very welcoming to newcomers either).

For example, which is easier to explain to a newcomer:

(ns foo
  (:use my.dsl)
  (:require [some.library :as bar])
  (:import baz.java.Class))

(ns foo
  (:require [my.dsl :refer :all])
  (:require [some.library :as bar])
  (:import baz.java.Class))

The second version is more verbose, has more "magic keywords" (count them!), and is IMHO somewhat confusing in the sense that you are using ":require" to do two very different things. ":use" is a simpler and more concise syntax for what the ns declarations above are trying to express (and has the advantage of consistency with "use" at the REPL).

Reductio ad absurdum: If we take the logic of deprecating ":use" and overloading ":require" to its logical conclusion, surely we should also deprecate ":import" and replace it with something like (:require [:java-package baz.java :java-classes [Class]])? Replacing ":import" in this way would also simplify ns declarations and make things easier for newcomers, right? :-)

Mikera

unread,
Aug 5, 2013, 8:15:23 AM8/5/13
to clo...@googlegroups.com
+1 to this - different operations deserve different names.

I'd add that there are many situations, especially when using DSLs, where you don't really want your code cluttered with aliases. It's just unnecessary noise - what you want to do is set up your namespace and have the relevant functions directly available as appropriate for you domain.

Aliases can also get problematic when you have to manage code that starts to have multiple aliases defined differently in different places. It makes refactoring / transferring code between namespaces much more fiddly, especially when code that used one alias in one namespace needs to be converted to use a different alias in another namespaces (also, aliases can collide too.....).

If you don't like"use" then just don't put it in your own code. But removing helpful existing functionality that many people have in their code bases as a breaking change just because some other people don't want to use it is bad language design IMHO.

Mikera

unread,
Aug 5, 2013, 8:22:43 AM8/5/13
to clo...@googlegroups.com
On Monday, 5 August 2013 09:50:34 UTC+1, Steven Degutis wrote:
The only time I've seen :as lead to ugly code was when it was in a DSL that would probably have been nicer to use if it was a data-based DSL like Hiccup rather than code-based.

It's pretty ugly to use aliases for numerical code, e.g. with core.matrix, e.g.

(mat/dot (ops/+ [1 2 3] 1) (ops/- [1 2 3] 1))

vs:

(dot (+ [1 2 3] 1) (- [1 2 3] 1))

Stefan Kamphausen

unread,
Aug 5, 2013, 8:28:07 AM8/5/13
to clo...@googlegroups.com


On Monday, August 5, 2013 2:13:02 PM UTC+2, Mikera wrote:

To me the things that make Clojure namespace handling a nightmare for beginners are:
- Bad error messages (no.1 problem!)
- Confusion with keywords vs. symbols (why ":use" in ns declarations vs "use" at the repl?)
- Confusion about quoting and when / where it is needed (again compared with "use" at the REPL)
- Confusion about when you should use lists vs. vectors vs symbols etc., and how this interacts with the extra magic syntax like ":as"
- Problems with circular loading of namespaces (and how this affects your code structure)

well summarized.

Greg

unread,
Aug 5, 2013, 10:04:59 AM8/5/13
to clo...@googlegroups.com
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?

-Greg

--
Please do not email me anything that you are not comfortable also sharing with the NSA.

signature.asc

Greg

unread,
Aug 5, 2013, 10:08:10 AM8/5/13
to clo...@googlegroups.com
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?

* Or for the more gentlemanly and considerate among us, just (:require ... :refer [+ - / *]).

-Greg

--
Please do not email me anything that you are not comfortable also sharing with the NSA.

signature.asc

Phillip Lord

unread,
Aug 5, 2013, 10:52:46 AM8/5/13
to clo...@googlegroups.com
Greg <gr...@kinostudios.com> 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

Greg

unread,
Aug 5, 2013, 12:00:54 PM8/5/13
to clo...@googlegroups.com
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.

signature.asc

Greg

unread,
Aug 5, 2013, 12:10:29 PM8/5/13
to clo...@googlegroups.com
* That email was just an idea to explore, not perfection.

Also, this is a mistake:

 (:require [clojure.core :refer [ancestors printf]]

Should read something like:

 (:require [clojure.core :refer-except [ancestors printf]]

- Greg

--
Please do not email me anything that you are not comfortable also sharing with the NSA.

signature.asc

Greg

unread,
Aug 5, 2013, 12:15:46 PM8/5/13
to clo...@googlegroups.com
Looking at it again, we don't even need an explicit :require anymore:

(ns one.fresh-server
  "optional doc string goes here"
  [clojure.core :refer-except [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])
- Greg

--
Please do not email me anything that you are not comfortable also sharing with the NSA.

signature.asc

Lee Spector

unread,
Aug 5, 2013, 12:18:33 PM8/5/13
to clo...@googlegroups.com

On Aug 5, 2013, at 4:40 AM, Korny Sietsma wrote:
>
> 3. Use ":refer :all". It's perfectly fine, IMHO, when used responsibly.

I agree in principle, but as I mentioned earlier in a related thread, when I actually tried to convert my :use instances to :require :refer :all I learned (I think!) that this cannot be done without substantially increasing the size of the ns declaration.

The problem is that :use allows one to list a bunch of namespaces in one declaration reasonably concisely, as in:

(ns use2require.core
(:use [use2require myfns yourfns]))

while :require :refer :all requires a separate entry (and a separate :refer :all) for each namespace, as in:

(ns use2require.core
(:require [use2require.myfns :refer :all]
[use2require.yourfns :refer :all]))

or

(ns use2require.core
(:require [use2require [myfns :refer :all]
[yourfns :refer :all]]))

Of course it's not a big deal with only two namespaces, but if you have dozens then this would be a real escalation in the size of the ns declaration.

Or am I missing something, and maybe there's a more concise way to use :require :refer :all that approximates the amount of code required for :use?

FYI the thread in which I previously posted this, and on which several others had comments, can be found at:

http://grokbase.com/t/gg/clojure/137v769emd/help-actually-changing-use-to-require-refer-all

If I haven't missed something then I'd advocate for an enhancement to :require :refer :all that fixes this OR the retention of :use.

-Lee

Lee Spector

unread,
Aug 5, 2013, 12:48:01 PM8/5/13
to clo...@googlegroups.com

On Aug 5, 2013, at 8:15 AM, Mikera wrote:

> On Monday, 5 August 2013 11:35:22 UTC+1, Phillip Lord wrote:
> Anthony Grimes <discip...@gmail.com> writes:
> > I can't think of a single good reason to not deprecate :use. :require can
> > do everything :use could do now.
>
> Wait for it, wait for it....
>
> > This isn't about whether or not (:use ..) without :only is bad. I'd go as
> > far as to say that outside of test files (and sometimes not even those) and
> > repl sessions, :use without :only is objectively bad.
>
> Yeah, you see, you can think of a single good reason, although you then
> contradict yourself just to make it clear that it's not the case.
>
> I mean, is there really any good reason why namespace qualifing
> "deftest" should be necessary. Reason -- it's familiar and there are not
> that many functions in clojure.test.
>
> Another good reason, I have given before. I have written hundreds of
> lines of code, with *no* calls at all to clojure.core, and lots to my
> own library. Why under these circumstances is using clojure.core by
> default and requiring my own library conducive to clear code?

I think that these are good points and that there are indeed good reasons to keep :use or something with equivalent functionality and conciseness (which, as far as I can tell, :require :use :all doesn't quite deliver).

More generally, I think we should keep in mind that different Clojure programmers work in different programming contexts with different needs and priorities.

In my own context it'd actually be best to be able to say (ns foo :use-whatever-you-need) and leave it to the system to find things and tell me if there are conflicts.

Yes, that would be insane in some contexts, and if I used this thing and then wanted to port my code to some other context, like controlling a nuclear power plant, then I'd want a utility function something like print-explicit-ns-declaration-for-everything-you-need, which I could use to produce the mess that I'd then substitute for the concise thing before it goes into production, so I could make sure that all of the references were really correct, etc.

I don't expect everyone to think this is a good idea in their programming contexts, but from where I sit it would really be fantastic. I also don't expect anyone to implement this unless they have similar needs and interests and time, and I don't expect Clojure to be changed to support anything like this. My point is just that the needs and priorities are diverse, and I wish people wouldn't be so enthusiastic about deprecating features that are valued by others in the community.

-Lee

Brian Marick

unread,
Aug 5, 2013, 2:42:59 PM8/5/13
to clo...@googlegroups.com
I find that having both `:use` and `:require` in my `ns` declarations can, with a little judicious formatting, communicate something about which packages are core and which are peripheral. Having to obfuscate that distinction with a `:refer :all` tacked - in a visually obscure way - onto `:require` forms would make me sad. Not wildly sad, but wistfully sad that people would prefer a breaking change to simply avoiding something they don't want to use.

Or:

On Aug 5, 2013, at 11:48 AM, Lee Spector <lspe...@hampshire.edu> wrote:

> My point is just that the needs and priorities are diverse, and I wish people wouldn't be so enthusiastic about deprecating features that are valued by others in the community.

--------
Latest book: /Functional Programming for the Object-Oriented Programmer/
https://leanpub.com/fp-oo

Softaddicts

unread,
Aug 5, 2013, 3:33:17 PM8/5/13
to clo...@googlegroups.com
I agree on this, just started to replace some :use by refer all and I have to
maintain the convention to place these at the end of the :require list
otherwise they get obfuscated if they end up in the middle.
There are only one or two per name space and we can have six to a dozen
required name spaces with aliases in our name spaces.

:use is much more obvious. we usually place them after the :require section and they
can not be missed by a reader.

I can live with this but not really convinced that it improves readability.
Still debatable.

Luc.
> --
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>
>

Phillip Lord

unread,
Aug 6, 2013, 7:22:35 AM8/6/13
to clo...@googlegroups.com


Struggling a bit. Moving the keywords to the end of the vector rather
than the beginning? This reduces complexity?

Phil

Greg

unread,
Aug 6, 2013, 10:58:36 AM8/6/13
to clo...@googlegroups.com
> Struggling a bit. Moving the keywords to the end of the vector rather
> than the beginning? This reduces complexity?

I changed the syntax a bit since posting that, please have a look at the "[Proposal] Simplified 'ns' declaration" thread.

- Greg

--
Please do not email me anything that you are not comfortable also sharing with the NSA.

signature.asc
Reply all
Reply to author
Forward
0 new messages