This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-09-21
Channels
- # 100-days-of-code (6)
- # aleph (26)
- # beginners (129)
- # boot (5)
- # calva (3)
- # cider (5)
- # cljs-dev (16)
- # cljsrn (4)
- # clojure (204)
- # clojure-dev (36)
- # clojure-italy (23)
- # clojure-nl (4)
- # clojure-spec (221)
- # clojure-uk (60)
- # clojurescript (68)
- # datomic (47)
- # emacs (4)
- # figwheel-main (50)
- # fulcro (29)
- # graphql (10)
- # hyperfiddle (19)
- # lein-figwheel (3)
- # leiningen (20)
- # liberator (3)
- # off-topic (89)
- # onyx (15)
- # pedestal (1)
- # portkey (2)
- # re-frame (3)
- # reagent (6)
- # ring-swagger (1)
- # rum (12)
- # shadow-cljs (10)
- # uncomplicate (4)
- # vim (5)
I just ran into the fact that compile doesn't compile anything that's already loaded. I can't seem to see anywhere that specifies this behaviour. Is this a long standing bug with no good / intended fix? Is this documented somewhere and I can add that place to my check list when understanding things.
compilation happens as a side effect of load so that makes conceptually makes sense to me
https://clojure.org/reference/compilation is probably the canonical reference page
I wouldn’t say it’s a bug and it seems like it it worked otherwise, compilation would result in a lot of recompilation when compiling many namespaces
It's a problem because the root namespace doesn't look for the .clj too, so it actually fails when run.
don’t understand
In my case I did an AOT of user (root ns), edge.system was already loaded though, so didn't AOT. When I tried to use user as a main from that directory later, it failed because it couldn't find edge/system$new_system.class
Even though edge/system.clj was present. Message didn't indicate that it tried both.
To clarify, you AOTed 'user, which was already loaded by the time you asked for 'user to get compiled
given that user is special-cased into the runtime, this is a particularly weird case
so I’d suggest not doing that :)
I agree. I think it would happen in other cases too. I'm certain I saw it a while ago in another project not using user.
It actually doesn't matter which ns you AOTed - any thing required by user would be affected
exactly - user is designed NOT to be AOT’ed (as the runtime explicitly loads user.clj)
But if I have a user.clj in my classpath that requires edge.main, that would cause this bug too.
so, don’t load stuff in user.clj?
That's a fine answer, if it's the intended behaviour. It does cause minor issues trying to write a build system that doesn't have to spin up a whole extra jvm/pod just for aot.
There are workarounds though, so nothing pressing. But if it's something that could be enhanced, then I'm happy to open a jira, or vote for one. If there's a reason that it should stay this way then that's knowledge worth having too.
I said the reasons above
if compile recompiled loaded stuff then every compile would recompile everything
Because most people don’t their compile time to be n!
I guess more n^2 or something
I suppose the caching seems wrong to me. I would expect caching to be based on the class file, not what is loaded in memory, and possibly not on disk.
it’s just leveraging the existing load system which transitively loads namespaces. if you encounter a new (unloaded) namespace, compile it
you’re N steps down the decision chain here, asking “why X”. it’s difficult to walk that chain backwards, recovering all the design decisions from 10 years ago.
Leveraging the load system I understand. It's a fairly convenient way to implement this. Sorry, I think I have misunderstood. I thought you were implying that the expected common case for compile involved a scenario where skipping loaded namespaces was useful. I was trying to figure out what the expected workflow is exactly. I understand that performance is a feature, but I wouldn't expect it at this kind of detriment to compile. With limited experience with the larger picture for this feature, this limitation seems arbitrary, verging on accident of history. Which is okay too, I am not interested in the why of how it happened so much as why it should stay the way it is.
I don't have experience in dealing with the detailed behavior of compile here, so out of my depth, but in general a reason for things to stay the way they are is to avoid creating possible bugs in build and/or deployment flows that people are using today.
“I thought you were implying that the expected common case for compile involved a scenario where skipping loaded namespaces was useful.” - yes I was saying that
if you are in a project and you want to compile everything in the project, you need to invoke compile for every namespace in the project
you don’t want every one of those calls to recompile every namespace
you want to compile every namespace once
by compiling on load and leveraging the set of loaded namespaces as a tracking mechanism, you achieve that