juliaobjects / accessors.jl Goto Github PK
View Code? Open in Web Editor NEWUpdate immutable data
License: Other
Update immutable data
License: Other
Hi!
Recently, I started to see errors during precompilation of my packages that use Accessors:
Precompiling SatelliteToolbox
21 dependencies successfully precompiled in 12 seconds. 35 already precompiled.
3 dependencies had output during precompilation:
┌ Accessors → AccessorsTestExt
│ ┌ Warning: Module AccessorsDatesExt with build ID ffffffff-ffff-ffff-0000-0128c163477b is missing from the cache.
│ │ This may mean AccessorsDatesExt [308068fd-b978-57fd-b78f-2a52fb63dba4] does not support precompilation but is imported
by a module that does.
│ └ @ Base loading.jl:1942
│ ┌ Error: Error during loading of extension AccessorsDatesExt of Accessors, use `Base.retry_load_extensions()` to retry.
│ │ exception =
│ │ 1-element ExceptionStack:
│ │ Declaring __precompile__(false) is not allowed in files that are being precompiled.
│ │ Stacktrace:
│ │ [1] _require(pkg::Base.PkgId, env::Nothing)
│ │ @ Base ./loading.jl:1946
│ │ [2] __require_prelocked(uuidkey::Base.PkgId, env::Nothing)
│ │ @ Base ./loading.jl:1806
│ │ [3] #invoke_in_world#3
│ │ @ Base ./essentials.jl:921 [inlined]
│ │ [4] invoke_in_world
│ │ @ Base ./essentials.jl:918 [inlined]
│ │ [5] _require_prelocked
│ │ @ Base ./loading.jl:1797 [inlined]
│ │ [6] _require_prelocked
│ │ @ Base ./loading.jl:1796 [inlined]
│ │ [7] run_extension_callbacks(extid::Base.ExtensionId)
│ │ @ Base ./loading.jl:1289
│ │ [8] run_extension_callbacks(pkgid::Base.PkgId)
│ │ @ Base ./loading.jl:1324
│ │ [9] run_package_callbacks(modkey::Base.PkgId)
│ │ @ Base ./loading.jl:1158
│ │ [10] __require_prelocked(uuidkey::Base.PkgId, env::String)
│ │ @ Base ./loading.jl:1813
│ │ [11] #invoke_in_world#3
│ │ @ Base ./essentials.jl:921 [inlined]
│ │ [12] invoke_in_world
│ │ @ Base ./essentials.jl:918 [inlined]
│ │ [13] _require_prelocked(uuidkey::Base.PkgId, env::String)
│ │ @ Base ./loading.jl:1797
│ │ [14] macro expansion
│ │ @ Base ./loading.jl:1784 [inlined]
│ │ [15] macro expansion
│ │ @ Base ./lock.jl:267 [inlined]
│ │ [16] __require(into::Module, mod::Symbol)
│ │ @ Base ./loading.jl:1747
│ │ [17] #invoke_in_world#3
│ │ @ Base ./essentials.jl:921 [inlined]
│ │ [18] invoke_in_world
│ │ @ Base ./essentials.jl:918 [inlined]
│ │ [19] require(into::Module, mod::Symbol)
│ │ @ Base ./loading.jl:1740
│ │ [20] include
│ │ @ Base ./Base.jl:495 [inlined]
│ │ [21] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{St
ring}, load_path::Vector{String}, concrete_deps::Vector{Pair{Base.PkgId, UInt128}}, source::String)
│ │ @ Base ./loading.jl:2216
│ │ [22] top-level scope
│ │ @ stdin:3
│ │ [23] eval
│ │ @ Core ./boot.jl:385 [inlined]
│ │ [24] include_string(mapexpr::typeof(identity), mod::Module, code::String, filename::String)
│ │ @ Base ./loading.jl:2070
│ │ [25] include_string
│ │ @ Base ./loading.jl:2080 [inlined]
│ │ [26] exec_options(opts::Base.JLOptions)
│ │ @ Base ./client.jl:316
│ │ [27] _start()
│ │ @ Base ./client.jl:552
│ └ @ Base loading.jl:1295
│ ┌ Warning: Module AccessorsTestExt with build ID ffffffff-ffff-ffff-0000-0128b54e2ef6 is missing from the cache.
│ │ This may mean AccessorsTestExt [3f8c54d2-55ce-559e-9981-66f7a1691a45] does not support precompilation but is imported b
y a module that does.
│ └ @ Base loading.jl:1942
│ ┌ Error: Error during loading of extension AccessorsTestExt of Accessors, use `Base.retry_load_extensions()` to retry.
│ │ exception =
│ │ 1-element ExceptionStack:
│ │ Declaring __precompile__(false) is not allowed in files that are being precompiled.
│ │ Stacktrace:
│ │ [1] _require(pkg::Base.PkgId, env::Nothing)
│ │ @ Base ./loading.jl:1946
│ │ [2] __require_prelocked(uuidkey::Base.PkgId, env::Nothing)
│ │ @ Base ./loading.jl:1806
│ │ [3] #invoke_in_world#3
│ │ @ Base ./essentials.jl:921 [inlined]
│ │ [4] invoke_in_world
│ │ @ Base ./essentials.jl:918 [inlined]
│ │ [5] _require_prelocked
│ │ @ Base ./loading.jl:1797 [inlined]
│ │ [6] _require_prelocked
│ │ @ Base ./loading.jl:1796 [inlined]
│ │ [7] run_extension_callbacks(extid::Base.ExtensionId)
│ │ @ Base ./loading.jl:1289
│ │ [8] run_extension_callbacks(pkgid::Base.PkgId)
│ │ @ Base ./loading.jl:1324
│ │ [9] run_package_callbacks(modkey::Base.PkgId)
│ │ @ Base ./loading.jl:1158
│ │ [10] __require_prelocked(uuidkey::Base.PkgId, env::String)
│ │ @ Base ./loading.jl:1813
│ │ [11] #invoke_in_world#3
│ │ @ Base ./essentials.jl:921 [inlined]
│ │ [12] invoke_in_world
│ │ @ Base ./essentials.jl:918 [inlined]
│ │ [13] _require_prelocked(uuidkey::Base.PkgId, env::String)
│ │ @ Base ./loading.jl:1797
│ │ [14] macro expansion
│ │ @ Base ./loading.jl:1784 [inlined]
│ │ [15] macro expansion
│ │ @ Base ./lock.jl:267 [inlined]
│ │ [16] __require(into::Module, mod::Symbol)
│ │ @ Base ./loading.jl:1747
│ │ [17] #invoke_in_world#3
│ │ @ Base ./essentials.jl:921 [inlined]
│ │ [18] invoke_in_world
│ │ @ Base ./essentials.jl:918 [inlined]
│ │ [19] require(into::Module, mod::Symbol)
│ │ @ Base ./loading.jl:1740
│ │ [20] include
│ │ @ Base ./Base.jl:495 [inlined]
│ │ [21] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{St
ring}, load_path::Vector{String}, concrete_deps::Vector{Pair{Base.PkgId, UInt128}}, source::String)
│ │ @ Base ./loading.jl:2216
│ │ [22] top-level scope
│ │ @ stdin:3
│ │ [23] eval
│ │ @ Core ./boot.jl:385 [inlined]
│ │ [24] include_string(mapexpr::typeof(identity), mod::Module, code::String, filename::String)
│ │ @ Base ./loading.jl:2070
│ │ [25] include_string
│ │ @ Base ./loading.jl:2080 [inlined]
│ │ [26] exec_options(opts::Base.JLOptions)
│ │ @ Base ./client.jl:316
│ │ [27] _start()
│ │ @ Base ./client.jl:552
│ └ @ Base loading.jl:1295
│ ┌ Warning: Module AccessorsTestExt with build ID ffffffff-ffff-ffff-0000-0128b54e2ef6 is missing from the cache.
│ │ This may mean AccessorsTestExt [3f8c54d2-55ce-559e-9981-66f7a1691a45] does not support precompilation but is imported b
y a module that does.
│ └ @ Base loading.jl:1942
│ ┌ Error: Error during loading of extension AccessorsTestExt of Accessors, use `Base.retry_load_extensions()` to retry.
│ │ exception =
│ │ 1-element ExceptionStack:
│ │ Declaring __precompile__(false) is not allowed in files that are being precompiled.
│ │ Stacktrace:
│ │ [1] _require(pkg::Base.PkgId, env::Nothing)
│ │ @ Base ./loading.jl:1946
│ │ [2] __require_prelocked(uuidkey::Base.PkgId, env::Nothing)
│ │ @ Base ./loading.jl:1806
│ │ [3] #invoke_in_world#3
│ │ @ Base ./essentials.jl:921 [inlined]
│ │ [4] invoke_in_world
│ │ @ Base ./essentials.jl:918 [inlined]
│ │ [5] _require_prelocked
│ │ @ Base ./loading.jl:1797 [inlined]
│ │ [6] _require_prelocked
│ │ @ Base ./loading.jl:1796 [inlined]
│ │ [7] run_extension_callbacks(extid::Base.ExtensionId)
│ │ @ Base ./loading.jl:1289
│ │ [8] run_extension_callbacks(pkgid::Base.PkgId)
│ │ @ Base ./loading.jl:1324
│ │ [9] run_package_callbacks(modkey::Base.PkgId)
│ │ @ Base ./loading.jl:1158
│ │ [10] __require_prelocked(uuidkey::Base.PkgId, env::String)
│ │ @ Base ./loading.jl:1813
│ │ [11] #invoke_in_world#3
│ │ @ Base ./essentials.jl:921 [inlined]
│ │ [12] invoke_in_world
│ │ @ Base ./essentials.jl:918 [inlined]
│ │ [13] _require_prelocked(uuidkey::Base.PkgId, env::String)
│ │ @ Base ./loading.jl:1797
│ │ [14] macro expansion
│ │ @ Base ./loading.jl:1784 [inlined]
│ │ [15] macro expansion
│ │ @ Base ./lock.jl:267 [inlined]
│ │ [16] __require(into::Module, mod::Symbol)
│ │ @ Base ./loading.jl:1747
│ │ [17] #invoke_in_world#3
│ │ @ Base ./essentials.jl:921 [inlined]
│ │ [18] invoke_in_world
│ │ @ Base ./essentials.jl:918 [inlined]
│ │ [19] require(into::Module, mod::Symbol)
│ │ @ Base ./loading.jl:1740
│ │ [20] include
│ │ @ Base ./Base.jl:495 [inlined]
│ │ [21] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{St
ring}, load_path::Vector{String}, concrete_deps::Vector{Pair{Base.PkgId, UInt128}}, source::String)
│ │ @ Base ./loading.jl:2216
│ │ [22] top-level scope
│ │ @ stdin:3
│ │ [23] eval
│ │ @ Core ./boot.jl:385 [inlined]
│ │ [24] include_string(mapexpr::typeof(identity), mod::Module, code::String, filename::String)
│ │ @ Base ./loading.jl:2070
│ │ [25] include_string
│ │ @ Base ./loading.jl:2080 [inlined]
│ │ [26] exec_options(opts::Base.JLOptions)
│ │ @ Base ./client.jl:316
│ │ [27] _start()
│ │ @ Base ./client.jl:552
│ └ @ Base loading.jl:1295
└
┌ Accessors → AccessorsLinearAlgebraExt
│ ┌ Warning: Module AccessorsLinearAlgebraExt with build ID ffffffff-ffff-ffff-0000-012844f91d11 is missing from the cache.
│ │ This may mean AccessorsLinearAlgebraExt [6d540e18-2ad7-59a5-acf8-1761f4011e1b] does not support precompilation but is i
mported by a module that does.
│ └ @ Base loading.jl:1942
│ ┌ Error: Error during loading of extension AccessorsLinearAlgebraExt of Accessors, use `Base.retry_load_extensions()` to
retry.
│ │ exception =
│ │ 1-element ExceptionStack:
│ │ Declaring __precompile__(false) is not allowed in files that are being precompiled.
│ │ Stacktrace:
│ │ [1] _require(pkg::Base.PkgId, env::Nothing)
│ │ @ Base ./loading.jl:1946
│ │ [2] __require_prelocked(uuidkey::Base.PkgId, env::Nothing)
│ │ @ Base ./loading.jl:1806
│ │ [3] #invoke_in_world#3
│ │ @ Base ./essentials.jl:921 [inlined]
│ │ [4] invoke_in_world
│ │ @ Base ./essentials.jl:918 [inlined]
│ │ [5] _require_prelocked
│ │ @ Base ./loading.jl:1797 [inlined]
│ │ [6] _require_prelocked
│ │ @ Base ./loading.jl:1796 [inlined]
│ │ [7] run_extension_callbacks(extid::Base.ExtensionId)
│ │ @ Base ./loading.jl:1289
│ │ [8] run_extension_callbacks(pkgid::Base.PkgId)
│ │ @ Base ./loading.jl:1324
│ │ [9] run_package_callbacks(modkey::Base.PkgId)
│ │ @ Base ./loading.jl:1158
│ │ [10] __require_prelocked(uuidkey::Base.PkgId, env::String)
│ │ @ Base ./loading.jl:1813
│ │ [11] #invoke_in_world#3
│ │ @ Base ./essentials.jl:921 [inlined]
│ │ [12] invoke_in_world
│ │ @ Base ./essentials.jl:918 [inlined]
│ │ [13] _require_prelocked(uuidkey::Base.PkgId, env::String)
│ │ @ Base ./loading.jl:1797
│ │ [14] macro expansion
│ │ @ Base ./loading.jl:1784 [inlined]
│ │ [15] macro expansion
│ │ @ Base ./lock.jl:267 [inlined]
│ │ [16] __require(into::Module, mod::Symbol)
│ │ @ Base ./loading.jl:1747
│ │ [17] #invoke_in_world#3
│ │ @ Base ./essentials.jl:921 [inlined]
│ │ [18] invoke_in_world
│ │ @ Base ./essentials.jl:918 [inlined]
│ │ [19] require(into::Module, mod::Symbol)
│ │ @ Base ./loading.jl:1740
│ │ [20] include
│ │ @ Base ./Base.jl:495 [inlined]
│ │ [21] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{St
ring}, load_path::Vector{String}, concrete_deps::Vector{Pair{Base.PkgId, UInt128}}, source::String)
│ │ @ Base ./loading.jl:2216
│ │ [22] top-level scope
│ │ @ stdin:3
│ │ [23] eval
│ │ @ Core ./boot.jl:385 [inlined]
│ │ [24] include_string(mapexpr::typeof(identity), mod::Module, code::String, filename::String)
│ │ @ Base ./loading.jl:2070
│ │ [25] include_string
│ │ @ Base ./loading.jl:2080 [inlined]
│ │ [26] exec_options(opts::Base.JLOptions)
│ │ @ Base ./client.jl:316
│ │ [27] _start()
│ │ @ Base ./client.jl:552
│ └ @ Base loading.jl:1295
└
┌ Accessors → AccessorsDatesExt
│ ┌ Warning: Module AccessorsDatesExt with build ID ffffffff-ffff-ffff-0000-0127c5bbad19 is missing from the cache.
│ │ This may mean AccessorsDatesExt [308068fd-b978-57fd-b78f-2a52fb63dba4] does not support precompilation but is imported
by a module that does.
│ └ @ Base loading.jl:1942
│ ┌ Error: Error during loading of extension AccessorsDatesExt of Accessors, use `Base.retry_load_extensions()` to retry.
│ │ exception =
│ │ 1-element ExceptionStack:
│ │ Declaring __precompile__(false) is not allowed in files that are being precompiled.
│ │ Stacktrace:
│ │ [1] _require(pkg::Base.PkgId, env::Nothing)
│ │ @ Base ./loading.jl:1946
│ │ [2] __require_prelocked(uuidkey::Base.PkgId, env::Nothing)
│ │ @ Base ./loading.jl:1806
│ │ [3] #invoke_in_world#3
│ │ @ Base ./essentials.jl:921 [inlined]
│ │ [4] invoke_in_world
│ │ @ Base ./essentials.jl:918 [inlined]
│ │ [5] _require_prelocked
│ │ @ Base ./loading.jl:1797 [inlined]
│ │ [6] _require_prelocked
│ │ @ Base ./loading.jl:1796 [inlined]
│ │ [7] run_extension_callbacks(extid::Base.ExtensionId)
│ │ @ Base ./loading.jl:1289
│ │ [8] run_extension_callbacks(pkgid::Base.PkgId)
│ │ @ Base ./loading.jl:1324
│ │ [9] run_package_callbacks(modkey::Base.PkgId)
│ │ @ Base ./loading.jl:1158
│ │ [10] __require_prelocked(uuidkey::Base.PkgId, env::String)
│ │ @ Base ./loading.jl:1813
│ │ [11] #invoke_in_world#3
│ │ @ Base ./essentials.jl:921 [inlined]
│ │ [12] invoke_in_world
│ │ @ Base ./essentials.jl:918 [inlined]
│ │ [13] _require_prelocked(uuidkey::Base.PkgId, env::String)
│ │ @ Base ./loading.jl:1797
│ │ [14] macro expansion
│ │ @ Base ./loading.jl:1784 [inlined]
│ │ [15] macro expansion
│ │ @ Base ./lock.jl:267 [inlined]
│ │ [16] __require(into::Module, mod::Symbol)
│ │ @ Base ./loading.jl:1747
│ │ [17] #invoke_in_world#3
│ │ @ Base ./essentials.jl:921 [inlined]
│ │ [18] invoke_in_world
│ │ @ Base ./essentials.jl:918 [inlined]
│ │ [19] require(into::Module, mod::Symbol)
│ │ @ Base ./loading.jl:1740
│ │ [20] include
│ │ @ Base ./Base.jl:495 [inlined]
│ │ [21] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{St
ring}, load_path::Vector{String}, concrete_deps::Vector{Pair{Base.PkgId, UInt128}}, source::String)
│ │ @ Base ./loading.jl:2216
│ │ [22] top-level scope
│ │ @ stdin:3
│ │ [23] eval
│ │ @ Core ./boot.jl:385 [inlined]
│ │ [24] include_string(mapexpr::typeof(identity), mod::Module, code::String, filename::String)
│ │ @ Base ./loading.jl:2070
│ │ [25] include_string
│ │ @ Base ./loading.jl:2080 [inlined]
│ │ [26] exec_options(opts::Base.JLOptions)
│ │ @ Base ./client.jl:316
│ │ [27] _start()
│ │ @ Base ./client.jl:552
│ └ @ Base loading.jl:1295
│ ┌ Warning: Module AccessorsDatesExt with build ID ffffffff-ffff-ffff-0000-0127c5bbad19 is missing from the cache.
│ │ This may mean AccessorsDatesExt [308068fd-b978-57fd-b78f-2a52fb63dba4] does not support precompilation but is imported
by a module that does.
│ └ @ Base loading.jl:1942
│ ┌ Error: Error during loading of extension AccessorsDatesExt of Accessors, use `Base.retry_load_extensions()` to retry.
│ │ exception =
│ │ 1-element ExceptionStack:
│ │ Declaring __precompile__(false) is not allowed in files that are being precompiled.
│ │ Stacktrace:
│ │ [1] _require(pkg::Base.PkgId, env::Nothing)
│ │ @ Base ./loading.jl:1946
│ │ [2] __require_prelocked(uuidkey::Base.PkgId, env::Nothing)
│ │ @ Base ./loading.jl:1806
│ │ [3] #invoke_in_world#3
│ │ @ Base ./essentials.jl:921 [inlined]
│ │ [4] invoke_in_world
│ │ @ Base ./essentials.jl:918 [inlined]
│ │ [5] _require_prelocked
│ │ @ Base ./loading.jl:1797 [inlined]
│ │ [6] _require_prelocked
│ │ @ Base ./loading.jl:1796 [inlined]
│ │ [7] run_extension_callbacks(extid::Base.ExtensionId)
│ │ @ Base ./loading.jl:1289
│ │ [8] run_extension_callbacks(pkgid::Base.PkgId)
│ │ @ Base ./loading.jl:1324
│ │ [9] run_package_callbacks(modkey::Base.PkgId)
│ │ @ Base ./loading.jl:1158
│ │ [10] __require_prelocked(uuidkey::Base.PkgId, env::String)
│ │ @ Base ./loading.jl:1813
│ │ [11] #invoke_in_world#3
│ │ @ Base ./essentials.jl:921 [inlined]
│ │ [12] invoke_in_world
│ │ @ Base ./essentials.jl:918 [inlined]
│ │ [13] _require_prelocked(uuidkey::Base.PkgId, env::String)
│ │ @ Base ./loading.jl:1797
│ │ [14] macro expansion
│ │ @ Base ./loading.jl:1784 [inlined]
│ │ [15] macro expansion
│ │ @ Base ./lock.jl:267 [inlined]
│ │ [16] __require(into::Module, mod::Symbol)
│ │ @ Base ./loading.jl:1747
│ │ [17] #invoke_in_world#3
│ │ @ Base ./essentials.jl:921 [inlined]
│ │ [18] invoke_in_world
│ │ @ Base ./essentials.jl:918 [inlined]
│ │ [19] require(into::Module, mod::Symbol)
│ │ @ Base ./loading.jl:1740
│ │ [20] include
│ │ @ Base ./Base.jl:495 [inlined]
│ │ [21] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{St
ring}, load_path::Vector{String}, concrete_deps::Vector{Pair{Base.PkgId, UInt128}}, source::String)
│ │ @ Base ./loading.jl:2216
│ │ [22] top-level scope
│ │ @ stdin:3
│ │ [23] eval
│ │ @ Core ./boot.jl:385 [inlined]
│ │ [24] include_string(mapexpr::typeof(identity), mod::Module, code::String, filename::String)
│ │ @ Base ./loading.jl:2070
│ │ [25] include_string
│ │ @ Base ./loading.jl:2080 [inlined]
│ │ [26] exec_options(opts::Base.JLOptions)
│ │ @ Base ./client.jl:316
│ │ [27] _start()
│ │ @ Base ./client.jl:552
│ └ @ Base loading.jl:1295
│ ┌ Warning: Module AccessorsLinearAlgebraExt with build ID ffffffff-ffff-ffff-0000-0127dab8811c is missing from the cache.
│ │ This may mean AccessorsLinearAlgebraExt [6d540e18-2ad7-59a5-acf8-1761f4011e1b] does not support precompilation but is i
mported by a module that does.
│ └ @ Base loading.jl:1942
│ ┌ Error: Error during loading of extension AccessorsLinearAlgebraExt of Accessors, use `Base.retry_load_extensions()` to
retry.
│ │ exception =
│ │ 1-element ExceptionStack:
│ │ Declaring __precompile__(false) is not allowed in files that are being precompiled.
│ │ Stacktrace:
│ │ [1] _require(pkg::Base.PkgId, env::Nothing)
│ │ @ Base ./loading.jl:1946
│ │ [2] __require_prelocked(uuidkey::Base.PkgId, env::Nothing)
│ │ @ Base ./loading.jl:1806
│ │ [3] #invoke_in_world#3
│ │ @ Base ./essentials.jl:921 [inlined]
│ │ [4] invoke_in_world
│ │ @ Base ./essentials.jl:918 [inlined]
│ │ [5] _require_prelocked
│ │ @ Base ./loading.jl:1797 [inlined]
│ │ [6] _require_prelocked
│ │ @ Base ./loading.jl:1796 [inlined]
│ │ [7] run_extension_callbacks(extid::Base.ExtensionId)
│ │ @ Base ./loading.jl:1289
│ │ [8] run_extension_callbacks(pkgid::Base.PkgId)
│ │ @ Base ./loading.jl:1324
│ │ [9] run_package_callbacks(modkey::Base.PkgId)
│ │ @ Base ./loading.jl:1158
│ │ [10] __require_prelocked(uuidkey::Base.PkgId, env::String)
│ │ @ Base ./loading.jl:1813
│ │ [11] #invoke_in_world#3
│ │ @ Base ./essentials.jl:921 [inlined]
│ │ [12] invoke_in_world
│ │ @ Base ./essentials.jl:918 [inlined]
│ │ [13] _require_prelocked(uuidkey::Base.PkgId, env::String)
│ │ @ Base ./loading.jl:1797
│ │ [14] macro expansion
│ │ @ Base ./loading.jl:1784 [inlined]
│ │ [15] macro expansion
│ │ @ Base ./lock.jl:267 [inlined]
│ │ [16] __require(into::Module, mod::Symbol)
│ │ @ Base ./loading.jl:1747
│ │ [17] #invoke_in_world#3
│ │ @ Base ./essentials.jl:921 [inlined]
│ │ [18] invoke_in_world
│ │ @ Base ./essentials.jl:918 [inlined]
│ │ [19] require(into::Module, mod::Symbol)
│ │ @ Base ./loading.jl:1740
│ │ [20] include
│ │ @ Base ./Base.jl:495 [inlined]
│ │ [21] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{St
ring}, load_path::Vector{String}, concrete_deps::Vector{Pair{Base.PkgId, UInt128}}, source::String)
│ │ @ Base ./loading.jl:2216
│ │ [22] top-level scope
│ │ @ stdin:3
│ │ [23] eval
│ │ @ Core ./boot.jl:385 [inlined]
│ │ [24] include_string(mapexpr::typeof(identity), mod::Module, code::String, filename::String)
│ │ @ Base ./loading.jl:2070
│ │ [25] include_string
│ │ @ Base ./loading.jl:2080 [inlined]
│ │ [26] exec_options(opts::Base.JLOptions)
│ │ @ Base ./client.jl:316
│ │ [27] _start()
│ │ @ Base ./client.jl:552
│ └ @ Base loading.jl:1295
I am seeing this issue locally but also on CI in GitHub:
Is it a known problem? Is there something I need to do from my side?
In Accessors v0.1.5.
Breaks down when the type parameter is not "used" in the struct.
julia> using Accessors
julia> struct MyType{T}
i::Int64
end
julia> m = MyType{String}(42)
MyType{String}(42)
julia> @set m.i += 1
ERROR: MethodError: no method matching MyType(::Int64)
Stacktrace:
[1] setproperties_object(obj::MyType{String}, patch::NamedTuple{(:i,), Tuple{Int64}})
@ ConstructionBase C:\Users\nls\.julia\packages\ConstructionBase\N3vfl\src\ConstructionBase.jl:149
[2] setproperties(obj::MyType{String}, patch::NamedTuple{(:i,), Tuple{Int64}})
@ ConstructionBase C:\Users\nls\.julia\packages\ConstructionBase\N3vfl\src\ConstructionBase.jl:63
[3] set
@ C:\Users\nls\.julia\packages\Accessors\pI3fw\src\optics.jl:376 [inlined]
[4] _modify
@ C:\Users\nls\.julia\packages\Accessors\pI3fw\src\optics.jl:200 [inlined]
[5] modify(f::Accessors._UpdateOp{typeof(+), Int64}, obj::MyType{String}, optic::Accessors.PropertyLens{:i})
@ Accessors C:\Users\nls\.julia\packages\Accessors\pI3fw\src\optics.jl:180
[6] top-level scope
@ REPL[4]:1
MWE:
using Random, Accessors
struct A{T,R}
state::Float64
rng::R
value::T
A(state, rng::R, value::T) where {T,R} = new{T,R}(state, rng, value)
A{T,R}(state, rng) where {T,R} = new{T,R}(state, rng) # only difference
end
struct B{T,R}
state::Float64
rng::R
value::T
B(state, rng::R, value::T) where {T,R} = new{T,R}(state, rng, value)
end
function update_all!(s)
for x in 1:10^7
@reset s.state += x
end
return s
end
rng = Xoshiro(42);
a = A(0.0, rng, 0)
b = B(0.0, rng, 0)
update_all!(a);
update_all!(b);
@time update_all!(a);
@time update_all!(b);
This returns
julia> @time update_all!(a);
0.053849 seconds (10.00 M allocations: 305.176 MiB, 8.74% gc time)
julia> @time update_all!(b);
0.007276 seconds (1 allocation: 32 bytes)
But the only difference between A
and B
is that I have a parametric inner constructor in A
, I don't think this should affect the performance of @reset
right?
hi, I'm starting to think Accessors can be a big role in Soss, not just as a library, but also in the generated code I use for sampling. The idea would be to have a collection of optics for each model, and compose these to descend into submodels.
To make this work, I need to have type-level representation of PropertyLens
and ComposedOptic
. A quick test gives
julia> typeof(@optic _.a.b)
Base.var"#62#63"{Accessors.PropertyLens{:b},Accessors.PropertyLens{:a}}
I had thought maybe I can get ::ComposedOptic
more directly, but
julia> Accessors.ComposedOptic(Accessors.PropertyLens{:b}(),Accessors.PropertyLens{:a}())
(@optic _.b) ∘ (@optic _.a)
julia> typeof(ans)
Base.var"#62#63"{Accessors.PropertyLens{:b},Accessors.PropertyLens{:a}}
Working in terms of Base.var"#62#63"
for generated code seems very error-prone. Is there a better way to do this?
Hi,
If I understand well, the macro @reset
is the equivalent of Setfield.@set!
.
Why did you chose to remove the !
Thank you
It would often be useful, convenient, and general to create an object from values of several optics that uniquely define it, Here, I call this operation "assemble", and below are a couple of motivating examples.
These examples showcase non-trivial conversions, but even trivial ones can be potentially convenient.
For now, this is an RFC: I'm not sure what the best interface would look like from the syntax and implementation PoVs. But would be glad to hear your ideas and suggestions, maybe something similar exists in other ecosystems? I couldn't find anywhere...
Complex from polar:
@assemble ComplexF64
abs(_) = 5
angle(_) = π/3
Singleton collection from its only element:
@assemble Vector only(_) = 123
@assemble Set only(_) = 123
@assemble Tuple only(_) = 123
...
Composability:
@assemble NamedTuple
@assemble _.x::Complex abs(_) = 5, angle(_) = π/3
@assemble _.y::Vector only(_) = 123
Custom structs:
struct RelativisticVelocity
β
end
β(v::RelativisticVelocity) = ...
doppler(v::RelativisticVelocity) = ...
lorenz(v::RelativisticVelocity) = ...
@assemble RelativisticVelocity lorenz(_) = 10
struct Gaussian
A
σ
end
A(g::Gaussian) = ...
σ(g::Gaussian) = ...
fwhm(g::Gaussian) = ...
area(g::Gaussian) = ...
@assemble Gaussian A(_) = 1, fwhm(_) = 1
@assemble Gaussian A(_) = 1, area(_) = 1
Given something like:
struct A; a; end
z = A(1)
b = :a
I want to modify theb
property (which is a symbol for thea
field) ofz
using something like:
@reset Base.getproperty(z,b) = 2
But this does not work. Is there any way to do what I want?
That is, I have a function where I am passedz
andb
so the function does not "know" to write@reset z.a = 2
.
I checked "Automatically delete head branches" in https://github.com/JuliaObjects/Accessors.jl/settings so that the feature branch will be automatically deleted once the PR is merged. @jw3126 Are you OK with it?
IndexLens is pretty convenient, and works nicely with index ranges:
julia> v = [1, 2, 3]
julia> @modify(cumsum, v[2:3])
3-element Vector{Int64}:
1
2
5
But the limitation is that the result needs to have the same size:
julia> @modify(diff, v[2:3])
ERROR: DimensionMismatch: tried to assign 1 elements to 2 destinations
# want [1, 1]
julia> str = "ab cd ef"
julia> @modify(s -> "[$s]", str[4:5])
# want "ab [cd] ef"
Fixed replacement length totally makes sense by default, but sometimes resizing is also useful.
I wonder if you have any thoughts on what a reasonable interface for this may look like. Something like @optic v[FlexIndex(2:3)]
is possible, but IMO reads kinda weird.
struct A
a::Int64
end
val = Ref(A(10))
@set val[].a = 30
#=expands to -
begin
lens = @optic _[].a
Accessors.set(val, lens, 30)
end
=#
which fails with ERROR: MethodError: no method matching setindex(::Base.RefValue{A}, ::A)
. I suppose you can't define such method because that's type piracy and there's no way to setindex for a Ref without allocating a new one or updating the previous one. Even then, you won't be able to do val[] = @set val[].a = 30
, which is more natural, but rather have to do val = @set val[].a = 30
.
I don't know if this should be considered an issue since this only applies to Ref I think, and I don't see a good way around it.
If the macro expanding into the following valid code(only for Ref) doesn't cause an issue:
begin
lens = @optic _.a
Accessors.set(val[], lens, 30)
end
then perhaps there can be a customized variant @set
for Ref and an overloaded Accessors.set
.
Or optic = ($optictransform)($optic)
=> optic = METHOD($optictransform, $optic)
where METHOD specializes on Ref and an overloaded Accessors.set
so there's no need for a variant @set
.
All of the above applies to modify
too, but I am not sure.
I had an idea today for a macro and wrote it. I wonder if it might live in Accessors.jl
It's probably easiest to show what it does with an example
julia> @addto df begin
julia> df = DataFrame()
0×0 DataFrame
julia> @addto df begin
a = rand(10)
@add b = a .+ 1
c = a .- 1
@add d = c .* 2
end
10-element Array{Float64,1}:
-1.8879819894077188
-1.9232990887258832
-1.7912547756149566
-0.22723256024847016
-1.0615125043480096
-1.7319007178607428
-1.8852704274665473
-1.5832932598005565
-1.9653282149932627
-0.9196418738013863
julia> df
10×2 DataFrame
Row │ b d
│ Float64 Float64
─────┼────────────────────
1 │ 1.05601 -1.88798
2 │ 1.03835 -1.9233
3 │ 1.10437 -1.79125
4 │ 1.88638 -0.227233
5 │ 1.46924 -1.06151
6 │ 1.13405 -1.7319
7 │ 1.05736 -1.88527
8 │ 1.20835 -1.58329
9 │ 1.01734 -1.96533
10 │ 1.54018 -0.919642
The implementation is fairly trivial
is_add(x::Expr) = x.head == :macrocall && x.args[1] == Symbol("@add")
is_add(x) = false
function add_add(arg, x)
@assert arg.args[3].head === :(=)
fieldname = arg.args[3].args[1]
quote
$x.$fieldname = $fieldname
end
end
function addto_helper(x, body)
rewritten_args = []
adds = quote end
for arg in body.args
if is_add(arg)
push!(rewritten_args, arg.args[3])
push!(rewritten_args, add_add(arg, x))
else
push!(rewritten_args, arg)
end
end
result = Expr(:block, rewritten_args...)
return result
end
macro addto(x, body)
esc(addto_helper(x, body))
end
Would something like this be interesting?
While I'm able to insert using named tuples, it doesn't seem to work for structs?
julia> using Accessors
julia> struct HelloWorld
greeting::String
name::String
end
julia> x = HelloWorld("hi", "World")
HelloWorld("hi", "World")
julia> lens = @optic _.response
(@optic _.response)
julia> insert(x, lens, "goodbye")
ERROR: MethodError: no method matching insert(::HelloWorld, ::PropertyLens{:response}, ::String)
Closest candidates are:
insert(::Any, ::ComposedFunction, ::Any) at ~/.julia/packages/Accessors/KHKiv/src/optics.jl:223
insert(::NamedTuple, ::PropertyLens{field}, ::Any) where field at ~/.julia/packages/Accessors/KHKiv/src/optics.jl:401
insert(::Any, ::typeof(last), ::Any) at ~/.julia/packages/Accessors/KHKiv/src/functionlenses.jl:8
...
Stacktrace:
[1] top-level scope
@jw3126 I think this is working well now. What do you think of moving Leaves
into Accessors? It's very fast, and seems it could be useful for others.
Most of the code is here. Biggest concern I could see is that it depends on GeneralizedGenerated. There may be a way to drop that dependency, but it would take some fiddling.
It's no trouble to me either way, and I won't be offended if you don't think it's a good fit. Just seems more natural to me to have it in Accessors.
Here is how I think we should proceed:
using Accessors, StructArrays
julia> @set StructArray((;a=[1,2], b=[10,20])).c = [100,200]
ERROR: ArgumentError: Failed to assign properties (:c,) to object with properties (:a, :b).
It would be nice to use @set
on StructArray
.
Hi, I just put together this little proof of concept using Setfield:
https://github.com/cscherrer/NestedTuples.jl
I wonder if it could make more sense to move it to using Accessors. Also, @rafaqz , I just saw your post, looks like there might be some overlap in our needs. Pinging you here in case that's right :)
The problem I'm working on is a good way to represent samples in a Monte Carlo simulation. In Soss, each sample is a named tuple. And I need to manage these programmatically, so I need a clean interface.
I thought StructArrays might already do it, but from what I've seen so far, StructArrays don't have much support for nested structure. So I started down this road today thinking I might get to something more tailored for the problem.
So I guess my questions are
I've been really impressed with the data manipulation work I've seen from you (@jw3126 and @tkf ), so I hope anything I contribute can fit cleanly into that :)
This package is great to see. Just wondering if you have a list of differences and changes from Setfield.jl - current or intended?
Edit: Looks like Recursive
can do pretty flexible descent/tree walking wIth Filter
! That's a lot of what I need to replace Flatten.jl.
I knew I saw it somewhere before but forgot, and now found a discussion by @jw3126 in the Setfield repo – jw3126/Setfield.jl#137 :)
I added this feature to AccessorsExtra a few month ago, turns out to be useful sometimes.
Examples:
julia> old = (a=(1,), b=(2, 3))
julia> new = (a=(10,), b=(2, 0.3))
julia> modify(/, old, (@o _[∗][∗]), new)
(a = (0.1,), b = (1.0, 10.0))
julia> acc = (a=10, b=[(d=3, e=40)], c="x")
julia> newval = (a=1, b=[(d=30, e=4)], c="y")
julia> acc = modify(max, acc, RecursiveOfType(Number), newval)
(a = 10, b = [(d = 30, e = 40)], c="x")
Implementation is very simple in https://gitlab.com/aplavin/AccessorsExtra.jl/-/blob/master/src/modifymany.jl. Most of the lines are to handle Elements and Properties.
First, I wonder if you have any suggestions on the interface. Is that useful for what you had in mind?
Second, if this is considered generally within the Accessors scope, we can add it here. Wonder if this is widely useful (I think so, but not without promoting these features...), and worry a bit about "feature creep" of such a foundational package. In comparison, AccessorsExtra contains less clear-cut stuff anyways, so I'm much less worried there :)
Thanks for the package. Very useful. I was wondering if there was a functional implementation of the @set
macro. I mean,
something that allows me to do stuff like:
struct MyData
name::String
end
item = MyData("Ok")
setfield(item, :name, "Update")
This would be the same as `@set item.name = "Update", but now I could easily pass fields programmatically.
Anyways, I wrote a little macro to do this for me. Perhaps (if there isn't something like this), it could be added to the package.
function setfield(item, field::Symbol, value)
ex = quote
@set item.$field = $value
end
return eval(ex)
end
Cheers!
(Same as jw3126/Setfield.jl#179)
IR: Test Failed at /home/pkgeval/.julia/packages/Accessors/81CPQ/test/perf.jl:92
Expression: uniquecounts(heads_lens) == uniquecounts(heads_hand)
Evaluated: Dict(:call => 9, :new => 1) == Dict(:call => 3, :new => 1)
Stacktrace:
[1] macro expansion
@ /opt/julia/share/julia/stdlib/v1.11/Test/src/Test.jl:679 [inlined]
[2] test_ir_lens_vs_hand(info_lens::Core.CodeInfo, info_hand::Core.CodeInfo)
@ Main.Perf ~/.julia/packages/Accessors/81CPQ/test/perf.jl:92
[3] macro expansion
@ ~/.julia/packages/Accessors/81CPQ/test/perf.jl:139 [inlined]
[4] macro expansion
@ /opt/julia/share/julia/stdlib/v1.11/Test/src/Test.jl:1700 [inlined]
[5] macro expansion
@ ~/.julia/packages/Accessors/81CPQ/test/perf.jl:137 [inlined]
[6] macro expansion
@ /opt/julia/share/julia/stdlib/v1.11/Test/src/Test.jl:1789 [inlined]
[7] top-level scope
@ ~/.julia/packages/Accessors/81CPQ/test/perf.jl:121
If one has a mutable array of immutable objects, is it possible to use Accessors.jl to update just one object in the array without copying the whole array?
julia> struct MyT
x::Int
end
julia> v = [MyT(1), MyT(2)]
2-element Vector{MyT}:
MyT(1)
MyT(2)
julia> @set v[1].x = 5
2-element Vector{MyT}:
MyT(5)
MyT(2)
julia> v
2-element Vector{MyT}:
MyT(1)
MyT(2)
Looks like @set
is returning a whole copy of v
, not just updating v[1]
. Is that right? Is there a way around this?
Sometimes I'd like to check beforehand whether an optic is truly applicable to a type; especially when dealing with deeply-nested optics. It would be quite useful if there existed a hasproperty()
analogue for optics on a type. I've made a simple version for PropertyLens
and ComposedFunction
, but I'm not sure about the rest of the optic types. I'm opening this issue so that if someone else is interested, they can carry this to completion.
function Base.hasproperty(x, o::PropertyLens)
return typeof(o).parameters[1] ∈ propertynames(x)
end
function Base.hasproperty(x, o::ComposedFunction)
return hasproperty(x, o.outer) &&
hasproperty(o.outer(x), o.inner)
end
This allows tests such as the following:
using Accessors
struct T
a
b
end
x = T(T(1,2), 3)
@show hasproperty(x, @optic _.a)
@show hasproperty(x, @optic _.b)
@show hasproperty(x, @optic _.c)
@show hasproperty(x, @optic _.a.a)
@show hasproperty(x, @optic _.a.a.a)
@show hasproperty(x, @optic _.b.a)
I just wanted to add one more comment to discussion #133 which was apparently closed because the authors dont want to receive any criticism:
They were so concerned with whether it's possible to make the compiler do extra unnecessary work, they completely overlooked the question of whether it is wise to make the compiler do more work than necessary.
A wise man once said, make things as simple as possible, but not simpler.
A fool's errand is when somebody causes more work than necessary. You are sending the compiler on a fool's errand.
Just because you can make the compiler do extra unnecessary work, doesn't mean it is wise to do so. In fact, it seems quite foolish to me.
I'm not interested in insulting people, continue acting a fool if you wish, I'm just telling you how it looks like you are lazy programmers.
Being a lazy programmer is fine, but it is how I would formally classify this style of programming, as such I would avoid packages depending on this.
Julia programmers can fall into a trap like this, I am merely trying to point out that this is a trap a competent programmer could fall into and become classified as a lazy programmer as a result.
The base Julia language is quite well designed with immutable structs and constructors.
This great design of Julia is diminished by the inappropriate use of macros where they are not necessary at all.
The advantages of Julia get diminished, the more unnecessary things the compiler does, you are unnecessarily increasing the work the compiler has to do.
It's not a good trade off. All you have to do is spend a bit of extra effort writing code, and then you dont increase the workload of the compiler on every user's computer. You could just write the code correctly once. Instead, the compiler has to spend effort on every user's computer to optimize lazy programming.
Potentially, it could be a significant overhead to the compile times, since immutable object constructors are very fundamental and common.
KISS "Keep it simple stupid" is a great philosophy. This is not keeping it simple. Base Julia is nice and simple with handling immutable objects and their constructors. This makes everything more complicated for the compiler, all because you were too lazy to use the base language, with simple constructors.
I have given plenty of suggestions for action here. The action I am suggesting is to not do lazy programming which unnecessarily increases the overhead of compiling code.
It wasnt my intention to open another issue, but to make this final comment, that's what's necessary.
Feel free to ignore me if you are comfortable being classed as a lazy programmer. As I said, there's nothing wrong with being lazy, but it's a lower bar/standard. It's not good enough for my standards. Of course you dont have to care about what my standards are, since this is an open source project I am merely sharing my view.
julia> @optic _."abc"
ERROR: TypeError: in Type, in parameter, expected Type, got a value of type String
This is because PropertyLens is defined to hold the property name as a type parameter, and Strings cannot be type params.
Not sure what we can do, but maybe someone has ideas on how to fix it?
Hi! Wanted to share that I've registered AccessorsExtra.jl
focusing on integrations of Accessors with other packages: StructArrays, AxisKeys, IntervalSets, and more. It also defines a couple of more opinionated lenses.
Docs & examples (non-exhaustive) | Source code (with a healthy dose of 🏴☠️)
I enjoy using Setfield.jl
and recently heard about Accessors.jl
as its successor.
Would like to propose a delete
function that looks generally very useful:
delete( (a=1, b=2, c=3), @lens(_.a) ) == (b=2, c=3)
delete( (1,2,3), @lens(last(_)) ) == (1, 2)
delete( "path/to/file, @lens(basename(_)) ) == "path/to/"
...
Relevant prior work: NamedTupleTools.delete((a=1, b=2, c=3), :a) == (b=2, c=3)
.
I would like to be able to set multiple fields in a single statement. Maybe something like
@set f.a = 10 f.b = 20
if we had an object f
with fields a
and b
.
Right now the only way I know how to do that properly is
@set (@set f.a = 10).b = 20
which is a little ugly looking. Is there any other way to do this using this package? If not could this be a feature request?
Some existing optics, such as Elements()
, If()
and Recursive()
, can only be modify
ed - one cannot retrieve the values specified by them. I understand that it's not obvious how to implement optic(obj)
for them and even what type it should return. However, from time to time I try to reach for this functionality: either to specifically extract the corresponding values, or just to see what values modify
would be called with.
Do you think it's possible to design value extraction for those optics in a consistent manner?
Suppose I have a structure obj = (flux=10., size=1., coords=(NaN, 5.))
and want to modify (get/set/optimize/...) its flux and the first coordinate.
Would be nice to have something like
julia> o = concatenate(@optic(_.flux), @optic(first(_.coords)))
ConcatLens((@optic(_.flux), @optic(first(_.coords))))
julia> modify(x -> isnan(x) ? zero(x) : x, obj, o)
(flux=10., size=1., coords=(0., 5.))
julia> getall(obj, o)
(10., NaN)
julia> setall(obj, o, (2., 3.))
(flux=2., size=1., coords=(3., 5.))
Currently, it's much less clean and composable - eg modify
:
julia> func = x -> isnan(x) ? zero(x) : x
julia> obj = modify(func, obj, @optic(_.flux))
julia> obj = modify(func, obj, @optic(first(_.coords)))
I'm not sure about the best name, syntax, and semantics for this operation, though. Comments and suggestions are welcome!
@jw3126 @tkf @rafaqz
This issue is used to trigger TagBot; feel free to unsubscribe.
If you haven't already, you should update your TagBot.yml
to include issue comment triggers.
Please see this post on Discourse for instructions and more details.
If you'd like for me to do this for you, comment TagBot fix
on this issue.
I'll open a PR within a few hours, please be patient!
Assuming JuliaLang/julia#46453 gets merged at some point, Base will export functions insert
and delete
. This raises the question of what to do with Accessors.insert
and delete
? At least three possible alternatives:
Accessors.delete(...)
is pretty verbose.delete(_, ::ComposedFunction)
. Hard to imagine something other than optics library defining this method anyway :)odelete
?I wonder if I'm missing others or their +/-.
Hello,
If I understand correctly, we may expect this to work out-of-the-box:
julia> using Accessors, StaticArrays
julia> s = SVector{4}(1:4) # immutable fixed size vector
4-element SVector{4, Int64} with indices SOneTo(4):
1
2
3
4
julia> @set s[2] += 100 # single indexing works
4-element SVector{4, Int64} with indices SOneTo(4):
1
102
3
4
julia> @set s[2:3] .+= 100 # broadcasted functions are not recognised
ERROR: UndefVarError: .+ not defined
Stacktrace:
[1] top-level scope
@ REPL[257]:1
julia> @set s[2:3] += [100, 100] # slicing fails ungracefully
ERROR: StackOverflowError:
Regarding the first error, the macro expands to something containing Accessors.:.+
. We probably need to esc
the operator symbol .+
so it gets evaluated to Base.Broadcast.BroadcastFunction(+)
, but I’m not sure if it’s that simple.
The second error seems like it needs more urgent attention. If s = [1, 2, 3]
is a normal vector, @set s[2:3] += [100, 100]
works fine, so it seems like this should be supported for static vectors.
Setting several fields at once would reduce the number of times the immutable struct is copied. For example,
nt = (a=1, b=2)
@reset nt.a=2, nt.b=3
instead of
nt = (a=1, b=2)
@reset nt.a=2
@reset nt.b=3
This is bad programming. By using this you're going to create multiple objects as you update it one property at a time, instead of just creating a new object once by updating all values at once. This kind of lazy thinking is a terrible idea.
Is this error expected?
julia> (@optic _[2:lastindex(_)])(1:10)
2:10
julia> (@views @optic _[2:lastindex(_)])(1:10)
ERROR: LoadError: Only a single function argument can be the optic target
julia> @macroexpand1 (@views @optic _[2:lastindex(_)])(1:10)
:((#= REPL[58]:1 =# @optic((Base.maybeview)(_, 2:lastindex(_))))(1:10))
[7d9f7c33] Accessors v0.1.32
It would be very useful to have a function that can determine if an object obeys the lens API. Ideally with traits. Eg something like
julia> is_optic(@optic _.a)
Val{true}()
(After discussion, I am of course happy to make a PR).
Hi,
One thing that can help with compatibility elsewhere is to hint your lenses and so-on are functions, by directly subtyping Function
.
For example the code at https://github.com/JuliaObjects/Accessors.jl/blob/master/src/optics.jl#L345 could become:
struct PropertyLens{fieldname} <: Function
end
This came up in SplitApplyCombine, which (unfortunately) is currently using Base.Callable
in a few cases (although I wish the API were factored so it were obvious which terms must be functions rather than collections), here.
CC @aplavin
I wonder, does this line in README from 2 years ago still holds true?
Line 12 in 2c7fbd1
when loading FastGaussQuadrature
I get the following warning:
┌ Warning: Package Accessors does not have StaticArrays in its dependencies:
│ - If you have Accessors checked out for development and have
│ added StaticArrays as a dependency but haven't updated your primary
│ environment's manifest file, try `Pkg.resolve()`.
│ - Otherwise you may need to report an issue with Accessors
└ Loading StaticArrays into Accessors from project dependency, future warnings for Accessors are suppressed.
this is in my Project.toml
:
[6e4b80f9] BenchmarkTools v1.1.1
[336ed68f] CSV v0.8.5
[8be319e6] Chain v0.4.7
[b0b7db55] ComponentArrays v0.11.1
[a93c6f00] DataFrames v1.2.1
[1313f7d8] DataFramesMeta v0.8.0
[31c24e10] Distributions v0.25.11
[cc61a311] FLoops v0.1.10
[442a2c76] FastGaussQuadrature v0.4.7
[5789e2e9] FileIO v1.10.1
[41a02a25] Folds v0.2.5
[a75be94c] GalacticOptim v2.0.3
[337daf1e] NLSolvers v0.1.0
[76087f3c] NLopt v0.6.3
[2774e3e8] NLsolve v4.5.1
[8913a72c] NonlinearSolve v0.3.8
[429524aa] Optim v1.4.0
[91a5bcdd] Plots v1.19.4
[f2b01f46] Roots v1.0.11
[3a884ed6] UnPack v1.0.2
[112f6efa] VegaLite v2.6.0
let me know if you need more info.
Are there any guarantees on the traversal order of Recursive
?
I'm not sure anyone would ever hit this ambiguity in practice, but just FYI, Aqua.jl alerted me to this:
1 ambiguities found
Ambiguity #1
show(io::IO, optic::ComposedFunction{<:Any, <:Union{Accessors.IndexLens, Accessors.PropertyLens}}) @ Accessors ~/.julia/packages/Accessors/g8gNQ/src/sugar.jl:440
show(io::IO, c::ComposedFunction{typeof(!)}) @ Base operators.jl:1053
Possible fix, define
show(::IO, ::ComposedFunction{typeof(!), I} where I<:Union{Accessors.IndexLens, Accessors.PropertyLens})
It would be nice to be able to do
n = (a = 1, b = 2, c = 3)
n2 = @set n begin
a = 4
b = 100
end
julia> a = @set a.octime = 5
ERROR: MethodError: no method matching Implication(::StaticArrays.SVector{2, Word}, ::Int64)
Stacktrace:
[1] setproperties_object(obj::Implication{Forward}, patch::NamedTuple{(:octime,), Tuple{Int64}})
@ ConstructionBase mypath\.julia\packages\ConstructionBase\N3vfl\src\ConstructionBase.jl:149
my struct definition:
struct Implication{O} <: Term
comps::SVector{N, T} where {N, T <: Term}
octime::UInt
end
ConstructionBase.jl
uses a function called constructorof
, when it try to find obj
's constructor, it use nameof
, thus it droped my parametric type.
julia> typeof(a)
Implication{Forward}
julia> nameof(typeof(a))
:Implication
We are trying to update Turing.jl to using Accessors.jl in sync with BangBang (TuringLang/AbstractPPL.jl#91)
I noticed that ==
for IndexLens
is not defined, (c.f. Setfield's definition).
Are there reasons this is removed (or just not ported)?
Setfield.jl allowed interpolation with $
, but that of course has some corner cases so I understand why it is not allowed in @optic
. However, it would be nice to be able to build lenses with functions, eg for a
(a = 1:2, b = 1:3)
build the equivalent of [@optic(_.a[1]), @optic(_.a[2]), @optic(_.b[1]), @optic(_.b[2]), @optic(_.b[3])]
with a loop or similar, eg with a syntax like Property(:a) ∘ Index(1)
etc.
Just wondering if this is a bug or a feature. Using the julia docs example:
julia> struct SummedArray{T<:Number,S<:Number}
data::Vector{T}
sum::S
function SummedArray(a::Vector{T}) where T
S = widen(T)
new{T,S}(a, sum(S, a))
end
end
julia> sa = SummedArray([1,2,3])
SummedArray{Int64, Int128}([1, 2, 3], 6)
julia> @set sa.sum = 5
ERROR: MethodError: no method matching SummedArray(::Vector{Int64}, ::Int64)
Closest candidates are:
SummedArray(::Vector{T}) where T at REPL[14]:4
Stacktrace:
[1] setproperties_object(obj::SummedArray{Int64, Int128}, patch::NamedTuple{(:sum,), Tuple{Int64}})
@ ConstructionBase C:\Users\ilyao\.julia\packages\ConstructionBase\N3vfl\src\ConstructionBase.jl:149
[2] setproperties(obj::SummedArray{Int64, Int128}, patch::NamedTuple{(:sum,), Tuple{Int64}})
@ ConstructionBase C:\Users\ilyao\.julia\packages\ConstructionBase\N3vfl\src\ConstructionBase.jl:63
[3] set(obj::SummedArray{Int64, Int128}, l::Accessors.PropertyLens{:sum}, val::Int64)
@ Accessors C:\Users\ilyao\.julia\packages\Accessors\KLYEx\src\optics.jl:376
[4] top-level scope
@ REPL[16]:1
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.