From ac5de77fe0452f9622d3ffbd6f5e767f54dd0663 Mon Sep 17 00:00:00 2001 From: Xianda Sun Date: Tue, 9 Apr 2024 06:28:02 +0100 Subject: [PATCH 1/2] =?UTF-8?q?add=20`=E2=88=98`=20and=20`=E2=A8=9F`=20fun?= =?UTF-8?q?ction=20between=20varname=20and=20optic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/varname.jl | 14 +++++++++++--- test/varname.jl | 7 ++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/varname.jl b/src/varname.jl index 83d58ce..cb55623 100644 --- a/src/varname.jl +++ b/src/varname.jl @@ -1,5 +1,6 @@ using Accessors using Accessors: ComposedOptic, PropertyLens, IndexLens, DynamicIndexLens +import Accessors: opcompose, ⨟ const ALLOWED_OPTICS = Union{typeof(identity),PropertyLens,IndexLens,ComposedOptic} @@ -148,6 +149,13 @@ function Accessors.set(obj, vn::VarName{sym}, value) where {sym} return Accessors.set(obj, PropertyLens{sym}() ⨟ getoptic(vn), value) end +# Allow compositions with optic. +function Base.:∘(optic::ALLOWED_OPTICS, vn::VarName{sym,<:ALLOWED_OPTICS}) where {sym} + return VarName{sym}(optic ∘ getoptic(vn)) +end +function Accessors.opcompose(vn::VarName{sym,<:ALLOWED_OPTICS}, optic::ALLOWED_OPTICS) where {sym} + return VarName{sym}(getoptic(vn) ⨟ optic) +end Base.hash(vn::VarName, h::UInt) = hash((getsym(vn), getoptic(vn)), h) function Base.:(==)(x::VarName, y::VarName) @@ -631,8 +639,8 @@ function varname(expr::Expr, concretize=Accessors.need_dynamic_optic(expr)) if concretize return :( $(AbstractPPL.VarName){$sym}( - $(AbstractPPL.concretize)($optics, $sym_escaped) - ) + $(AbstractPPL.concretize)($optics, $sym_escaped) + ) ) elseif Accessors.need_dynamic_optic(expr) error("Variable name `$(expr)` is dynamic and requires concretization!") @@ -687,7 +695,7 @@ function _parse_obj_optics(ex) else throw(ArgumentError( string("Error while parsing :($ex). Second argument to `getproperty` can only be", - "a `Symbol` or `String` literal, received `$property` instead.") + "a `Symbol` or `String` literal, received `$property` instead.") )) end else diff --git a/test/varname.jl b/test/varname.jl index 6488c61..a26e346 100644 --- a/test/varname.jl +++ b/test/varname.jl @@ -5,7 +5,7 @@ using OffsetArrays using AbstractPPL: ⊑, ⊒, ⋢, ⋣, ≍ using AbstractPPL: Accessors -using AbstractPPL.Accessors: IndexLens, PropertyLens +using AbstractPPL.Accessors: IndexLens, PropertyLens, ⨟ macro test_strict_subsumption(x, y) quote @@ -50,6 +50,11 @@ end @test test_equal(@varname(x.a[1:end, end][:], true), @varname(x.a[1:3,2][1:3])) end + @testset "compose and opcompose" begin + @test IndexLens(1) ∘ @varname(x.a) == @varname(x.a[1]) + @test @varname(x.a) ⨟ IndexLens(1) == @varname(x.a[1]) + end + @testset "get & set" begin x = (a = [1.0 2.0; 3.0 4.0; 5.0 6.0], b = 1.0); @test get(x, @varname(a[1, 2])) == 2.0 From 43dc512ddfebe35c9d675145299e8ee629d0bd9d Mon Sep 17 00:00:00 2001 From: Xianda Sun <5433119+sunxd3@users.noreply.github.com> Date: Tue, 9 Apr 2024 09:04:32 +0100 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: David Widmann --- src/varname.jl | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/varname.jl b/src/varname.jl index cb55623..0f470a1 100644 --- a/src/varname.jl +++ b/src/varname.jl @@ -1,6 +1,5 @@ using Accessors using Accessors: ComposedOptic, PropertyLens, IndexLens, DynamicIndexLens -import Accessors: opcompose, ⨟ const ALLOWED_OPTICS = Union{typeof(identity),PropertyLens,IndexLens,ComposedOptic} @@ -153,9 +152,6 @@ end function Base.:∘(optic::ALLOWED_OPTICS, vn::VarName{sym,<:ALLOWED_OPTICS}) where {sym} return VarName{sym}(optic ∘ getoptic(vn)) end -function Accessors.opcompose(vn::VarName{sym,<:ALLOWED_OPTICS}, optic::ALLOWED_OPTICS) where {sym} - return VarName{sym}(getoptic(vn) ⨟ optic) -end Base.hash(vn::VarName, h::UInt) = hash((getsym(vn), getoptic(vn)), h) function Base.:(==)(x::VarName, y::VarName)