The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.
Iterator functions are now allowed to have a close
argument. If they do, they will be called with a
close = TRUE
value when iteration is terminated early. This
gives the opportunity to clean up resources.
Generators now run on.exit()
expressions when they
are closed.
Iterators managed by coro::loop()
and by generator
for
loops are now cleaned up when terminated early, either
because of an error or because of a break
(#52).
Implicit and explicit return values of generators are no longer yielded. This is consistent with Javascript and Python and simplifies certain idioms (#51).
Generators and async functions assigned in namespaces no longer produce R CMD check notes about visible bindings (#40).
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
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.