The Pipeline api help you define a series of functions that can easily be decomposed and then combined with
other function to form a new pipeline. A function (Pipeline
) is tagged with one (or multiple) Symbol
s.
The return values of that Pipeline
will be bound to those symbols storing in a NamedTuple
. Precisely,
A Pipeline
take two inputs, a regular input value (source
) and a NamedTuple
(target
) that stores
the results, applying the function to them, and then store the result with the name it carried with into target
.
We can then chaining multiple Pipeline
s into a Pipelines
. For example:
julia> pipes = Pipeline{:x}(identity, 1) |> Pipeline{(:sinx, :cosx)}((x,y)->sincos(x))
julia> pipes(0.3)
(x = 0.3, sinx = 0.29552020666133955, cosx = 0.955336489125606)
# define a series of function
julia> pipes = Pipeline{:θ}(Base.Fix1(*, 2), 1) |>
Pipeline{(:sinθ, :cosθ)}(sincos, :θ) |>
Pipeline{:tanθ}(2) do target
target.sinθ / target.cosθ
end
Pipelines:
target[θ] := *(2, source)
target[(sinθ, cosθ)] := sincos(target.θ)
target[tanθ] := #68(target)
# get the wanted results
julia> pipes2 = pipes |> PipeGet{(:tanθ, :θ)}()
Pipelines:
target[θ] := *(2, source)
target[(sinθ, cosθ)] := sincos(target.θ)
target[tanθ] := #68(target)
target := (target.tanθ, target.θ)
julia> pipes2(ℯ)
(tanθ = -1.1306063769531505, θ = 5.43656365691809)
# replace some functions in pipeline
julia> pipes3 = pipes2[1] |> Pipeline{:tanθ}(tan, :θ) |> pipes2[end]
Pipelines:
target[θ] := *(2, source)
target[tanθ] := tan(target.θ)
target := (target.tanθ, target.θ)
julia> pipes3(ℯ)
(tanθ = -1.1306063769531507, θ = 5.43656365691809)
# and the pipelines is type stable
julia> using Test; @inferred pipes3(ℯ)
(tanθ = -1.1306063769531507, θ = 5.43656365691809)