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

Add std.core/def- #20

Closed
wants to merge 1 commit into from
Closed

Add std.core/def- #20

wants to merge 1 commit into from

Conversation

andrewberls
Copy link
Contributor

def- is the missing counterpart to defn- for defining private
bindings, as opposed to strictly private functions.

There is much debate in community about the absence of def- [0][1], with
many pointing out the alternative: (def ^{:private true} x 2).
However, defn- is quite pervasive in Clojure code, and so it seems
reasonable to offer def- as a library alternative, at least.

0: https://groups.google.com/forum/#!topic/clojure/O7xWh72zzuo
1:
https://groups.google.com/forum/#!msg/clojure/r_ym-h53f1E/y1S31QXNhcAJ

@andrewberls andrewberls requested a review from elliot42 March 27, 2017 22:44
`def-` is the missing counterpart to `defn-` for defining private
bindings, as opposed to strictly private functions.

There is much debate in community about the absence of def- [0][1], with
many pointing out the alternative: `(def ^{:private true} x 2)`.
However, `defn-` is quite pervasive in Clojure code, and so it seems
reasonable to offer `def-` as a library alternative, at least.

0: https://groups.google.com/forum/#!topic/clojure/O7xWh72zzuo
1:
https://groups.google.com/forum/#!msg/clojure/r_ym-h53f1E/y1S31QXNhcAJ
@andrewberls andrewberls force-pushed the aberls/add-core-def- branch from e0e8e43 to a992622 Compare March 27, 2017 22:46
@elliot42
Copy link
Member

Further debate:

bbatsov/clojure-style-guide#124

Given the style guide doesn't endorse it, and the core team doesn't endorse it, for seemingly reasonable reasons, I am not inclined to support this myself. To the contrary, I would rather see an api namespace where everything is public, than a namespace that is mixing private and public functions, which is almost always an enormous pain organizing which/which order to put the private stuff, especially since in Clojure all of the private stuff would need to go at the top, not at the bottom of the file.

I remain super unconvinced of any of this public vs. private construct in basically any language. It seems like an unnecessary construct when you can just put the internal stuff in an internal namespace, and put the public facing API in an api namespace--every language I can think of seems cleaner and simpler when there is not time spent fiddling with this stuff.

@andrewberls
Copy link
Contributor Author

andrewberls commented Apr 4, 2017

I find the style guide pretty oddly inconsistent in that (def ^:private private-var ...) is encouraged but (defn ^:private private-fun [] ...) is deemed too verbose, with defn- recommended instead. It seems that to truly follow the core's sentiment, you would ban defn- in your styleguide and codebase to follow suit. I think we should take a hard line either way rather than existing in the middle.

Personally, I think defn- is quite concise and elegant, and find the lack of def- unfortunate. That's why I think the ability to offer it in a library is quite nice - to me utility libraries offer choice and flexibility. For those who want def- it can be available, for those who disagree they can avoid it. I've never bought the slippery slope argument much ("why not defmulti- / defprotocol- / etc?") as def/defn are the overwhelmingly present duo. In any case, most important to me is choosing a stance and sticking with it consistently, as I think we're in-between.

(The existence of visibility modifiers at all is interesting, but a bit out of scope I think)

@elliot42
Copy link
Member

Did you still want this? I feel like I'm....willing to compromise on this one at this point, though I'm not clear if this implementation fully works like one might expect it to, e.g. presumably one can't do the following?

(def- ^{:my-other-meta-stuff :foobar} baz :quux)

(Because the additional metadata won't compose in.)

@gnl
Copy link

gnl commented Apr 10, 2018

In order not to override any additional metadata, it probably should be something like this:

(defmacro def-
  [sym form]
  `(def ~(vary-meta sym assoc :private true) ~form))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants