— Can break libraries
— How so?
Yeah, I'm confused and put it wrong. I mean, we can have issues when interacting with libraries and direct linking is enabled for the whole codebase.
The first scenario is, perhaps, unlikely, but a library might expect that users implement a protocol differently and redefine an instance, or we'd like to do this for some reason.
;; Library
(defprotocol MyProtocol
(my-function [this]))
(def my-instance (reify MyProtocol
(my-function [this] (println "hello"))))
;; Application
;; we can't redefine my-instance
;; and we can't make it ^:redef, it's in the library
The second case is when we're working on a library and forgot to mark a variable as ^:redef, the applicaion won't see the changes in it.
;; Library
(def my-var 10)
;; we're trying to update this later, when everything is compiled
;; Application
(defn use-var []
(println my-var))
Both examples are probably contrived, and I don't have an exact question to ask in the form "How to do the following?", but direct linking is documented only briefly and not explained how to deal with in a fine-grained manner, that's why I'm asking.
Andray Shotkin checked and, apparently, this works, the code is indeed directly linked with no vars.
(binding [*compiler-options* {:direct-linking false}]
(clj-java-decompiler.core/decompile (fn []
(seq (map :x [1 2 3])))))
(binding [*compiler-options* {:direct-linking true}]
(clj-java-decompiler.core/decompile (fn []
(seq (map :x [1 2 3])))))
So, I'm pasting an example of how to enable direct linking for a namespace here, just in case. In case I completely forget about this conversation and look up direct linking again later haha.
(ns my-namespace
(:require [clojure.core :as core]))
(binding [core/*compiler-options*
{:direct-linking true}]
,,,
)