The following do/a
macro can auto-insert await
when asyncio
function is used.
The following also shows usage.
(import asyncio)
(import time)
(defmacro do/a [&rest code]
`(do ~@(lfor p code
(if
(= (cut (str (first p)) -2) "/a")
`(await ~p)
p))))
(defmacro progn/a [&rest code]
`(.run_until_complete (.get-event-loop asyncio )
((fn/a []
(do/a ~@code)
))
))
(defn/a sleep_test/a [t]
(await (asyncio.sleep t))
(print t)
t)
(defn sleep_test [t]
(time.sleep t)
(print t)
t)
(progn/a
(print 3)
(await (sleep_test/a 3))
(sleep_test/a 2) ;;can omit await
(sleep_test 1) ;;auto swich by fn name
(+ 20 30)
)
This macro detects async function by the function name "/a".
It is better using asyncio.iscoroutinefunction
to detect async functions.
But this does not work.
Plz see the following macro and executed result.
(defmacro isasynctestmac [f]
(if (asyncio.iscoroutinefunction f)
`["async" ~(asyncio.iscoroutinefunction f) (asyncio.iscoroutinefunction ~f) (type ~f)]
`["not async" ~(asyncio.iscoroutinefunction f) (asyncio.iscoroutinefunction ~f) (type ~f)]
))
(isasynctestmac sleep_test/a)
==> ['not async', False, True, <class 'function'>]
You will see an async function is regarded as a symbol in hy-lang macro.
Appling eval
can not avoid this problem.
How to resolve this problem?