Fork me on GitHub
#clojure-europe
<
2023-09-19
>
dharrigan05:09:28

Good Morning!

Mario Trost06:09:45

Morning! Just returned from vacations in Corsica, can recommend if you like mountains or beaches

⛰️ 6
5
🙌 1
😍 4
schmalz07:09:43

Morning all.

reefersleep07:09:45

Godmorgen folkens!

genRaiy07:09:58

Good morning

vemv08:09:22

having a ReentrantReadWriteMorning 🔒

mdiin09:09:27

Good morning

reefersleep20:09:39

Good morning again

reefersleep20:09:56

What gives?

(with-redefs [first dec
              inc dec]
  [(first 5) (inc 5)])
=> [4 6]

seancorfield21:09:44

core is direct-linked when AOT'd so I'm surprised you can redef first tbh

reefersleep21:09:35

I notice that first is defined through a def and inc is defined through defn. idk if that makes the difference (yet)

reefersleep21:09:06

looks like it might

reefersleep21:09:27

next is def'ed as well

(with-redefs [first dec
              next dec]
  [(first 5) (next 5)])
=> [4 4]

seancorfield21:09:29

Looks like with-redefs was introduced in Clojure 1.3 but for 1.3 through 1.7 that code throws an exception:

=== 1.3 ===
Exception in thread "main" java.lang.ClassCastException: class clojure.lang.PersistentArrayMap$Seq cannot be cast to class java.lang.Number (clojure.lang.PersistentArrayMap$Seq is in unnamed module of loader 'app'; java.lang.Number is in module java.base of loader 'bootstrap')
        at clojure.lang.Numbers.dec(Numbers.java:118)
        at clojure.core$dec.invoke(core.clj:1082)
        at clojure.core$with_redefs_fn$root_bind__5911.invoke(core.clj:6477)
        at clojure.core$with_redefs_fn.invoke(core.clj:6485)
and then from 1.8 onward it produces [4 6]

reefersleep21:09:56

There's nothing in the docstring or on clojuredocs that suggests to me that clojure.core vars are exempt from the effect of with-redefs

seancorfield21:09:38

Direct-linking in AOT generally means that if you redefine a symbol, but don't redefine each caller, the redefinition "won't be seen", because the var-lookup at the call site is omitted and the original version of the function is emitted in the bytecode.

seancorfield21:09:31

I suspect the def vs defn is a quirk that circumvents the direct-linking substitution of the function...?

reefersleep21:09:54

You tell me. I don't know nearly as much about these concepts as you do 🙂 I was just trying to show a junior coworker something and was surprised when with-redefs basically didn't work as documented. Your explanation hints at an edge case, or at least an explanation that is more complex than would normally fit in a docstring, so I "get it"... I just don't like surprises like that 🙂

seancorfield21:09:25

Trying to redef core fns is a Bad Idea(tm). with-redefs is a pretty problematic thing anyway since it's not thread-safe, as I recall, so it really should only be used in tests and even then only in limited situations, on your own application code.

upvote 1
👍 1
seancorfield21:09:49

Well, 3rd party libs might be "ok" too since they shouldn't be AOT compiled.

reefersleep10:09:36

Yeah, I see how it could create problems to with-redefs core fns. I thought that I could do it for fun and demonstrations in REPL play, though, and the clojuredocs examples seemed to support my thinking.

seancorfield17:09:56

I wonder if those clojuredocs examples predate direct-linking AOT for core? I don't remember when that changed.

think_beret 1
reefersleep08:09:08

Thank you for the enlightenment, @U04V70XH6 🙂

reefersleep13:09:21

@U04V70XH6 do you have a good source where I could read up on direct-linking AOT for core? Is it in the changelogs, or maybe there's an article explaining the motivation or something? I know very little about the innards of core and haven't cared (much) about the innards of Java/JVM for ages, so I could do with some education. I understand what AOT is from an abstract perspective, but I don't understand direct-linking and the relation to clojure core.

seancorfield16:09:16

LMK if that doesn't answer your Qs @U0AQ3HP9U

reefersleep18:09:30

Thank you very much, that clears up quite a bit, @U04V70XH6 ! 💪 🙏