Library

Public interface

ResumableFunctions.@resumableMacro

Macro that transforms a function definition in a finite-state machine:

  • Defines a new mutable struct that implements the iterator interface and is used to store the internal state.
  • Makes this new type callable having following characteristics:
    • implementents the statements from the initial function definition but;
    • returns at a @yield statement and;
    • continues after the @yield statement when called again.
  • Defines a constructor function that respects the calling conventions of the initial function definition and returns an object of the new type.

If the element type and length is known, the resulting iterator can be made more efficient as follows:

  • Use length=ex to specify the length (if known) of the iterator, like: @resumable length=ex function f(x); body; end Here ex can be any expression containing the arguments of f.
  • Use function f(x)::T to specify the element type of the iterator.

Extended

julia> @resumable length=n^2 function f(n)::Int
         for i in 1:n^2
           @yield i
         end
       end
f (generic function with 2 methods)

julia> collect(f(3))
9-element Vector{Int64}:
 1
 2
 3
 4
 5
 6
 7
 8
 9
source

Internals

Base.IteratorSizeMethod

Implements the iteratorsize method of the iterator interface for a subtype of FiniteStateMachineIterator.

source
Base.eltypeMethod

Implements the eltype method of the iterator interface for a subtype of FiniteStateMachineIterator.

source
ResumableFunctions.forward_argsMethod

Takes a function definition and returns the expressions needed to forward the arguments to an inner function. For example function foo(a, ::Int, c...; x, y=1, z...) will

  1. modify the function to gensym() nameless arguments
  2. return (:a, gensym(), :(c...)), (:x, :y, :(z...)))
source
ResumableFunctions.transform_argMethod

Function that replaces a arg = @yield ret statement by

  @yield ret;
  arg = arg_

where arg_ is the argument of the function containing the expression.

source
ResumableFunctions.transform_excMethod

Function that replaces a @yield ret or @yield statement by

  @yield ret
  _arg isa Exception && throw(_arg)

to allow that an Exception can be thrown into a @resumable function.

source
ResumableFunctions.transform_forMethod

Function that replaces a for loop by a corresponding while loop saving explicitly the iterator and its state.

For loops of the form for a, b, c; body; end are denested.

source
ResumableFunctions.transform_tryMethod

Function that replaces a try-catch-finally-end expression having a top level @yield statement in the try part

  try
    before_statements...
    @yield ret
    after_statements...
  catch exc
    catch_statements...
  finally
    finally_statements...
  end

with a sequence of try-catch-end expressions:

  try
    before_statements...
  catch
    catch_statements...
    @goto _TRY_n
  end
  @yield ret
  try
    after_statements...
  catch
    catch_statements...
  end
  @label _TRY_n
  finally_statements...
source
ResumableFunctions.transform_yieldMethod

Function that replaces a @yield ret or @yield statement with

  Base.inferencebarrier(ret)

This version is used for inference only. It makes sure that val = @yield ret is inferred as Any rather than typeof(ret).

source
ResumableFunctions.transform_yieldfromMethod

Function that replaces a @yieldfrom iter statement with

  _other_ = iter...
  _ret_ = generate(_other_, nothing)
  while !(_ret_ isa IteratorReturn)
    _value_, _state_ = _ret_
    _newvalue_ = @yield _value_
    _ret_ = generate(_other_, _newvalue_, _state_)
  end
  _
source