Internals
Setfield.FunctionLens — TypeFunctionLens(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.
Base.:∘ — Methodlens₁ ∘ 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)
1Setfield.compose — Functioncompose([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.
Setfield.lensmacro — Methodlensmacro(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)
endSee also setmacro.
Setfield.setmacro — Methodsetmacro(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)
endSee also lensmacro.