Using :refer 'sparingly'

540 views
Skip to first unread message

Akiva

unread,
May 17, 2015, 11:05:14 AM5/17/15
to clo...@googlegroups.com
In Stuart Sierra's article here
(http://stuartsierra.com/2015/05/10/clojure-namespace-aliases), he
recommends to use :refer sparingly but doesn't explain why this is a
good idea. Only thing I could think of without putting too much effort
into it is that it makes it slightly more tedious when you want to use a
function from a namespace that hasn't been already explicitly referred.

Are there no benefits other than possibly excluding function names that
might otherwise suffer a namespace clash (assuming their namespace isn't
being aliased already)?

Thanks,
Akiva

Max Countryman

unread,
May 17, 2015, 11:13:08 AM5/17/15
to clo...@googlegroups.com
I wonder if a reason could be to ensure it’s obvious where a function came from? For example (foo …) is ambiguous, it could be defined in the current namespace or it may have been referred from another whereas (my-ns/foo …) is explicit.
> --
> 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/d/optout.

Stuart Sierra

unread,
May 17, 2015, 11:21:31 AM5/17/15
to clo...@googlegroups.com, akiva....@gmail.com
Just like the rest of the article, it's about readability. With `:refer` you don't know where a symbol came from when you encounter it in the middle of the code.

–S

Akiva

unread,
May 17, 2015, 11:23:55 AM5/17/15
to clo...@googlegroups.com
Makes sense. I guess my other question then would be if there are any benefits to using :refer along with :as.

:A.

May 17, 2015 at 10:21 AM via Postbox
Just like the rest of the article, it's about readability. With `:refer` you don't know where a symbol came from when you encounter it in the middle of the code.

–S



On Sunday, May 17, 2015 at 4:05:14 PM UTC+1, Akiva Schoen wrote:
--
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/d/optout.
May 17, 2015 at 10:04 AM via Postbox
In Stuart Sierra's article here (http://stuartsierra.com/2015/05/10/clojure-namespace-aliases), he recommends to use :refer sparingly but doesn't explain why this is a good idea. Only thing I could think of without putting too much effort into it is that it makes it slightly more tedious when you want to use a function from a namespace that hasn't been already explicitly referred.

Are there no benefits other than possibly excluding function names that might otherwise suffer a namespace clash (assuming their namespace isn't being aliased already)?

Thanks,
Akiva

--
Sent from Postbox

Colin Yates

unread,
May 17, 2015, 11:29:13 AM5/17/15
to clo...@googlegroups.com
As stated in the article, I find the extra context of using :as aids
maintenance more than you might expect. The only time I use refer is
if the referred vars are conceptually owned, or the context is
implicit by the name space using them. For me it is about
responsibility and ignorance. :as implies distance/ignorance, :refer
implies closeness/knowledge.

A concrete example, in my use-case tests I refer most vars from
clojure.test for convenience but the thing being tested is aliased as
'sut'. I could swallow referring the forms being tested in the test
case as well but I am used to the convention of 'sut' (subject under
test).

John Wiseman

unread,
May 17, 2015, 12:05:59 PM5/17/15
to clo...@googlegroups.com
There's a close parallel in Python, where the same issue comes up of typically using several modules or packages in a source file and the language offers a way to import the functions and classes of those modules in such a way that they can be used without any syntactic marker of their origin.  For years I've used the Google style guideline which says "Use imports for packages and modules only", as distinct from functions, classes, etc., and the justification is "The source of each identifier is indicated in a consistent way; x.Obj says that object Obj is defined in module x".

I've found that when reading code that I haven't written it lowers the friction for understanding just a little bit but that's multiplied by roughly the number of names in the source code.  It makes it (mostly) self-evident whether an identifier names a concept from the file I'm looking at, or somewhere else.  And if it's from somewhere else, it says right there where that other place is.  It's a significant advantage and I think the same advantage applies to clojure source code.



Daniel Compton

unread,
May 17, 2015, 4:30:32 PM5/17/15
to clo...@googlegroups.com
I'm not sure if this is idiomatic, but I often like to refer any def* functions or macros, and :as alias the rest. I just prefer the visual look of a bare def without a prefix. There's usually only a couple of those in a codebase so it doesn't add too much overhead.

Christopher Small

unread,
May 17, 2015, 7:57:30 PM5/17/15
to clo...@googlegroups.com
I agree with the general sentiment expressed here, but would just like to add that `:refer`-ing a few frequently used functions (as Colin Yates stated, particularly when it's assumed there is strong coupling or closeness between the two namespaces involved), is a much more minor nuisance than `:refer :all`. At least with `:refer [some-fn some-other-fn]`, you _can_ figure out where the function came from by going up to the `ns` declaration, and if you're fast with your editor, this is easy to do. Both `:refer :all` and `:use`/ `(use)` should (IMHO) only be used for hacking around at the repl.

Luc Prefontaine

unread,
May 18, 2015, 6:22:28 AM5/18/15
to clo...@googlegroups.com
We systematically use refer all on tools.trace and a few other of our name spaces used for production support.

It becomes handy in a live repl in production.

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/d/optout.
>
--
Luc Prefontaine<lprefo...@softaddicts.ca> sent by ibisMail!

Akiva

unread,
May 27, 2015, 1:30:54 PM5/27/15
to clo...@googlegroups.com
I've been using :refer [...] exclusively but I've been growing increasingly disenchanted with it; it's just a nuisance when you're interrupted by having to address the ns to add a command you didn't previously know you needed. On the other hand, not using :as can become just as much of a nuisance especially during debugging in a ns that has many requires.

My idea now is to use :as always, as Stuart suggests, but then :refer when it helps decrease the inline noise or when the usage is obvious (for example, hiccup.core's html function although I wouldn't argue that h/html isn't also just as fine). I think now this is what Stuart was originally encouraging but in the post he never explained why to use refer sparingly. He just mentioned using it for non-alphanumeric functions. And I like the idea expressed by Daniel using it for def* functions and macros.

One last note: I used to use :refer :all exclusively in the REPL just to save keystrokes. But now I follow the standard of whatever code I'm working with because the moment you start sending sexps over from [insert-your-editor-of-choice] to be evaluated, having the namespaces the same is essential.

May 18, 2015 at 5:22 AM via Postbox
We systematically use refer all on tools.trace and a few other of our name spaces used for production support.

It becomes handy in a live repl in production.

Luc P.


--
Luc Prefontaine<lprefo...@softaddicts.ca> sent by ibisMail!

May 17, 2015 at 6:57 PM via Postbox
I agree with the general sentiment expressed here, but would just like to add that `:refer`-ing a few frequently used functions (as Colin Yates stated, particularly when it's assumed there is strong coupling or closeness between the two namespaces involved), is a much more minor nuisance than `:refer :all`. At least with `:refer [some-fn some-other-fn]`, you _can_ figure out where the function came from by going up to the `ns` declaration, and if you're fast with your editor, this is easy to do. Both `:refer :all` and `:use`/ `(use)` should (IMHO) only be used for hacking around at the repl.
--
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/d/optout.
May 17, 2015 at 3:30 PM via Postbox
I'm not sure if this is idiomatic, but I often like to refer any def* functions or macros, and :as alias the rest. I just prefer the visual look of a bare def without a prefix. There's usually only a couple of those in a codebase so it doesn't add too much overhead.
--
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/d/optout.
May 17, 2015 at 11:05 AM via Postbox
There's a close parallel in Python, where the same issue comes up of typically using several modules or packages in a source file and the language offers a way to import the functions and classes of those modules in such a way that they can be used without any syntactic marker of their origin.  For years I've used the Google style guideline which says "Use imports for packages and modules only", as distinct from functions, classes, etc., and the justification is "The source of each identifier is indicated in a consistent way; x.Obj says that object Obj is defined in module x".

I've found that when reading code that I haven't written it lowers the friction for understanding just a little bit but that's multiplied by roughly the number of names in the source code.  It makes it (mostly) self-evident whether an identifier names a concept from the file I'm looking at, or somewhere else.  And if it's from somewhere else, it says right there where that other place is.  It's a significant advantage and I think the same advantage applies to clojure source code.





--
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/d/optout.
May 17, 2015 at 10:28 AM via Postbox
As stated in the article, I find the extra context of using :as aids
maintenance more than you might expect. The only time I use refer is
if the referred vars are conceptually owned, or the context is
implicit by the name space using them. For me it is about
responsibility and ignorance. :as implies distance/ignorance, :refer
implies closeness/knowledge.

A concrete example, in my use-case tests I refer most vars from
clojure.test for convenience but the thing being tested is aliased as
'sut'. I could swallow referring the forms being tested in the test
case as well but I am used to the convention of 'sut' (subject under
test).



--
Sent from Postbox
Reply all
Reply to author
Forward
0 new messages