hyperfiddle

o位v 2025-12-09T14:36:07.301779Z

What is the difference between (e/for [x table] <body>) and (let [x table] <body>) ? I know the practical difference of

;; Renders [:div "foo"] and [:div "bar"]
(e/for [x (e/amb "foo" "bar" )]
  (dom/div (dom/text x)))

;; Only renders [:div "foo"]
(let [x (e/amb "foo" "bar")]
  (dom/div (dom/text x)))
but I don't understand how to think about it :^)

Dustin Getz (Hyperfiddle) 2025-12-09T14:50:33.611179Z

Official answer: don't use e/amb directly, to render collections use the new virtual scroll patterns documented in the new tutorial

Dustin Getz (Hyperfiddle) 2025-12-09T14:52:10.054799Z

I am happy to respond to your actual question but https://xyproblem.info/ what are you trying to actually do

Dustin Getz (Hyperfiddle) 2025-12-09T14:53:55.410569Z

(dom/div (dom/text (e/amb "foo" "bar"))) is racing a "foo" and a "bar" into the same textnode, because the dom macros use the "mount point" infrastructure to reflect their location in the DAG to a corresponding location in the DOM

馃憤 1
o位v 2025-12-09T15:14:42.466519Z

I'm not xy-ing. I'm trying to improve my understanding of Electric 馃檪

Dustin Getz (Hyperfiddle) 2025-12-09T15:15:09.187319Z

ah ok. Was my answer sufficient?

o位v 2025-12-09T15:37:02.237879Z

Yeah, I think I got it after thinking now 馃槃 Is this right: With let, dom/div is only mounted once and then dom/text is mounted (e/Count (e/amb "foo" "bar")) times in the same environment, I.e with dom/node bound to the same div meaning the text of the div is being continually replaced rather than accreting new text nodes / element nodes in the dom.

;; Surgically mounts dom/text which each value of x, always
;; in the context of dom/node being the same div
(let [x (e/amb "foo" "bar")]
  (dom/div (dom/text x)))
;; Creates parallel branches for each superposed value
(e/for [x (e/amb "foo" "bar")]
  (dom/div (dom/text x)))

o位v 2025-12-09T15:37:29.816199Z

I will study the new virtual scroll patterns tonight 馃

Dustin Getz (Hyperfiddle) 2025-12-09T15:44:52.423779Z

yes

馃殌 1
xificurC 2025-12-09T15:54:24.977169Z

and if we implemented dom/text with e/for inside you'd get a third picture

o位v 2025-12-09T17:45:34.080899Z

@xifi now I'm curious :^)

xificurC 2025-12-09T18:38:06.363359Z

if I remove the unnecessary parts for this discussion, dom/text boils down to

(e/defn Text [arg]
  (let [e (.createTextNode js/document "")]
    (set! (.-textContent e) arg)))
Notice e doesn't depend on arg so we only create 1 text node, but set! does and therefore we get 2 set!s for (dom/div (dom/text (e/amb "foo" "bar"))). But we could decide to support e/amb argument
(e/defn Text [arg]
  (e/for [v arg]
    (let [e (.createTextNode js/document "")]
      (set! (.-textContent e) v))))
Now the same code would mount 1 div but 2 text nodes.

o位v 2025-12-09T19:47:56.623819Z

Ohh right, very cool!