Given that core.async takes ~4s to require, is it worthwhile providing a aot'd version of that dependency for the purposes of speeding up programs relying on it? Any downsides to that? Yada uses core.async, and it's making yada look very slow as this is one of the biggest causes of slowdown. @alexmiller I think you mentioned you were working on a potential caching utility for an upcoming clojure, would the need for this be obsoleted by your work?
@dominicm maybe you can lazily require core.async, or is core.async also used by manifold and a non-optional thing in yada?
Manifold uses core async too, and I don't think yada can be lazy because it's protocol extension (although maybe it could try and extend it only when required? Sounds potentially dodgy)
having gone deeper now, it looks like it's the core.async.impl.ioc-macro's dependency of tools.analyzer which is slow.
Providing only an aot core.async is a recipe for trouble. You really need to aot all dependent code as well to avoid the classic protocol reloading issues. So would also need tools.analyzer etc. it’s really best to aot at the app level where you can do everything (and where you’re not deploying to maven and making that choice for everyone else)
And yes, I would expect the caching work would help. Really any time you’re reading and compiling something into a class that you’ve done before, it would potentially help
user=> (defrecord ^:private Foo [a])
user.Foo
user=> (meta #'->Foo)
{:arglists ([a]), :doc "Positional factory function for class user.Foo.", :line 1, :column 1, :file "NO_SOURCE_PATH", :name ->Foo, :ns #object[clojure.lang.Namespace 0x64b70919 "user"]}
Private records are not a thing
but I'd wager you could alter-meta!
the factory functions to be private
You can, or ns-unmap to remove entirely (which we do in a couple places)
I guess at the end of the file, if you want the references therein to compile
Any reason they're not a thing?
@dominicm seems like that’d be confusing. Can’t have a “private top level” java class. So would have to be like package private. Which clj doesn’t really utilize. Only the auto generated factory functions would make any sense, and that seems odd to me.
just for the record, CLJS:
ClojureScript 1.10.520
cljs.user=> (defrecord ^:private Foo [a])
cljs.user/Foo
cljs.user=> (meta #'->Foo)
{:private true, :ns cljs.user, :name ->Foo, :file nil, :end-column 25, :column 1, :internal-ctor true, :factory :positional, :line 1, :end-line 1, :arglists ([a]), :doc "Positional factory function for cljs.user/Foo.", :test nil}
this is used in CLJS source code
that seems to be a translation of this:
https://github.com/clojure/clojure/blob/4ef4b1ed7a2e8bb0aaaacfb0942729252c2c3091/src/clj/clojure/pprint/pretty_writer.clj#L71
and maybe defstructs
can be private in clojure