Skip to content

Commit 62e7fd0

Browse files
committed
migrated from Setfield to Accessors
1 parent a747257 commit 62e7fd0

File tree

7 files changed

+93
-79
lines changed

7 files changed

+93
-79
lines changed

Project.toml

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
name = "Mill"
22
uuid = "1d0525e4-8992-11e8-313c-e310e1f6ddea"
33
authors = ["Tomas Pevny <[email protected]>", "Simon Mandlik <[email protected]>"]
4-
version = "2.10"
4+
version = "2.10.0"
55

66
[deps]
7+
Accessors = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697"
78
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
89
Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"
910
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
@@ -17,12 +18,12 @@ MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
1718
OneHotArrays = "0b1bfda6-eb8a-41d2-88d8-f5af5cad476f"
1819
PooledArrays = "2dfb63ee-cc39-5dd5-95bd-886bf059d720"
1920
Preferences = "21216c6a-2e73-6563-6e65-726566657250"
20-
Setfield = "efcf1570-3423-57d1-acb7-fd33fddbac46"
2121
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
2222
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
2323
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
2424

2525
[compat]
26+
Accessors = "0.1"
2627
ChainRulesCore = "1"
2728
Combinatorics = "1.0"
2829
DataFrames = "1"
@@ -35,7 +36,6 @@ MacroTools = "0.5"
3536
OneHotArrays = "0.1, 0.2"
3637
PooledArrays = "1"
3738
Preferences = "1"
38-
Setfield = "1"
3939
julia = "1.9"
4040

4141
[extras]
@@ -45,4 +45,4 @@ InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
4545
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
4646

4747
[targets]
48-
test = [ "BenchmarkTools", "Documenter", "InteractiveUtils", "Random" ]
48+
test = ["BenchmarkTools", "Documenter", "InteractiveUtils", "Random"]

docs/Project.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
[deps]
2+
Accessors = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697"
23
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
34
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
45
DocumenterCitations = "daee34ce-89f3-4625-b898-19384cb65244"
@@ -10,6 +11,5 @@ HierarchicalUtils = "f9ccea15-0695-44b9-8113-df7c26ae4fa9"
1011
Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306"
1112
Mill = "1d0525e4-8992-11e8-313c-e310e1f6ddea"
1213
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
13-
Setfield = "efcf1570-3423-57d1-acb7-fd33fddbac46"
1414
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
1515
Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f"

docs/make.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using Pkg
22
using Documenter, DocumenterCitations, Literate
3-
using Mill, Flux, Random, SparseArrays, Setfield, HierarchicalUtils
3+
using Mill, Flux, Random, SparseArrays, Accessors, HierarchicalUtils
44

55
#=
66
Useful resources for writing docs:
@@ -53,7 +53,7 @@ function Mill.unpack2mill(ds::LazyNode{:Sentence})
5353
end
5454

5555
DocMeta.setdocmeta!(Mill, :DocTestSetup, quote
56-
using Mill, Flux, Random, SparseArrays, Setfield, HierarchicalUtils
56+
using Mill, Flux, Random, SparseArrays, Accessors, HierarchicalUtils
5757
ENV["LINES"] = ENV["COLUMNS"] = typemax(Int)
5858
end; recursive=true)
5959

src/Mill.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module Mill
22

3+
using Accessors
34
using ChainRulesCore
45
using Combinatorics
56
using DataFrames
@@ -12,14 +13,13 @@ using MacroTools
1213
using OneHotArrays
1314
using PooledArrays
1415
using Preferences
15-
using Setfield
1616
using SparseArrays
1717
using Statistics
1818

1919
using Base: CodeUnits, nameof
2020
using ChainRulesCore: NotImplemented, NotImplementedException
2121
using HierarchicalUtils: encode, stringify
22-
using Setfield: IdentityLens, PropertyLens, IndexLens, ComposedLens
22+
using Accessors: PropertyLens, IndexLens, ComposedOptic
2323

2424
import Base: *, ==
2525

src/util.jl

