Skip to content

Instantly share code, notes, and snippets.

@linktohack
Created March 28, 2022 23:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save linktohack/850c57d6f5e82a2c03983e415d47040b to your computer and use it in GitHub Desktop.
Save linktohack/850c57d6f5e82a2c03983e415d47040b to your computer and use it in GitHub Desktop.
Lua coroutinize
;; -- Coroutinize
(fn coroutinize [f ...]
"Coroutinize a function `f' allow to to call functions with a callback within its body naturally
via coroutine, eliminate the callback hell.
These function often need to be evaluated in main thread or where `coroutine.resume' is not
availabe (Hammerspoon). The functions should to be wraped within `(fn [resolve] (f ... resolve))'
and yielded.They will be evaluated (in main thread) and come back via `coroutine.yield'
The code is taken from https://luyuhuang.tech/2020/09/13/callback-to-coroutine.html with some small
adaption.
If `coroutine.resume' is available, an `await' is often a better choice.
Example:
(coroutinize (fn []
;; Long version
(coroutine.yield (fn [resolve] (hs.timer.doAfter hs.math.minFloat resolve))) ; REPL Hack
;; Short version
(coroutine.yield #(hs.timer.doAfter hs.math.minFloat $1)) ; REPL Hack
(print \"Make a request\")
(-> (coroutine.yield #(hs.http.asyncGet \"https://jsonplaceholder.typicode.com/todos/1\"
{} $1))
(table.pack)
(fennel.view)
(print))))
"
(let [co (coroutine.create f)]
(fn resume [...]
(local (ok cb) (coroutine.resume co ...))
(if (not ok) (error (debug.traceback co cb))
(not (= (coroutine.status co) :dead)) (cb resume)))
(resume ...)))
(coroutinize (fn []
;; Long version
(coroutine.yield (fn [resolve] (hs.timer.doAfter hs.math.minFloat resolve))) ; REPL Hack
;; Short version
(coroutine.yield #(hs.timer.doAfter hs.math.minFloat $1)) ; REPL Hack
(print "Make a request")
(-> (coroutine.yield #(hs.http.asyncGet "https://jsonplaceholder.typicode.com/todos/1"
{} $1))
(table.pack)
(fennel.view)
(print))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment