-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dynamic creation of lenses #73
Comments
Is this what you need? julia> using Setfield
julia> a = Setfield.PropertyLens{:a}()
(@lens _.a)
julia> b = Setfield.PropertyLens{:b}()
(@lens _.b)
julia> a ∘ b
(@lens _.a.b) |
Thank @tkf, I am aware of this syntax. Just curious whether an easier way of doing this is possible. |
Hmm... I think writing julia> mapfoldl(x -> Setfield.PropertyLens{x}(), ∘, [:prop1, :prop2, :prop3])
(@lens _.prop1.prop2.prop3) |
Ha, I like this one-liner! Thank you! Can this one-liner be added to public APIs and documentation? |
I don't know if it worth mentioning since it's just another way to write l = @lens _
for name in [:prop1, :prop2, :prop3]
l = l ∘ Setfield.PropertyLens{name}()
end
l I think an actionable item here is to expose |
Thank you @tkf. That's a good idea! I prefer writing makelens(props::AbstractVector{Symbol}) = mapfoldl(x -> Setfield.PropertyLens{x}(), ∘, props) since the latter one is less readable. I can make a PR. The reason why I want an API to handle this is that I do not want to write something dealing with lenses in my package, which has nothing to do with lenses. That's what a package like this should provide. |
I am okay with @tkf s suggestion to make |
I'm mild -1 to adding such function as it's just onelinear. Having said that, one justification would be that a function propertylens(name::Symbol) = Propertylens{name}()
propertylens(names::Symbol...) = mapfoldl(propertylens, ∘, names) is somewhat similar to string(x) = String(x)
string(xs...) = mapfoldl(string, *, xs) |
Building a string is a much more common operation then what we do here though. Also Still I really like the syntax much better then @singularitti, @tkf Do you have some open source code where you would like to use this/already use this? |
Hi @jw3126, I do not have an open-source code using this. But I may want to use this feature in the near future. |
That's the reason why I didn't call But this signature does not match well for index lens, as maybe you'd want indexlens(idx...) = IndexLens(idx) so that
I agree. If we are to make the constructor an API, I think it's better to have
No, I don't have a usecase. I'm totally OK with writing When I touch |
My use case may be: function modify_fields(obj::MyNestedType, val, props...)
lens = mapfoldl(x -> Setfield.PropertyLens{x}(), ∘, [props...])
set(obj, lens, val)
end where struct M
c::N
end
struct N
d
end
struct A
a::M
b
e
end
x = A(M(N(1)), 2, 4)
modify_fields(x, 3, :a, :c:, :d)
# return y with y.a.c.d = 3 |
Is it that the name "lens" feels out of place? Maybe |
I think it makes more senses to those who have seen Haskell's lens, so let's keep this name. And if a user uses |
Note that your As for changes in this library I am ok with documenting+exporting PropertyLens(name::Symbol) = PropertyLens{name}() but not |
Could we have a syntax that supports dynamic creation of lenses? Currently, if I want to create some lens, I need to write
But sometimes I may have properties that are stored in variables. So I want to request a syntax like
where
:prop1
,:prop2
and:prop3
are just symbols, usually got from thefieldnames
function._
is omitted there. Andvar1 = :prop1
,var2 = :prop2
,var3 = :prop3
, respectively.Is this possible?
The text was updated successfully, but these errors were encountered: