Chainables API

ChainablesModule

Chainables.jl is a library for working better with Chain.jl

source

Module Index

API

Chainables.PartialType
Partial

A lightweight struct to hold a function and its args, for the purposes of partial application.

source
Chainables.partialMethod
partial(f, args...; kwargs...)

Create a Partial (a partially applied function). For more convenience, see @partial or @∂.

Example:

f(a,b) = 2*a + b
f_partial = partial(f, 3) # put 3 in place of a 
@assert f_partial(1) == f(3, 1)

This can handle varargs and kwargs:

foo(args...; kwargs...) = sum(args) + length(kwargs) 
foo_partial = @∂ foo(10, 10; a = 5)
foo_partial(20; b = 7) == foo(10,10,20; a = 5, b = 7) == 42

You can choose where the positional arguments get curried to with use of @x.

foo_partial_2 = @∂ foo(10, @x; a = 5)
foo_partial_2(30; b = 7) == foo(10,30; a = 5, b = 7) == 42

If you have not fully exhausted the list of unknown placeholders, and you call a Partial, you will get back a Partial. As such:

foo_partial_3 = @∂ foo(1,@x,@x,@x)
foo_partial_4 = foo_partial_3(10)
final_answer = foo_partial_4(30)(1)
@assert final_answer == foo(1,10,30,1) == 42

You can chain partials together as follows:

bar(args...) = sum(args)

b1 = @∂ bar(6,@x,2,@x,@x,12)
b2 = @∂ b1(5,10) 
b3 = @∂ b1(@x,10,7)

@assert @all [
    b1(5,10,7)
    b2(7)
    b3(5)
] @∂ ==(42) 
source
Chainables.revMethod
rev(f::Function)

Rearrange the inputs to f such that the original first arg is now the last one.

source
Chainables.unpackMethod
unpack(f::Function)

Return a valid form of f that can destructure its args. Also see @unpack. Without this function you may find yourself working with tuples as a single argument to a function.

For instance, the usage of t[1] and t[2] in the following is untasty.

@chain 1:10 begin
    zip(20:30)
    @map t -> t[1] + t[2]
end

With this function, you write something equally untasty:

@chain 1:10 begin
    zip(20:30)
    @map unpack((a, b) -> a + b)
end

See @unpack for something better.

source
Chainables.unzipMethod
unzip(zipped_iter)

Lazily unzip a zipped structure. Useful when you need to zip structures together, compute results, and then get back your original iterators.

@chain [1,2,3] begin 
    zip([4,5,6]) 
    collect
    @filter @unpack (x,y) -> x + y <= 7
    unzip 
    @. collect 
end 
source
Chainables.withMethod
with(f::Function, args...; kwargs...)

Curry out the first variable from function f. This is useful if you wanted do blocks in chain statements. For instance:

@chain 12 begin 
    @apply with(1) do x,y
        x^2 + y 
    end 
end 
# == 12^2 + 1 == 145
source
Chainables.@applyMacro
@apply(x, f)

Apply f to x. Useful when chaining. For example, imagine we want the first letter of the second word in the following sentence:

x = @chain "Hello Fine Ladies" begin 
    split.(" ")
    @apply x -> x[2][1]
end 
@assert x == 'F'
source
Chainables.@partialMacro
@partial(expr)

A macro form of the partial function. See that function for further documentation.

foo(varargs...) = sum(varargs)
p1 = @partial foo(1)
p2 = @∂ foo(1)
p3 = partial(foo, 1)
@assert p1 == p2 == p3 
source
Chainables.@revMacro
@rev(arg, expr)

Rearrange arg to go into the expr. Useful for doing this kind of thing:

@chain 1:100 begin 
    @rev reduce(+)
end 
source
Chainables.@unpackMacro
@unpack(f::Function)

The macro equivalent of unpack.

Enables unpacking of tuples. For instance, the usage of t[1] and t[2] in the following is untasty.

@chain 1:10 begin
    zip(20:30)
    @map t -> t[1] + t[2]
end

With this macro, you write something tasty:

@chain 1:10 begin
    zip(20:30)
    @map @unpack (a, b) -> a + b 
end

This uses splatting under the hood so it's not too efficient for a high number of args. For a small number of args, this is good.

source
Chainables.@vecMacro
@vec(f::Function)

Return the vectorised form of the function. Useful for ensuring vectorisation when using other utilities from the Chainables.jl package. For example:

@chain 1:3 begin 
    zip(4:6)
    @apply @vec @unpack (a, b) -> a * b^2
end 
source
Chainables.@xMacro
@x

A quick macro to create a placeholder variable for partial application (currying) purposes.

@x creates a Placeholder, and this is recognised by:

  • partial (the function) such as partial(foo, arg1, @x, arg2)
  • @partial (the macro) such as @partial foo(arg1, @x, arg2)
  • @∂ such as @∂ foo(arg1, @x, arg2)
source