Fork me on GitHub
#clojure-dev
<
2017-06-22
>
thheller11:06:13

is there official documentation about AOT besides https://clojure.org/reference/compilation

thheller11:06:10

does it recompile automatically if files changes?

thheller11:06:35

it seems to only compile once and never recompile even when a file changes?

Alex Miller (Clojure team)12:06:24

Re recompile, no - what would "it" be here?

thheller12:06:51

(clojure.core/compile 'my.app)

thheller12:06:22

if I change my.app it appears to recompile but not whenever any dependencies change

thheller12:06:37

(which is ok, only want to confirm)

thheller12:06:13

I haven’t totally deciphered the load process when it comes to AOT

bronsa12:06:46

it's exactly the same as with require

thheller12:06:51

RT.load is simple enough but do classes still call that or do they directly refer to classes?

bronsa12:06:07

it will load (and compile) namespaces that have not already been loaded

bronsa12:06:12

transitively

bronsa12:06:29

if a namespace has already been loaded it won't reload it

thheller12:06:45

its a fresh JVM so nothing is loaded

thheller12:06:29

I basically call clojure.main -e "(compile 'my.thing)" -m my.thing

bronsa12:06:49

except it will recompile a namespace if the clj file is newer than the classfile

thheller12:06:55

so that I have AOT compiled code on the next run

bronsa12:06:18

but only for the root namespace you pass through to compile

thheller12:06:40

yeah that was my quesion

thheller12:06:53

if (ns my.thing (:require [foo])) and foo changes

thheller12:06:02

the (compile 'my.thing) won’t recompile foo

bronsa12:06:03

yeah well, the transitive namespaces are laoded via require not compile

bronsa12:06:06

so they behave as per require

bronsa12:06:28

meaning they don't get re-loaded (and re-compiled) automatically

thheller12:06:04

hmm but (compile 'my.thing) compiles everything (transitively)

thheller12:06:16

not just my.thing

bronsa12:06:44

compile sets up a compilation context, every namespace loaded within that compile call will get compiled

thheller12:06:45

now I’m confused …

thheller12:06:52

the point I’m confused about is whether or not it still recompiles once it has loaded a class (and didn’t reocmpile it)

thheller12:06:24

I don’t know how classes load dependencies

bronsa12:06:42

so, having (ns foo (:require bar)) (ns bar)

bronsa12:06:59

if you (compile 'foo) and bar isn't loaded yet, bar will get AOT compiled

bronsa12:06:06

if bar is loaded already, it won't

thheller12:06:14

yes that is clear

thheller12:06:20

as I said NOTHING is loaded

thheller12:06:24

its a fresh JVM

thheller12:06:30

so it doesn’t matter

thheller12:06:44

clojure.main -e "(compile 'my.thing)" -m my.thing

bronsa12:06:46

if you change foo and recompile foo, only foo will get AOT compiled

bronsa12:06:02

if you change bar and recompile foo, nothing will get recompiled

thheller12:06:37

ok thx. I was unsure about that

bronsa12:06:55

unless your requires have a :reload clause

bronsa12:06:06

in that case they might get re-compiled transitively

thheller12:06:10

so if I know that bar changed I need to delete the .class file for foo

thheller12:06:21

compile has :reload?

bronsa12:06:28

no, require does

bronsa12:06:08

if you (ns foo (:require bar :reload)), change bar and foo and recompile foo, bar will get recompiled too

bronsa12:06:28

or whatever the syntax for reload is

thheller12:06:03

I’ll just reset the .class files whenever I know that something may have changed

hiredman21:06:08

is proxy-super thread safe?

hiredman21:06:25

(defn proxy-call-with-super [call this meth]
 (let [m (proxy-mappings this)]
    (update-proxy this (assoc m meth nil))
    (try
      (call)
      (finally (update-proxy this m)))))

(defmacro proxy-super 
  "Use to call a superclass method in the body of a proxy method. 
  Note, expansion captures 'this"
  {:added "1.0"}
  [meth & args]
 `(proxy-call-with-super (fn [] (. ~'this ~meth ~@args))  ~'this ~(name meth)))

hiredman21:06:58

that doesn't look thread safe, but I must be missing something

Alex Miller (Clojure team)22:06:10

I’ve never looked at it. what looks unsafe?

hiredman22:06:34

it mutates the method map for the proxy, and for the duration of (call) it seems like any callers of that method on the proxy, would get the superclass's method instead

hiredman22:06:34

(is how I read i t, but I haven't looked in the guts of proxy in a while, and it seems crazy that it wouldn't be threadsafe, so I must be missing something)

Alex Miller (Clojure team)22:06:54

well, I didn’t exhaustively through all the code, but at a glance, that seems correct

Alex Miller (Clojure team)23:06:07

I mean your analysis seems correct that is

Alex Miller (Clojure team)23:06:53

although I’m not sure it’s possible for that method to be in the proxy in first place as you can’t proxy super methods

hiredman23:06:16

I don't entirely follow that last bit, I have a (not very small) test case https://gist.github.com/hiredman/a42f83c2708bf6291a75c9372ad26525 that seems to demonstrate the thread unsafe behavior