Fork me on GitHub
#clojure-dev
<
2022-07-26
>
thheller06:07:56

hmm I guess there is something in clojure I have never run into before and don't actually understand what is happening

thheller06:07:14

(ns test.thing)

(defrecord Thing []
  clojure.lang.IFn
  (invoke [this]
    "thing"))

(def thing
  (Thing.))

(def bar (let [] (thing)))

(def foo (thing))

thheller06:07:14

what is different with (def foo (thing)) that it ends up failing with

Execution error (AbstractMethodError) at test.thing.Thing/applyTo (server.clj:-1).
Method test/thing/Thing.applyTo(Lclojure/lang/ISeq;)Ljava/lang/Object; is abstract

thheller06:07:24

why is it trying to apply?

thheller06:07:31

as soon as its used in a top-level def it just fails. (def {:foo (thing)}) or any other collection also fails. wrapping it in a let magically makes it work?

thheller06:07:09

I guess I must implement applyTo from IFn but I wonder why?

thheller06:07:16

(going from defrecord to deftype changes the error message but still complains about applyTo)

hiredman06:07:00

For "simple" code (like invoking a function bound to a var) unless aot compiling, the compiler doesn't bother generating bytecode, it runs a minimal interpreter, which invokes funtions using apply

🤯 3
nwjsmith20:07:31

This might be a weird question, but do you have any tips for me? I'd like to have the depth of understanding of the compiler that you do. Is it as simple as "read all of the compiler source" 😅?

nwjsmith20:07:21

Or is this something you learned while trying to make changes to the compiler?

hiredman20:07:20

more of the latter then the former, I have a vague idea of the overall structure and what parts exist in the compiler that guides looking for stuff in it, I wouldn't say I have read it all

hiredman21:07:10

some familiarity with tools.analyzer output can help a lot, because tools.analyzer does pretty much the same analysis as the compiler does, but the results are nice bits of clojure data.

hiredman21:07:48

similarly the clojurescript compiler is a compiler for a clojure like language written in clojure

nwjsmith16:07:12

Thanks so much for the pointers. I haven't spent enough time with tools.analyzer, will start there

hiredman06:07:03

Which is why the let version works fine, that doesn't count as simple, so it generates bytecode that calls the invoke method for function invocation

thheller06:07:38

TIL. thanks