+78-63
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ end
99
"""
1010
pred_lens(p, n)
1111
12-
Return a `Vector` of `Setfield.Lens`es for accessing all nodes/fields in `n` conforming to predicate `p`.
12+
Return a `Vector` of `Accessors.jl` lenses for accessing all nodes/fields in `n` conforming to
13+
predicate `p`.
1314
1415
# Examples
1516
```jldoctest
@@ -20,18 +21,35 @@ ProductNode # 2 obs, 16 bytes
2021
╰── ArrayNode(2×2 Array with Int64 elements) # 2 obs, 80 bytes
2122
2223
julia> pred_lens(x -> x isa ArrayNode, n)
23-
1-element Vector{Setfield.ComposedLens{Setfield.PropertyLens{:data}, Setfield.IndexLens{Tuple{Int64}}}}:
24-
(@lens _.data[2])
24+
1-element Vector{Any}:
25+
(@optic _.data[2])
2526
```
2627
2728
See also: [`list_lens`](@ref), [`find_lens`](@ref), [`findnonempty_lens`](@ref).
2829
"""
29-
pred_lens(p::Function, n) = _pred_lens(p, n)
30+
function pred_lens(p::Function, n)
31+
result = Any[]
32+
_pred_lens!(p, n, (), result)
33+
return result
34+
end
35+
36+
_pred_lens!(p::Function, x, l, result) = p(x) && push!(result, Accessors.opticcompose(l...))
37+
function _pred_lens!(p::Function, n::T, l, result) where T <: AbstractMillStruct
38+
p(n) && push!(result, Accessors.opticcompose(l...))
39+
for k in fieldnames(T)
40+
_pred_lens!(p, getproperty(n, k), (l..., PropertyLens{k}()), result)
41+
end
42+
end
43+
function _pred_lens!(p::Function, n::Union{Tuple, NamedTuple}, l, result)
44+
for i in eachindex(n)
45+
_pred_lens!(p, n[i], (l..., IndexLens((i,))), result)
46+
end
47+
end
3048

