Fork me on GitHub
#sci
<
2021-07-27
>
borkdude10:07:29

I was recently discussing some workaround for direct linking with @didibus

borkdude10:07:19

I think one could install a patched version of clojure.core/defn that looks at some config file where you can state which vars you actually don't want to directly link

borkdude10:07:35

and this could be used for SCI-based graalvm binaries where the compiled vars need a bit of patching

borkdude10:07:58

of course this patch needs to be loaded first thing, before any other library

didibus16:07:58

Couldn't you alter-meta for the defn to add ^:redef to it before compilation? Assuming you didn't own the code

borkdude16:07:14

@didibus No, that you cannot do that, since the direct linking can occur in the same namespace

didibus17:07:51

Oh... I see what you mean, like you'd need to alter the meta right after the defn if other things later in the namespace were calling it

didibus17:07:50

If you declare the def first, does calling defn overwrite the meta for it or just merges?

didibus17:07:24

Like say you'd do:

(in-ns ns-i-dont-control)
(declare ^:redef foo)
(ns my-ns
  (:require [ns-i-dont-control :as dont]))
Where foo is the defn you don't want direct linked

borkdude17:07:41

I think it merges

borkdude17:07:46

so that would also be a clever hack

didibus17:07:33

I love a good clever hack 😉

didibus17:07:56

What could go wrong 😂

borkdude17:07:39

worst case it would get directly linked :)

borkdude17:07:07

but I think that hack might work well, thanks

borkdude17:07:32

but if you create those namespaces then require won't load the real ones anymore?

borkdude17:07:46

perhaps not when you do it with in-ns

borkdude17:07:45

I think that might be the case

didibus17:07:04

I used in-ns cause I felt like maybe it avoided that. But we'd need to try it

didibus17:07:45

Seems with self-hosted ClojureScript, the meta gets replaced, not merged... Just trying using my Android self-hosted repl. Not sure for real Clojure

borkdude17:07:58

Hmm...

user=> (in-ns 'cheshire.core)
#object[clojure.lang.Namespace 0x55ea2d70 "cheshire.core"]
cheshire.core=> (declare ^:redef generate-string)
Syntax error compiling at (REPL:1:1).
Unable to resolve symbol: declare in this context
cheshire.core=> (clojure.core/declare ^:redef generate-string)
#'cheshire.core/generate-string
cheshire.core=> (ns user
)
nil
user=> (require 'cheshire.core)
nil
user=> (meta #'cheshire.core/generate-string)
{:arglists ([obj] [obj opt-map]), :doc "Returns a JSON-encoding String for the given Clojure object. Takes an\n  optional date format string that Date objects will be encoded with.\n\n  The default date format (in UTC) is: yyyy-MM-dd'T'HH:mm:ss'Z'", :line 49, :column 1, :file "cheshire/core.clj", :name generate-string, :ns #object[clojure.lang.Namespace 0x55ea2d70 "cheshire.core"]}
user=> (:redef (meta #'cheshire.core/generate-string))
nil

borkdude17:07:24

I was pretty sure this worked for declare + :dynamic though

didibus17:07:36

Oh, declare is part.of clojure.core

didibus17:07:57

You could try with just (def ^:redef foo) it's what declare expands too anyways

didibus17:07:53

But ya... it seems the meta is replaced and not merged :(

borkdude17:07:55

I'm pretty sure this worked with dynamic, perhaps that's a special case

borkdude17:07:02

gotta investigate later, no time

didibus17:07:08

I think what happens for dynamic is that the meta tells def to create a Var configured to be dynamic. And when you call def for it again, even if you don't specify ^:dynamic, it will just alter-var-root so the Var will be the same which is still configured as dynamic... Maybe?

borkdude17:07:29

right, makes sense

borkdude17:07:50

but dynamic vars also don't get directly linked, so that would also work ;)

didibus20:07:09

I tried, it seems the meta for dynamic also get overridden, and then trying to call binding throws an error saying it's not dynamic.

didibus20:07:19

So not sure it would work

borkdude20:07:00

hmmm aah right