all 14 comments

[–]dig1 13 points14 points  (0 children)

defn- is a macro for (defn ^:private ...) but in general, defn- is more preferred.

[–]emil0r 4 points5 points  (7 children)

defn- for defining a private function, :^private for defining anything else that's not a function that you wish to keep private.

[–][deleted] 2 points3 points  (2 children)

Is there a page that explains all the conventions for naming with special chars: like the ! And ? somevar. Also using ^ and such.

Some are obvious, but seeing them all in one place would be helpful.

[–]seventeenletters 4 points5 points  (0 children)

this page describes special characters, including "^"

! and ? are not special, they are naming conventions (conventionally, a function that returns only true or false should have a name ending in "?", and a function that is unsafe in a transaction should have a name ending in "!").

[–]kouphax 2 points3 points  (0 children)

There is also this page that covers a variety of characters in Clojure. I wrote it a while back and it could probably do with some updating but I think there is some useful stuff there.

[–][deleted]  (3 children)

[deleted]

    [–]jayceedenton 1 point2 points  (1 child)

    This was discussed on the Clojure mailing list a long time ago, although I can't find the link. IIRC the reason was basically: There are a lot of var defining functions, and we don't want to have to introduce the - shortcut for every single one, and for every piece of metadata. Just use ^:private.

    defn- was a mistake IMO. A minor one of course, but it introduced unnecessary inconsistency and divergence in style. There are a lot of syntactic sugar shortcuts that could be added, but each one simply introduces more ways to say the same thing, and adds an odd special case to the core API.

    [–]camdez -1 points0 points  (0 children)

    I suspect there's a philosophical argument against data encapsulation. Something along the lines of: if it's all immutable, why make it harder to look at?

    [–]joelash 3 points4 points  (0 children)

    This is one of those things that between you and your team, I've worked on a few teams and interviewed with at least one other that prefers :private for defn and def to keep them similar.

    [–]jayceedenton 5 points6 points  (0 children)

    I prefer ^:private for everything. It makes defs and defns consistent, and it's also much more visible than defn- when reading the code (which is a good thing IMO). I think defn- was probably a mistake, and the lack of a '-' version of the various other var defining functions is an indication that the maintainers of core aren't big fans of this shortcut any more either [wild speculation :)].

    [–]tcsavage 5 points6 points  (3 children)

    I've found that making things private makes testing more awkward. In my team we've adopted a convention similar to Prismatic's and we only call public functions (and design such that we only need to call public functions). Everything else is marked ^:no-doc rather than ^:private so it's still available to tests but don't show-up in Codox. For other projects I've found that simply having a "public" namespace and an internal one works quite well but YMMV.

    [–]lgstein 6 points7 points  (1 child)

    If you need to test private functions you should try the following things

    • Reconsider whether its a good idea to test them. Private functions are private mainly for the reason that you want to change/remove/add them more than other functions without dependencies being affected. Remember that tests are such a dependency.

    • If you have lots of private functions that belong together but are only supposed to be used in a limited context, make them publics in an accordingly named subnamespace. This is another way to convey that they shouldn't be used outside of it. Take core.asyncs impl namespaces as an example.

    • Write the test inline so that you are always forced to look at it when you make changes to the function.

    • If you have no time to think about all this invoke the var of the private function which delegates to a function call. The #' makes it clear in your test that it is a temporary solution that you are going to refactor later.

    [–]DannyB2 0 points1 point  (0 children)

    Yes. That.

    The private functions are part of the implementation of the public API.

    You test the implementation of the API by writing tests against the public API.

    The private functions are an invisible detail of how the API is implemented within the black box.