Async functions created by coro::async()
now return
their promises::promise()
invisibly (#46, @shikokuchuo).
Fixes for CRAN checks.
coro::as_iterator()
method added for reticulate Python
objects, enabling usage like:
coro::loop(for (elem in my_py_object) ...)
(#37, @t-kalinowski).The exhaustion sentinel is now
as.symbol(".__exhausted__.")
instead of
as.symbol("exhausted")
to reduce the risk of collisions. It
is also recommended to never store the exhaustion sentinel in an
environment or list, and instead use it as a temporary value to further
reduce the risk of collisions (#35).
Fixed a leak that occurred via JIT caching (#36).
collect()
now preserves lists and data frames
(#32).This is the first public version of coro.
Python iterators created with the reticulate package can now be
composed with coro generators. They can also be used with
loop()
and collect()
.
iterate()
has been renamed to loop()
to
avoid name clash and semantic conflict with
reticulate::iterate()
.
collect()
calls as_iterator()
on its
input.
as_iterator()
is now a generic function
(#28).
Generators and async functions now support on.exit()
expressions. They also support exit expressions installed with functions
like withr::local_options()
. This requires R >=
3.5.
Generator arguments are forced on reentry in the approriate
context (e.g. in the tryCatch()
context if generator was
yielded from a tryCatch()
). This makes it possible to clean
up cancelled generators (by jumping from the generator with a restart)
or propagate errors in async functions.
Generators and async functions now support yielding within
tryCatch()
expressions.
Generators and async functions are now disabled when an unexpected exit occurs (error, interrupt, restart invokation, debugger exit, etc.). Reentering the generator is an error.
Generators and async functions now support stepping with
browser()
. Set options(coro_debug = TRUE)
for
browsing all functions created with coro. Use coro_debug()
for browsing specific functions.
generator()
now accepts functions of one argument.
The first time a generator is called the argument is defined in the
suspendable function. On subsequent invokations, the argument is
returned from yield()
.
generator()
now creates generator factories. It
takes a function template and returns a function that creates generator
functions from this template. This is consistent with languages like
Javascript and Python.
The async()
function operator creates functions for
cooperative concurrency using the later and promises
framework.
async_generator()
creates iterable functions that are
also awaitable.
The iterator abstraction has been removed from coro. It is replaced with the following protocol:
exhausted()
(or equivalently, the quote(exhausted)
symbol).Exhausted generators no longer throw when called again. Instead,
they return the exhausted()
sentinel (#6).
Fixed top-level break
statements in loops
(#7).
Initial release