Internals

Setfield.FunctionLensType
FunctionLens(f)
@lens f(_)

Lens with get method definition that simply calls f. set method for each function f must be implemented manually. Use methods(set, (Any, Setfield.FunctionLens, Any)) to get a list of supported functions.

Note that FunctionLens flips the order of composition; i.e., (@lens f(_)) ∘ (@lens g(_)) == @lens g(f(_)).

Example

julia> using Setfield

julia> obj = ((1, 2), (3, 4));

julia> lens = (@lens first(_)) ∘ (@lens last(_))
(@lens last(first(_)))

julia> get(obj, lens)
2

julia> set(obj, lens, '2')
((1, '2'), (3, 4))

Implementation

To use myfunction as a lens, define a set method with the following signature:

Setfield.set(obj, ::typeof(@lens myfunction(_)), val) = ...

typeof is used above instead of FunctionLens because how actual type of @lens myfunction(_) is implemented is not the part of stable API.

source
Base.:∘Method
lens₁ ∘ lens₂

Compose lenses lens₁, lens₂, ..., lensₙ to access nested objects.

Example

julia> using Setfield

julia> obj = (a = (b = (c = 1,),),);

julia> la = @lens _.a
       lb = @lens _.b
       lc = @lens _.c
       lens = la ∘ lb ∘ lc
(@lens _.a.b.c)

julia> get(obj, lens)
1
source
Setfield.composeFunction
compose([lens₁, [lens₂, [lens₃, ...]]])

Compose lens₁, lens₂ etc. There is one subtle point here: While the two composition orders (lens₁ ∘ lens₂) ∘ lens₃ and lens₁ ∘ (lens₂ ∘ lens₃) have equivalent semantics, their performance may not be the same. The compiler tends to optimize right associative composition (second case) better then left associative composition.

The compose function tries to use a composition order, that the compiler likes. The composition order is therefore not part of the stable API.

source
Setfield.lensmacroMethod
lensmacro(lenstransform, ex::Expr)

This function can be used to create a customized variant of @lens. It works by applying lenstransform to the created lens at runtime.

function mytransform(lens::Lens)::Lens
    ...
end
macro mylens(ex)
    lensmacro(mytransform, ex)
end

See also setmacro.

source
Setfield.setmacroMethod
setmacro(lenstransform, ex::Expr; overwrite::Bool=false)

This function can be used to create a customized variant of @set. It works by applying lenstransform to the lens that is used in the customized @set macro at runtime.

function mytransform(lens::Lens)::Lens
    ...
end
macro myset(ex)
    setmacro(mytransform, ex)
end

See also lensmacro.

source