3149
"""
3250
list_lens(n)
3351
34-
Return a `Vector` of `Setfield.Lens`es for accessing all nodes/fields in `n`.
52+
Return a `Vector` of `Accessors.jl` lenses for accessing all nodes/fields in `n`.
3553
3654
# Examples
3755
```jldoctest
@@ -42,16 +60,16 @@ ProductNode # 2 obs, 16 bytes
4260
╰── ArrayNode(2×2 Array with Int64 elements) # 2 obs, 80 bytes
4361
4462
julia> list_lens(n)
45-
9-element Vector{Lens}:
46-
(@lens _)
47-
(@lens _.data[1])
48-
(@lens _.data[1].data)
49-
(@lens _.data[1].bags)
50-
(@lens _.data[1].metadata)
51-
(@lens _.data[2])
52-
(@lens _.data[2].data)
53-
(@lens _.data[2].metadata)
54-
(@lens _.metadata)
63+
9-element Vector{Any}:
64+
identity (generic function with 1 method)
65+
(@optic _.data[1])
66+
(@optic _.data[1].data)
67+
(@optic _.data[1].bags)
68+
(@optic _.data[1].metadata)
69+
(@optic _.data[2])
70+
(@optic _.data[2].data)
71+
(@optic _.data[2].metadata)
72+
(@optic _.metadata)
5573
```
5674
5775
See also: [`pred_lens`](@ref), [`find_lens`](@ref), [`findnonempty_lens`](@ref).
@@ -61,7 +79,8 @@ list_lens(n) = pred_lens(t -> true, n)
6179
"""
6280
findnonempty_lens(n)
6381
64-
Return a `Vector` of `Setfield.Lens`es for accessing all nodes/fields in `n` that have at least one observation.
82+
Return a `Vector` of `Accessors.jl` lenses for accessing all nodes/fields in `n` that contain at
83+
least one observation.
6584
6685
# Examples
6786
```jldoctest
@@ -72,10 +91,10 @@ ProductNode # 2 obs, 16 bytes
7291
╰── ArrayNode(2×2 Array with Int64 elements) # 2 obs, 80 bytes
7392
7493
julia> findnonempty_lens(n)
75-
3-element Vector{Lens}:
76-
(@lens _)
77-
(@lens _.data[1])
78-
(@lens _.data[2])
94+
3-element Vector{Any}:
95+
identity (generic function with 1 method)
96+
(@optic _.data[1])
97+
(@optic _.data[2])
7998
```
8099
81100
See also: [`pred_lens`](@ref), [`list_lens`](@ref), [`find_lens`](@ref).
@@ -85,8 +104,8 @@ findnonempty_lens(n) = pred_lens(t -> t isa AbstractMillNode && numobs(t) > 0, n
85104
"""
86105
find_lens(n, x)
87106
88-
Return a `Vector` of `Setfield.Lens`es for accessing all nodes/fields in `n` that return `true` when
89-
compared to `x` using `Base.===`.
107+
Return a `Vector` of `Accessors.jl` lenses for accessing all nodes/fields in `n` that return `true`
108+
when compared to `x` using `Base.===`.
90109
91110
# Examples
92111
```jldoctest
@@ -97,30 +116,19 @@ ProductNode # 2 obs, 16 bytes
97116
╰── ArrayNode(2×2 Array with Int64 elements) # 2 obs, 80 bytes
98117
99118
julia> find_lens(n, n.data[1])
100-
1-element Vector{Setfield.ComposedLens{Setfield.PropertyLens{:data}, Setfield.IndexLens{Tuple{Int64}}}}:
101-
(@lens _.data[1])
119+
1-element Vector{Any}:
120+
(@optic _.data[1])
102121
```
103122
104123
See also: [`pred_lens`](@ref), [`list_lens`](@ref), [`findnonempty_lens`](@ref).
105124
"""
106125
find_lens(n, x) = pred_lens(t -> t x, n)
107126

108-
_pred_lens(p::Function, n) = p(n) ? [IdentityLens()] : Lens[]
109-
function _pred_lens(p::Function, n::T) where T <: AbstractMillStruct
110-
res = [map(l -> PropertyLens{k}() l, _pred_lens(p, getproperty(n, k))) for k in fieldnames(T)]
111-
res = vcat(filter(!isempty, res)...)
112-
p(n) ? [IdentityLens(); res] : res
113-
end
114-
function _pred_lens(p::Function, n::Union{Tuple, NamedTuple})
115-
res = [map(l -> IndexLens(tuple(i)) l, _pred_lens(p, n[i])) for i in eachindex(n)]
116-
vcat(filter(!isempty, res)...)
117-
end
118-
119127
"""
120128
code2lens(n, c)
121129
122-
Convert code `c` from [HierarchicalUtils.jl](@ref) traversal to a `Vector` of `Setfield.Lens` such
123-
that they access each node in tree egal to `n`.
130+
Convert code `c` from [HierarchicalUtils.jl](@ref) traversal to a `Vector` of `Accessors.jl`
131+
lenses such that they access each node in tree `n` egal to node under code `c` in the tree.
124132
125133
# Examples
126134
```jldoctest
@@ -133,8 +141,8 @@ ProductNode [""] # 2 obs, 16 bytes
133141
╰── ArrayNode(2×2 Array with Int64 elements) ["U"] # 2 obs, 80 bytes
134142
135143
julia> code2lens(n, "U")
136-
1-element Vector{Setfield.ComposedLens{Setfield.PropertyLens{:data}, Setfield.IndexLens{Tuple{Int64}}}}:
137-
(@lens _.data[2])
144+
1-element Vector{Any}:
145+
(@optic _.data[2])
138146
```
139147
140148
See also: [`lens2code`](@ref).
@@ -144,8 +152,8 @@ code2lens(n::AbstractMillStruct, c::AbstractString) = find_lens(n, n[c])
144152
"""
145153
lens2code(n, l)
146154
147-
Convert `Setfield.Lens` l to a `Vector` of codes from [HierarchicalUtils.jl](@ref) traversal such
148-
that they access each node in tree egal to `n`.
155+
Convert `Accessors.jl` lens `l` to a `Vector` of codes from [HierarchicalUtils.jl](@ref) traversal
156+
such that they access each node in tree `n` egal to node accessible by lens `l`.
149157
150158
# Examples
151159
```jldoctest
@@ -157,20 +165,27 @@ ProductNode [""] # 2 obs, 16 bytes
157165
│ ╰── ∅ ["M"]
158166
╰── ArrayNode(2×2 Array with Int64 elements) ["U"] # 2 obs, 80 bytes
159167
160-
julia> lens2code(n, (@lens _.data[2]))
168+
julia> lens2code(n, (@optic _.data[2]))
161169
1-element Vector{String}:
162170
"U"
163171
172+
julia> lens2code(n, (@optic _.data[∗]))
173+
2-element Vector{String}:
174+
"E"
175+
"U"
176+
164177
```
165178
166179
See also: [`code2lens`](@ref).
167180
"""
168-
lens2code(n::AbstractMillStruct, l::Lens) = HierarchicalUtils.find_traversal(n, get(n, l))
181+
lens2code(n::AbstractMillStruct, l) = mapreduce(vcat, Accessors.getall(n, l)) do x
182+
HierarchicalUtils.find_traversal(n, x)
183+
end
169184

170185
"""
171186
model_lens(m, l)
172187
173-
Convert `Setfield.Lens` `l` for a data node to a new lens for accessing the same location in model `m`.
188+
Convert `Accessors.jl` lens `l` for a data node to a new lens for accessing the same location in model `m`.
174189
175190
# Examples
176191
```jldoctest
@@ -187,26 +202,26 @@ ProductModel ↦ Dense(20 => 10) # 2 arrays, 210 params, 920 bytes
187202
│ ╰── ArrayModel(Dense(2 => 10)) # 2 arrays, 30 params, 200 bytes
188203
╰── ArrayModel(Dense(2 => 10)) # 2 arrays, 30 params, 200 bytes
189204
190-
julia> model_lens(m, (@lens _.data[2]))
191-
(@lens _.ms[2])
205+
julia> model_lens(m, (@optic _.data[2]))
206+
(@optic _.ms[2])
192207
```
193208
194209
See also: [`data_lens`](@ref).
195210
"""
196-
function model_lens(model, lens::ComposedLens)
197-
outerlens = model_lens(model, lens.outer)
198-
outerlens model_lens(get(model, outerlens), lens.inner)
211+
function model_lens(model, lens::ComposedOptic)
212+
innerlens = model_lens(model, lens.inner)
213+
innerlens model_lens(only(getall(model, innerlens)), lens.outer)
199214
end
200-
model_lens(::ArrayModel, ::PropertyLens{:data}) = @lens _.m
201-
model_lens(::BagModel, ::PropertyLens{:data}) = @lens _.im
202-
model_lens(::ProductModel, ::PropertyLens{:data}) = @lens _.ms
215+
model_lens(::ArrayModel, ::PropertyLens{:data}) = @optic _.m
216+
model_lens(::BagModel, ::PropertyLens{:data}) = @optic _.im
217+
model_lens(::ProductModel, ::PropertyLens{:data}) = @optic _.ms
203218
model_lens(::Union{NamedTuple, Tuple}, lens::IndexLens) = lens
204-
model_lens(::Union{AbstractMillModel, NamedTuple, Tuple}, lens::IdentityLens) = lens
219+
model_lens(::Union{AbstractMillModel, NamedTuple, Tuple}, lens::typeof(identity)) = lens
205220

206221
"""
207222
data_lens(n, l)
208223
209-
Convert `Setfield.Lens` `l` for a model node to a new lens for accessing the same location in data node `n`.
224+
Convert `Accessors.jl` lens `l` for a model node to a new lens for accessing the same location in data node `n`.
210225
211226
# Examples
212227
```jldoctest
@@ -222,21 +237,21 @@ ProductModel ↦ Dense(20 => 10) # 2 arrays, 210 params, 920 bytes
222237
│ ╰── ArrayModel(Dense(2 => 10)) # 2 arrays, 30 params, 200 bytes
223238
╰── ArrayModel(Dense(2 => 10)) # 2 arrays, 30 params, 200 bytes
224239
225-
julia> data_lens(n, (@lens _.ms[2]))
226-
(@lens _.data[2])
240+
julia> data_lens(n, (@optic _.ms[2]))
241+
(@optic _.data[2])
227242
```
228243
229244
See also: [`data_lens`](@ref).
230245
"""
231-
function data_lens(ds, lens::ComposedLens)
232-
outerlens = data_lens(ds, lens.outer)
233-
outerlens data_lens(get(ds, outerlens), lens.inner)
246+
function data_lens(ds, lens::ComposedOptic)
247+
innerlens = data_lens(ds, lens.inner)
248+
innerlens data_lens(only(getall(ds, innerlens)), lens.outer)
234249
end
235-
data_lens(::ArrayNode, ::PropertyLens{:m}) = @lens _.data
236-
data_lens(::AbstractBagNode, ::PropertyLens{:im}) = @lens _.data
237-
data_lens(::AbstractProductNode, ::PropertyLens{:ms}) = @lens _.data
250+
data_lens(::ArrayNode, ::PropertyLens{:m}) = @optic _.data
251+
data_lens(::AbstractBagNode, ::PropertyLens{:im}) = @optic _.data
252+
data_lens(::AbstractProductNode, ::PropertyLens{:ms}) = @optic _.data
238253
data_lens(::Union{NamedTuple, Tuple}, lens::IndexLens) = lens
239-
data_lens(::Union{AbstractMillNode, NamedTuple, Tuple}, lens::IdentityLens) = lens
254+
data_lens(::Union{AbstractMillNode, NamedTuple, Tuple}, lens::typeof(identity)) = lens
240255

241256
"""
242257
replacein(n, old, new)

test/runtests.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ end
9191

9292
@testset "Doctests" begin
9393
DocMeta.setdocmeta!(Mill, :DocTestSetup, quote
94-
using Mill, Flux, Random, SparseArrays, Setfield, HierarchicalUtils
94+
using Mill, Flux, Random, SparseArrays, Accessors, HierarchicalUtils
9595
# do not shorten prints in doctests
9696
ENV["LINES"] = ENV["COLUMNS"] = typemax(Int)
9797
end; recursive=true)

0 commit comments

Comments
 (0)