This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-09-24
Channels
- # announcements (7)
- # babashka (5)
- # babashka-sci-dev (20)
- # beginners (125)
- # biff (98)
- # catalyst (1)
- # clerk (37)
- # clj-kondo (6)
- # clojure (49)
- # clojure-dev (18)
- # clojure-europe (6)
- # clojure-uk (2)
- # data-science (17)
- # deps-new (20)
- # emacs (11)
- # helix (5)
- # hyperfiddle (34)
- # malli (3)
- # missionary (4)
- # reitit (4)
- # sci (15)
- # solo-full-stack (7)
- # sql (5)
- # testing (2)
context: trying to avoid designing a macro-based api with a dynamic var to hold context, but I think it might be the only way to get good ergonomics, since we're stuck with compile-time dependency injection
That opinion that Dynamic scope is RT is controversial, i’ve mostly had it beaten out of me (by Leo and others). Regardless of if it is RT i think it’s still great, it just interacts terribly in ordinary clojure with lazy-seq
so the solution to making dynamic scope not suck is to not do it in "ordinary clojure", so the electric dyn vars are only bound within the electric program?
arguably lazy-seq is the bigger mistake.. it's a really idiosyncratic thing to be idiomatic, other languages get by fine without them
I guess this is why you cannot bind dynamic vars inside electric programs. already ran into that trying to use with-out-str
an important difference between Electric dynamics and Clojure dynamics is that Electric dynamics have the Electric RAII lifecycle, making them more or less equivalent to Component/Mount as i believe we discussed last month
and since Electric code does not make use of the clojure seq abstraction at all (due to it not being reactive), the bad lazy seq interaction is avoided
Clojure dynamics have other problems with respect to how they interact with JVM concurrency and specifically about how Clojure’s “binding conveyance” between threads has serious shortcomings, Leo wrote a rant about this that I’ll have to go find. Again, Electric doesn’t use Clojure’s concurrency so those interactions are also avoided
with respect to binding Clojure dynamics from Electric programs (breaking with-out-str) I need to go look at our internal issue tracker to remember our stance on that and the details/options
re electric -> clj(s), reactive vars are conveyed where possible
(e/def db (e/watch !conn))
(e/defn App []
(d/q [] db) ; obviously works, passed as a positional argument
(#(prn db)) ; also works, we analyze and convey
(defn my-transact [] ; not electric
(d/q [] db)) ; not possible to convey
my opinion on lazy sequences and dynamic vars in clojure :
• the dynamic var idea started with good intentions but binding conveyance completely ruined it. Without binding conveyance, dynamic vars are equivalent to thread local state, which has some valid use cases. Using thread local state for DI is a bad idea because it breaks everything that relies on referential transparency - not only lazy sequences, really all kinds of deferred evaluation. If thread local state is what you need, use ThreadLocal
because dynamic var performance is terrible (due to binding conveyance, even if you don't use it). To understand why binding conveyance is bad, consider this snippet : (with-out-str (future (println "hello")))
• lazy sequences are not bad but it should not be the default because laziness+memoization is almost never what you need, you generally need one or the other but not both, so you pay the performance overhead for nothing
that's true, and in the two places I actually use lazy seqs the chunking works against me too
how is compile performance for people? I feel like i've done something wrong, getting ~9s compiles for a small test project
i’ve never seen that
you have proven that it is specific to this project?
today varargs expand https://github.com/hyperfiddle/electric/blob/0842e64e895b260707a532068dc7f35c147fb65f/src/hyperfiddle/electric.cljc#L247arguments. Reducing the number reduces the compile times, but we don't have a dynamic fallback case today so I have to make the cutoff somewhere
a single instance of e/defn .. &
with dom/on
currently doubles my build time. IMO it is completely unusable right now
what Peter is saying is that we probably want to land incremental compilation first which is our platform for future work on the build time
the specific interaction with dom/on is also surprising, needs more analysis on our part
Surely we can tune the varargs constant for now, and it feels like something O(n^2) may be happening as well
Immediate workaround: lift to arity-1 function that takes a single list and destructure the list
@U09FL65DK good to know, thank you!