Public API

Core

Continuables.ContinuableType

Continuable(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)
source
Continuables.@contMacro
@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.

source
Continuables.@RefMacro
@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.

source
Continuables.innerfunctypeFunction
innerfunctype(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
source
Continuables.AbstractContinuableType
AbstractContinuable

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.

source

Conversions

Continuables.aschannelFunction
aschannel(continuable) -> Channel

Convert the continuable into a channel. Performance is identical compared to when you would have build a Channel directly.

source

Factories

Continuables.repeatedFunction
repeated(() -> 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.

source
Continuables.iteratedFunction
iterated((x) -> x*x, startvalue)
iterated(startvalue) do x
  # ...
  x*x
end

Constructs an infinite Continuable which

source

Common Helpers

Base.collectFunction
collect(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.

source
Base.reduceFunction
reduce(operator, continuable; [init])

Like Base.reduce this will apply operator iteratively to combine all elements into one accumulated result.

source
Continuables.reduce!Function
reduce!(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)

source
Base.Iterators.zipFunction
zip(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.

source
Base.Iterators.productFunction
product(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.

source
Continuables.chainFunction
chain(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.

source
Base.Iterators.flattenFunction
flatten(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.

source
Base.Iterators.cycleFunction
cycle(continuable[, n])

Constructs new Continuable which loops through the given continuable. If n is given, it will loop n times, otherwise endlessly.

source
Base.foreachFunction
foreach(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.

source
Base.mapFunction
map(func, continuable)

Constructs new Continuable where the given func was applied to each element.

source
Base.allFunction
all([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.

source
Base.anyFunction
any([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.

source
Base.Iterators.takeFunction
take(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.

source
Continuables.takewhileFunction
takewhile(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.

source
Base.Iterators.dropFunction
drop(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.

source
Continuables.dropwhileFunction
dropwhile(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.

source
Base.Iterators.partitionFunction
partition(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]
source
Continuables.groupbyreduceFunction
groupbyreduce(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
source
Continuables.groupbyFunction
groupby(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]
source
Continuables.nthFunction
nth(continuable, n)
nth(n, continuable)

Extracts the nth element from the given continuable.

Examples

julia> using Continuables

julia> nth(i2c(4:10), 3)
6
julia> nth(1, i2c(4:10))
4
source