This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-11-15
Channels
- # aleph (2)
- # babashka (35)
- # beginners (31)
- # biff (6)
- # calva (6)
- # cider (5)
- # clojure (61)
- # clojure-android (1)
- # clojure-dev (12)
- # clojure-europe (22)
- # clojure-norway (7)
- # clojure-uk (4)
- # clojurescript (19)
- # datomic (5)
- # events (3)
- # fulcro (15)
- # graalvm (41)
- # guix (2)
- # honeysql (2)
- # hoplon (8)
- # hyperfiddle (10)
- # jobs (1)
- # off-topic (29)
- # overtone (5)
- # podcasts-discuss (1)
- # remote-jobs (1)
- # sci (30)
- # shadow-cljs (186)
- # specter (2)
- # squint (22)
Is what I’m trying to do here impossible?
(e/defn ToyRunner
[value]
(e/server (println value)))
(e/defn ToyExample
[Runner]
(e/client
(println 1)
(e/server (Runner. 2))))
;; Run with,
(e/client (Toyexample. ToyRunner))
;; Unserializable reference transfer (client side)
(e/client (ToyExample. (e/server ToyRunner))
;; Unserializable reference transfer (server side)
What I’m trying to do is to encapsulate named bags of server-side functionality and make them a pluggable/interchangable argument to a named bag of client-side functionality.
i see two issues here 1. electric fns/closures don't serialize and transmit (clojure's don't either) 2. electric fns are called from a single site, which means they collect their arguments to the site of the call. Here, due to this, ToyRunner is forced through a pointless roundtrip during which it fails to serialize. As you noted - you can work around with a macro. Even without falling back to macros there is usually a simple refactor that avoids this, which is why we deprioritized it. Note that e/def is multi-sited (each site has a version of the e/def), so top level functions like these can be resolved from either site. #1 will be fixed soon (the compiler can e.g. defunctionalize). #2 as well. This is likely coming right after differential electric (which is far more impactful and important)
Once differential lands, I expect I would write this very differently anyhow. Today, it’s dealing with calling various AI services and streaming back responses. I set this up (based on Peter’s advice) to be an accumulation into an atom, server-side, the value of which which is then streamed to a recipient, client-side. The client side handling turns out to be the same regardless, whereas the server-side bit varies wildly. So the goal was to bundle these into one client-side package, and many server-side packages. A macro is perfectly fine for now: it doesn’t need to be dynamic, just a bit more DRY than it would have been otherwise.
Does :style
have to be a literal?
I get this works:
(dom/props {:style {:top "798px" :left "17.125px" :position "absolute"}})
I can’t get this to work:
(let [style {:top "798px" :left "17.125px" :position "absolute"}]
(dom/props {:style style}))
Using master branch.Here’s the problem:
(defmacro style [m]
(if (map? m)
`(do ~@(map (fn [[k v]] `(new Style node ~k ~v)) m)) ; static keyset
`(new Styles ~m)))
;; =>
(defmacro style [m]
(if (map? m)
`(do ~@(map (fn [[k v]] `(new Style node ~k ~v)) m)) ; static keyset
`(new Styles node ~m)))
Styles
is not arity-1.
(e/def Styles
(e/fn* [node kvs]
(e/for-by first [[k v] kvs]
(Style. node k v))
nil))