1

Given that each Clojure namespace corresponds to a file, isn't it the case that a public function, macro, etc. can never be moved out of that file without breaking backward compatibility?

This seems like a surprisingly rigid system--essentially, refactoring of public-facing code can only be done within a single file.

Is there a technical reason for this limitation? Something to do with Java interop, maybe?

Tianxiang Xiong
  • 3,887
  • 9
  • 44
  • 63
  • 3
    How to "move a function/method out of a file/class without breaking backward compatibility" in Java BTW – Davyzhu Jun 20 '16 at 05:22
  • What @Davyzhu said. I'm having trouble seeing how this is significant and how it is different from other programming languages. – Sam Estep Jun 20 '16 at 12:46

2 Answers2

1

You can split a single namespace into multiple files ( see Splitting a Clojure namespace over multiple files ) but it is quite rare to do so. Also you can import-vars using https://github.com/ztellman/potemkin but again this is rarely done in practice. Clojure libraries tend to have relatively small public interfaces, perhaps because they usually operate on common data structures. As such there are rarely files with much code in them.

If you are wanting to preserve backwards compatibility, you can def a var into a namespace (or even within a namespace with a different name), to ensure that any callers will still resolve to the right function.

Community
  • 1
  • 1
Timothy Pratley
  • 10,586
  • 3
  • 34
  • 63
  • I see, so it is possible but not common to split a single namespace over multiple files. Well, that at least frees the abstract hierarchy of code drom the physical medium of files. – Tianxiang Xiong Jun 20 '16 at 17:34
1

Functions that are not considered part of the public api can be marked private, which leaves the opportunity for later refactoring without breaking calling code. Any changes to a public api will, of course, risk breaking backwards compatibility and there will a trade off between that breaking change and introducing a new api with redundant functionality.

(ns foo)

;; only visible in the foo ns
(defn- a-private-fn [] ...)

;; only visible in the foo ns
(def ^:private a-private-var BAR 1)
sw1nn
  • 7,278
  • 1
  • 26
  • 36