Public API
Continuables.emptycontinuable
Continuables.AbstractContinuable
Continuables.Continuable
Base.Iterators.cycle
Base.Iterators.drop
Base.Iterators.flatten
Base.Iterators.partition
Base.Iterators.product
Base.Iterators.take
Base.Iterators.zip
Base.all
Base.any
Base.collect
Base.foreach
Base.map
Base.prod
Base.reduce
Base.sum
Continuables.aschannel
Continuables.ascontinuable
Continuables.chain
Continuables.dropwhile
Continuables.groupby
Continuables.groupbyreduce
Continuables.i2c
Continuables.innerfunctype
Continuables.iterated
Continuables.nth
Continuables.reduce!
Continuables.repeated
Continuables.singleton
Continuables.takewhile
Continuables.@Ref
Continuables.@cont
Continuables.@i2c
Core
Continuables.Continuable
— TypeContinuable(func)
Assumes func to have a single argument, the continuation function (usually named cont
).
Example
Continuable(function (cont)
for i in 1:10
cont(i)
end
end)
Continuables.@cont
— Macro@cont begin
cont(1)
cont(2)
end
translates to
Continuable(function(cont)
cont(1)
cont(2)
end)
Furthermore, also function syntax is especially supported
@cont function(a, b) begin
cont(a)
cont(b)
end
is translated to
function(a, b)
Continuable(function(cont)
cont(1)
cont(2)
end)
end
In summary, @cont
wraps the return value into a Continuable.
Continuables.@Ref
— Macro@Ref begin
a = Ref(2)
a + 3
end
is translated to
begin
a = Ref(2)
a.x + 3
end
So that you do not need to write a.x
or 'a[]' all the way.
The macro works correctly with subfunctions shadowing the variables.
Continuables.innerfunctype
— Functioninnerfunctype(continuable)
Returns the generic type of continuable.f
. This can be used to specialize functions on specific Continuables, like Base.IteratorSize
and else.
Examples
mycont(x) = @cont cont(x)
Base.length(::Continuable{<:innerfunctype(mycont(:examplesignature))}) = :justatest
length(mycont(1)) == :justatest
length(mycont("a")) == :justatest
# other continuables are not affected
anothercont(x) = @cont cont(x)
length(anothercont(42)) == 1
Continuables.AbstractContinuable
— TypeAbstractContinuable
Abstract type which all continuable helper functions use for dispatch.
The interface for a continuable just consists of
Base.foreach(cont, continuable::YourContinuable)
For julia 1.0 you further need to provide
(continuable::YourContinuable)(cont) = foreach(cont, continuable)
which is provided automatically for more recent julia versions.
Conversions
Continuables.aschannel
— Functionaschannel(continuable) -> Channel
Convert the continuable into a channel. Performance is identical compared to when you would have build a Channel directly.
Continuables.ascontinuable
— Functionascontinuable(iterable)
Converts an iterable to a Continuable. There should not be any performance loss.
Continuables.i2c
— Functioni2c(iterable)
Alias for ascontinuable
. "i2c" is meant as abbreviation for "iterable to continuable". Also comes in macro form as @i2c
.
Continuables.@i2c
— Macro@i2c iterable
Alias for ascontinuable
. "i2c" is meant as abbreviation for "iterable to continuable". Also comes in function form as i2c
.
Factories
Continuables.emptycontinuable
— Constantemptycontinuable
The continuable with no elements.
Continuables.singleton
— Functionsingleton(value)
Construct a Continuable containing only the one given value.
Continuables.repeated
— Functionrepeated(() -> 2[, n])
repeated([n]) do
# ...
"returnvalue"
end
Constructs a Continuable which repeatedly yields the returnvalue from calling the given function again and again. Until infinity or if n
is given, exactly n
times.
Continuables.iterated
— Functioniterated((x) -> x*x, startvalue)
iterated(startvalue) do x
# ...
x*x
end
Constructs an infinite Continuable which
Common Helpers
Base.collect
— Functioncollect(continuable[, n]) -> Vector
Constructs Vector out of the given Continuable. If also given the length n
explicitly, a Vector of respective is preallocated. IMPORTANTLY n
needs to be the true length of the continuable. Smaller n
will result in error.
Base.reduce
— Functionreduce(operator, continuable; [init])
Like Base.reduce this will apply operator
iteratively to combine all elements into one accumulated result.
Continuables.reduce!
— Functionreduce!(op!, continuable; [init])
Mutating version of Base.reduce
If no init
is given op!
is assumed to mutate a hidden state (equivalent to mere continuation) else init
is the explicit state and will be passed to op!
as first argument (the accumulator)
Base.Iterators.zip
— Functionzip(continuables...; [lazy])
Constructs new Continuable with elements from the given continuables zipped up. I.e. will yield for each position in the original continuables a tuple (x, y, ...)
where x
, y
, ... are the elements from continuables
at the same position respectively.
If lazy=true
(default), it will use Channels to do the zipping. Elseif lazy=false
, it will use Arrays instead.
!!! warning CAUTION zip
on Continuables is not performant, but will fallback to either Channels (lazy=true
, default) which are very slow, or Arrays (lazy=false
) which will load everything into Memory.
Base.Iterators.product
— Functionproduct(continuables...)
Construct a new Continuable which yields all combinations of the given continuables, analog to how Iterators.product work for iterables.
Mind that product()
will still return an empty iterator instead of an empty Continuable. Use emptycontinuable
instead if you need an empty Continuable.
Continuables.chain
— Functionchain(continuables...)
chain(iterables...) = flatten(iterables)
When given Continuables it will construct a new continuable by concatinating all given continuables. When given anything else it will default to use Iterator.flatten
.
Base.Iterators.flatten
— Functionflatten(continuable_of_continuables)
Constructs new Continuable by concatinating all continuables in the given continuable_of_continuables
. Analog to Iterators.flatten.
For iterables of continuable use Continuables.chain(iterable_of_continuables...)
instead.
Base.Iterators.cycle
— Functioncycle(continuable[, n])
Constructs new Continuable which loops through the given continuable. If n
is given, it will loop n
times, otherwise endlessly.
Base.foreach
— Functionforeach(func, continuable)
Runs the continuable with func
as the continuation. This is the core interface of a continuable.
It is especially handy when using do
syntax.
Base.map
— Functionmap(func, continuable)
Constructs new Continuable where the given func
was applied to each element.
Base.all
— Functionall([func, ]continuable; [lazy])
Checks whether all elements in the continuable are true. If a function func
is given, it is first applied to the elements before comparing for truth.
If lazy=true
(default) the Continuable will only be evaluated until the first false
value. Elseif lazy=false
all elements of the Continuable will be combined.
Base.any
— Functionany([func, ]continuable; [lazy])
Checks whether at least one element in the continuable is true. If a function func
is given, it is first applied to the elements before comparing for truth.
If lazy=true
(default) the Continuable will only be evaluated until the first true
value. Elseif lazy=false
all elements of the Continuable will be combined.
Base.sum
— Functionsum(continuable)
sums up all elements
Base.prod
— Functionsum(continuable)
multiplies up all elements
Base.Iterators.take
— Functiontake(continuable, n)
take(n, continuable)
Construct a new Continuable which only yields the first n
elements. n
can be larger as the total length, no problem.
Continuables.takewhile
— Functiontakewhile(predicate, continuable)
takewhile(predicate, iterable)
If given a Continuable, it constructs a new Continuable yielding elements until predicate(element)
returns false
.
Also implements a respective functionality for iterables for convenience.
Base.Iterators.drop
— Functiondrop(continuable, n)
drop(n, continuable)
Construct a new Continuable which yields all elements but the first n
. n
can be larger as the total length, no problem.
Continuables.dropwhile
— Functiondropwhile(predicate, continuable)
dropwhile(predicate, iterable)
If given a Continuable, it constructs a new Continuable yielding elements until predicate(element)
returns true
.
Also implements a respective functionality for iterables for convenience.
Base.Iterators.partition
— Functionpartition(continuable, n[, step])
Constructs new Continuable which yields whole subsections of the given continuable, gathered as Vectors. n
is the length of a subsection. The very last subsection might be of length n
or smaller respectively, collecting the remaining elements.
If step
is given, the second subsection is exactly step
-number of elements apart from the previous subsection, and hence overlapping if n > step
. Further, importantly, if step
is given, there is no rest, but each subsection will be guaranteed to have the same length. This semantics is copied from IterTools.jl
Examples
julia> using Continuables
julia> partition(i2c(1:10), 3) |> collect
4-element Array{Any,1}:
Any[1, 2, 3]
Any[4, 5, 6]
Any[7, 8, 9]
Any[10]
julia> partition(i2c(1:10), 5, 2) |> collect
3-element Array{Any,1}:
Any[1, 2, 3, 4, 5]
Any[3, 4, 5, 6, 7]
Any[5, 6, 7, 8, 9]
julia> partition(i2c(1:10), 3, 3) |> collect
3-element Array{Any,1}:
Any[1, 2, 3]
Any[4, 5, 6]
Any[7, 8, 9]
Continuables.groupbyreduce
— Functiongroupbyreduce(by, continuable, op2[, op1])
groupbyreduce(by, iterable, op2[, op1])
Group elements and returns OrderedDict of keys (constructed by by
) and values (aggregated with op2
/op1
) If given anything else then a continuable, we interpret it as an iterable and provide the same functionality.
Parameters
by: function of element to return the key for the grouping/dict continuable: will get grouped op2: f(accumulator, element) = newaccumulator op1: f(element) = initialaccumulator
Examples
julia> using Continuables
julia> groupbyreduce(x -> x % 4, @i2c(1:10), (x, y) -> x + y)
OrderedCollections.OrderedDict{Any,Any} with 4 entries:
1 => 15
2 => 18
3 => 10
0 => 12
julia> groupbyreduce(x -> x % 4, @i2c(1:10), (x, y) -> x + y, x -> x+5)
OrderedCollections.OrderedDict{Any,Any} with 4 entries:
1 => 20
2 => 23
3 => 15
0 => 17
Continuables.groupby
— Functiongroupby(f, continuable)
groupby(f, iterable)
Wrapper around the more general groupbyreduce
which combines elements to a Vector. If you happen to aggregate your resulting grouped Vectors, think about using groupbyreduce
directly, as this can massively speed up aggregations.
Note that the interface is different from IterTools.groupby
, as we directly return an OrderedDict (instead of a iterable of values).
Examples
julia> using Continuables
julia> groupby(x -> x % 4, @i2c 1:10)
OrderedCollections.OrderedDict{Any,Any} with 4 entries:
1 => [1, 5, 9]
2 => [2, 6, 10]
3 => [3, 7]
0 => [4, 8]
Continuables.nth
— Functionnth(continuable, n)
nth(n, continuable)
Extracts the n
th element from the given continuable.
Examples
julia> using Continuables
julia> nth(i2c(4:10), 3)
6
julia> nth(1, i2c(4:10))
4