hyperfiddle / rcf

RCF – a REPL-first, async test macro for Clojure/Script
MIT License
279 stars 12 forks source link

async rcf/% inside core.async go blocks doesn't work #44

Closed dustingetz closed 2 years ago

dustingetz commented 2 years ago

For background, here's a test without the problem of % inside go block:

(tests
  "core.async"
  (def c (chan))
  (go-loop [x (<! c)]
    (when x
      (<! (timeout 10))
      (! x)
      (recur (<! c))))
  (go (>! c :hello) (>! c :world))
  % := :hello
  % := :world
  (close! c))

Now imagine the assertions were inside the go block:

(tests
 (def c (chan))
 (go
   (! 1)
   % := 1
   (<! c)))

we can't rewrite it for the same problem as go blocks not rewriting lambda. Like async/await, % is await.

We don't have a good test for this case; We think this is nonsense and may not need to handle this case.

dustingetz commented 2 years ago
(tests
  ((fn []
     (! 1)
     % := 1)))
dustingetz commented 2 years ago
(tests
  (if true 
    1 
    (do (! 2) % := 2)))

This is workable, the expression becomes asynchronous and analyzed into thunks for the "await" to work. However we don't need to support this. Geoffrey says it already works in the analyzer branch (not in master).

dustingetz commented 2 years ago
(tests
 (! 1)
 (loop []
   % := 1
   (recur)))

Well defined; recur is sequenced after the assertion (the recur is inside the continuation). The recur is no longer in the tail-call position however in the compiler loop/recur is a syntax unit, recur does not exist in emitted code.

(tests
 (loop []
   (! 1)
   % := 1
   (recur)))

Leo says this can be done and can point to examples, not a risk