Skip to content
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

typeof(::ComposedOptic) #16

Closed
cscherrer opened this issue Dec 13, 2020 · 6 comments
Closed

typeof(::ComposedOptic) #16

cscherrer opened this issue Dec 13, 2020 · 6 comments

Comments

@cscherrer
Copy link

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?

@cscherrer
Copy link
Author

Just found this:
JuliaLang/julia#37517

If I'm reading this right, it seems that in 1.6 will return a ComposedFunction instead of an anonymous one. So at that point all of this will work. But I'm on 1.5, which is why I'm seeing strange results. Does that sound right?

@jw3126
Copy link
Member

jw3126 commented Dec 13, 2020

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.

Sounds really exciting I need to check this out.

If I'm reading this right, it seems that in 1.6 ∘ will return a ComposedFunction instead of an anonymous one. So at that point all of this will work. But I'm on 1.5, which is why I'm seeing strange results. Does that sound right?

I think you can just dispatch on Accessors.ComposedOptic. Accessors.jl does this also internally. On 1.5 it is an alias for the scary looking var"...". On 1.6 it is an alias for Base.ComposedFunction.
Other than the bad printing, I did not encounter any problems on 1.5.

@cscherrer
Copy link
Author

I need to check this out

It's mostly here, specifically in

function sourceSample() 
    function(m::Model)
        
        _m = canonical(m)
        proc(_m, st::Assign)  = :($(st.x) = $(st.rhs))
        proc(_m, st::Sample)  = :($(st.x) = value(sample(_rng, $(st.rhs))))
        proc(_m, st::Return)  = :(_value = $(st.rhs))
        proc(_m, st::LineNumber) = nothing

        vals = map(x -> Expr(:(=), x,x),parameters(_m)) 

        wrap(kernel) = @q begin
            _rng -> begin
                _value = nothing
                $kernel
                _trace = $(Expr(:tuple, vals...))
                return (value = _value, trace = _trace)
            end
        end

        buildSource(_m, proc, wrap) |> flatten
    end
end

The trace property will contain values for latent variables. But one of those might itself be the output of a model, in which case we need to keep track of its latent variables as well. So I'm thinking I can pass an optic to represent the current scope.

I think you can just dispatch on Accessors.ComposedOptic. Accessors.jl does this also internally. On 1.5 it is an alias for the scary looking var"...". On 1.6 it is an alias for Base.ComposedFunction.
Other than the bad printing, I did not encounter any problems on 1.5.

Great! I'll try this, thanks :)

@cscherrer
Copy link
Author

cscherrer commented Dec 13, 2020

Confirmed!!

julia> using Accessors

julia> outeroptic(::Accessors.ComposedOptic{A,B}) where {A,B} = A
outeroptic (generic function with 1 method)

julia> o = @optic _.a.b
(@optic _.b)  (@optic _.a)

julia> outeroptic(o)
Accessors.PropertyLens{:b}

@cscherrer
Copy link
Author

Just opened cscherrer/Soss.jl#227

I think this is resolved on the Accessors side, thanks @jw3126

@cscherrer
Copy link
Author

Oh, last post here wasn't clear. I mean I'll close the issue, since it's currently more an issue on the Soss side. @jw3126 if you're interested I'd welcome any feedback there :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants