Fork me on GitHub
Dustin Getz22:03:31

tutorial - what do you think?

metal 21
💯 7

Looks great! One thing that I think should be called out explicitly is how reactivity is granular to the expression level, e.g. in this function, only the println that depends on x will be called when x changes.

(e/defn Foo [x]
  (println "about to print x")
  (println x) ;will print if x changes
  (println "done printing x"))
I think folks coming from a React background might expect the entire body to be executed each time an argument changes because that's how React works. I think the explanation in the two clocks demo implies this behavior but it could still be beneficial to mention it explicitly to avoid faulty assumptions on the user's part

👍 4
🙏 2
Dustin Getz23:03:38

ok ty i wil incorporate this

Michael W01:04:29

This looks amazing. Is there a repo for this?


I ended up writing quite a few comments! Respond to whatever you feel like responding to. -- General comments: 1. I’ve spent about 10 minutes staring at example 1 and 2, this is really helpful. Edit: after reading it all, it was even more helpful! 2. I appreciate that the code doesn’t show anything more than it needs to — there are no “loose ends”. Feels more “to the point” than previous Electric Clojure material I’ve read. 3. The “what’s happening”, “novel forms” and “key ideas” sections are very helpful to understand the code. Specifics: 1. Toggle: I don’t know what “latency-stabilized” means. 2. Toggle: “Traditional “single state atom” UI pattern, except the atom is on the server” - this sentence formulates neatly why I’m excited about Electric! 3. Toggle: “Quiz: why do we call pr-str on the type number type before transferring it?” a. I’m honestly not quite sure. Is it because values transferred over the network need to be serializable, and types aren’t? 4. SystemProperties code a. Is (map (juxt key val)) really required? I haven’t tried in a REPL, but I’d to be able to delete that line. I could be missing something here. 5. SystemProperties: “`e/offload`: move a blocking Clojure computation to a threadpool (server only)” a. I’m curious about why this needs to be done. b. Is it because we want the async electric code to be able to “stuff” all the time, without waiting for any single slow thing to block? In other words, could the user interface start lagging here if we didn’t use e/offload? c. Perhaps the form description could describe why we want to use offload, not just what it does. d. … and I see that you actually explained this below. 🙂

👀 2
🙏 2
Dustin Getz14:04:02

@UAB2NMK25 there is, it's private currently, why do you want to see it?

Carsten Behring17:04:51

Maybe make the code view "read-only".. I edited it, and nothing happened (of course...)

👍 2
Dustin Getz20:04:50

Thank you all, I have updated the tutorial in response to the feedback

Dave Mays13:04:12

Tutorial is awesome, very nice to see something up and running live without needing to clone a repo or anything.

🙂 2

Just read the updated tutorial, this is just getting better! > • Unlike React.js, reactivity is granular to the expression level, not the function level. > ◦ Each expression, e.g. (- s c), is a node in the DAG. > ◦ Lexical scope, e.g. c, is an edge in the DAG. > ◦ Expressions are recomputed when any argument updates. > ◦ So, if c changes, (- s c) is recomputed using memoized s. This piece took me a long time to understand. I think I get it now, but please correct me if I’m wrong. 1. Electric analyzes code on the expression level. a. Each expression is async b. Each expression is reactive 2. e/defn / e/fn create functions that Electric can analyze the body of, 3. defn work normally as it does in clojure/cljs — a normal, blocking function, opaque to Electric. Electric doesn’t mess with the clojure.core/defn macro. 4. (e/offload #(my-fun arg1 arg2)) is a way to “asyncify” normal Clojure code. We could just call Clojure code, but if it takes long to finish, it’s better to e/offload because then we don’t block Electric from updating other things while we’re waiting for results. In other words: use e/defn to make Electric analyze individual pieces, and (my-fn arg1 arg2) to call normal functions directly, or (e/offload #(my-fun arg1 arg2)) to let the function run without blocking the electric event loop & application UI.

👍 1
Dustin Getz19:04:58

That's right, I will update the tutorial with this feedback thank you

👍 2
Dustin Getz19:04:39

Btw we have not introduced e/offload in the tutorial yet because it causes a minor problem that we hadn't noticed, we might need to rework something. But your understanding is correct.

👍 2
🙏 2