This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-12-14
Channels
- # adventofcode (29)
- # aws (3)
- # babashka (25)
- # beginners (13)
- # calva (4)
- # cherry (7)
- # cider (26)
- # clj-kondo (9)
- # clojure (88)
- # clojure-europe (21)
- # clojure-losangeles (3)
- # clojure-nl (1)
- # clojure-norway (6)
- # clojure-uk (11)
- # clojuredesign-podcast (2)
- # clojurescript (4)
- # cursive (10)
- # datalevin (1)
- # emacs (50)
- # gratitude (1)
- # honeysql (12)
- # hyperfiddle (19)
- # jobs-discuss (28)
- # kaocha (3)
- # lsp (53)
- # malli (4)
- # meander (3)
- # off-topic (48)
- # re-frame (11)
- # releases (2)
- # ring-swagger (2)
- # shadow-cljs (50)
- # squint (26)
- # tools-build (3)
- # tools-deps (8)
- # xtdb (4)
- # yamlscript (1)
Thanks for shipping IC, excited to try it out! Is there a migration path from non-IC, or is it best to clone the starter project? Would be great to be able to migrate existing projects if possible.
From @U09FL65DK : "Take a look at this https://github.com/hyperfiddle/electric-starter-app/compare/main...ic?w=1 on how to upgrade.". This is what I did. The thread is: https://clojurians.slack.com/archives/C7Q9GSHFV/p1701979730768789
using httpkit I always get this error on boot
clj꞉dash.serve꞉>
; Thu Dec 14 13:34:53 EST 2023 [worker-4] ERROR - handle websocket frame org.httpkit.server.Frame$TextFrame@990243e
; java.lang.NullPointerException: Cannot invoke "clojure.lang.IFn.invoke(Object)" because the return value of "clojure.lang.RT.aget(Object[], int)" is null
; at hyperfiddle.electric_httpkit_adapter$handle_electric_ws$on_receive__80522.invoke(electric_httpkit_adapter.clj:79)
; at clojure.core$partial$fn__5920.invoke(core.clj:2641)
; at org.httpkit.server.AsyncChannel.messageReceived(AsyncChannel.java:153)
; at org.httpkit.server.WSHandler.run(RingHandler.java:187)
; at org.httpkit.server.LinkingRunnable.run(RingHandler.java:154)
; at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
; at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
; at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
; at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
; at java.base/java.lang.Thread.run(Thr @
but everything boots fine and the app works!is this a hot code reload
(when (and falsey maybe) ...)
when maybe
changes, is this expression short circuited or is still a diff happening?it will macroexpand to nested ifs, thus matching the behavior of electric-if
i.e. untaken branch is not mounted
Are you observing something different?
no, just thought it was interesting to know. mounting is actually fairly expensive too right, it's the only time missionary allocates?
electric let compiles to missionary allocation
mounting is expensive in the network planner though
i believe all mounts are currently broadcast, because the frame could contain client and server regions, and we don't yet do the network equivalent of dead code elimination (it has not yet been an issue in practice, we do measure)
sorry i'm tired and can't parse "electric let compiles to missionary allocation" -- what is electric let? how can you allocate at compile time
(let [x (F. a) (vector x x)) injects a m/signal! so that flow x is reused; i.e. it allocates a memo buffer in the reactor heap to store the latest value of x
well compilation is by def
now so it couldn't be the former. I was thrown off by "electric let", but that's the same let the and
macro uses
m/signal!
instruction is compiled into the target missionary DAG (in fact m/signal! is the operator that makes it an actual DAG as opposed to a tree, you need the memo buffer to get a DAG). The allocation happens at runtime. I believe the exact details of how at runtime it happens (i.e. "when the flow boots") was the subject of the missionary DAG supervision release, which supersedes m/signal!
with m/signal
and improves the semantics here. Electric v2 still uses the old way, the differential rewrite uses the new way