Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

defn- vs. defn ^:private #124

Open
looselytyped opened this Issue Nov 24, 2015 · 13 comments

Comments

Projects
None yet
8 participants
@looselytyped
Copy link

looselytyped commented Nov 24, 2015

Looking here it is suggested that

;; good
(defn- private-fun [] ...)

(defn ^:private private-fun [] ...) ; overly verbose

However reading up on this Google group discussion it seems that using defn- is a bit contradictory since there are other def that do not have a complimentary def- option. Quoting Vincent

It's better to use ^:private metadata on the symbol naming the var, since there is also defmacro, defmulti, etc, which not have hyphened versions too.

Should this continue to remain in the styleguide?

(I can submit a PR to make the change, however I felt that perhaps having a discussion prior to that would be appropriate)

@bbatsov

This comment has been minimized.

Copy link
Owner

bbatsov commented Jan 21, 2016

That's one interesting point. However, I don't recall ever seeing private macros or multimethods. Maybe we should just extend this a bit, to mention this consideration.

@eigenhombre

This comment has been minimized.

Copy link

eigenhombre commented Jan 22, 2016

My team prefers (defn ^:private ...) because it's consistent with the way to def a private var.

@philjackson

This comment has been minimized.

Copy link

philjackson commented Jan 25, 2016

We prefer defn- here and lament the lack of def-. I personally consider ^:private to be ugly.

@arrdem

This comment has been minimized.

Copy link
Contributor

arrdem commented Jan 25, 2016

def- and soforth don't exist for good reason, you get a combinatorial explosion for every variation. Having def- begs the question of why we don't have defmulti-, defprotocol- and on down the line. How about definline-. Maybe you want a postfix so you can elide ^:dynamic. Lets say -d. Now defd-? ^:static with -s, defs, so you also need defs-? This gets really silly really quickly and doesn't exist for this reason. I suspect were someone to do-over Clojure defn- probably wouldn't make the cut. Because the -- convention isn't a general thing, ^:private should be preferred since it does work everywhere and is explicit in its meaning.

Edit: said prefix, meant postfix.

@halgari

This comment has been minimized.

Copy link

halgari commented Jan 25, 2016

And then there's some that would argue that since :private doesn't really work the way you'd think (private vars can still be accessed via #'), and it inhibits testing, that we should prefer public vars over private vars.

@arrdem

This comment has been minimized.

Copy link
Contributor

arrdem commented Jan 25, 2016

There are some projects where people attempted to java-style provide a public API hiding implementation details and helper functions... my experience with ^:private is that I've just used #' to get around it when I found it convenient (meaning ^:private was useless), and that when I used it myself ^:private vars just got moved into util namespaces and ^:private got dropped. So I'm in the "just don't bother" camp mentioned by tb.

@puredanger

This comment has been minimized.

Copy link

puredanger commented Jan 25, 2016

@halgari I think ^:private is a useful way to indicate author intention as to which parts of the ns are considered subject to change and which aren't. While it doesn't mean the same thing as it does in other languages, it's still useful.

I personally use and prefer defn- over defn with ^:private b/c it's shorter and again, concisely communicates intent.

@bbatsov I have seen private macros and multimethods (there are certainly some in Clojure itself).

@philjackson

This comment has been minimized.

Copy link

philjackson commented Jan 25, 2016

@arrdem defn is the most common of the symbols you list, having a short-cut for the privacy declaration doesn't seem harmful in any way. Consistency is often great, but in this case, I prefer the conciseness.

@bbatsov

This comment has been minimized.

Copy link
Owner

bbatsov commented Jan 26, 2016

I understand @arrdem's point, but it still makes sense to have shorthands for commonly used stuff (or there should be no shorthands at all for the sake of consistency). I think that def- and defmacro- would probably cover the majority of usages. Dynamic vars are pretty uncommon, so drawing a comparison to them is probably not a good idea. :-)

@andrewhr

This comment has been minimized.

Copy link

andrewhr commented Jan 26, 2016

My 2 cc: the ^:private form also helps with learning. Explaining that (fn []) and #() are quite the same is one thing, but the lack of (def-) & friends normally causes some confusion when you are new to the language.

@puredanger

This comment has been minimized.

Copy link

puredanger commented Jan 26, 2016

We will not be adding any other "-" forms to core. I think perhaps if we could do it over, defn- would not be added either, but we're not going to take it away.

@bbatsov

This comment has been minimized.

Copy link
Owner

bbatsov commented Jan 26, 2016

@puredanger What about simply deprecating it (defn-) and keep it around forever (Java-style)? Seems like a good middle-ground to me. Sends the message this was probably not a good idea (and people won't fret over the lack of def- and friends), but doesn't affect the users of the defn-.

@puredanger

This comment has been minimized.

Copy link

puredanger commented Jan 26, 2016

I don't think we want to deprecate it, we just don't want to take the idea any further.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.