unthunk `getindex` and `iterate` on `Composite` objects
Fixes #233
Currently something like:
julia> r = Composite{Tuple{Float64,}}(a=(@thunk 2.0^2), b=(@thunk 2.0^3))
julia> collect(r)
MethodError: Cannot `convert` an object of type
Float64 to an object of type
Thunk
Closest candidates are:
convert(::Type{T}, !Matched::T) where T at essentials.jl:171
Thunk(::F) where F at /Users/gaurav/.julia/dev/ChainRulesCore/src/differentials/thunks.jl:95
Stacktrace:
[1] setindex!(::Array{Thunk,1}, ::Float64, ::Int64) at ./array.jl:826
[2] copyto!(::Array{Thunk,1}, ::Composite{Tuple{Float64},NamedTuple{(:a, :b),Tuple{Thunk{var"#3#5"},Thunk{var"#4#6"}}}}) at ./abstractarray.jl:724
[3] _collect(::UnitRange{Int64}, ::Composite{Tuple{Float64},NamedTuple{(:a, :b),Tuple{Thunk{var"#3#5"},Thunk{var"#4#6"}}}}, ::Base.HasEltype, ::Base.HasLength) at ./array.jl:609
[4] collect(::Composite{Tuple{Float64},NamedTuple{(:a, :b),Tuple{Thunk{var"#3#5"},Thunk{var"#4#6"}}}}) at ./array.jl:603
[5] top-level scope at In[12]:1
raises error. Would that need re-defining Base.collect as well?
Though as expected collect(Float64, r) works just fine:
julia> collect(Float64, r)
2-element Array{Float64,1}:
4.0
8.0
I'll add the test case for it.
Hi @nickrobinson251 can you please review this :)
julia> r = Composite{Tuple{Float64,}}(a=(@thunk 2.0^2), b=(@thunk 2.0^3)) julia> collect(r) MethodError: Cannot `convert` an object of type Float64 to an object of type Thunk
I think this is because we are now defining the eltype wrong.
Rather than special casing collect, we might need to special case HasEltype so that if the composite backing type has thunks, it says that it is EltypeUnknown.
This is more involved than i thought.
We should probably also have tests of something that uses iterate more directly than collect. Maybe a little function for a for loop?
What about something like:
julia> a = Composite{Tuple{Thunk}}((@thunk 2.0^3), (@thunk 2.0^2))
Is it supposed to give unthunked values on iteration?
What about something like:
julia> a = Composite{Tuple{Thunk}}((@thunk 2.0^3), (@thunk 2.0^2))Is it supposed to give unthunked values on iteration?
Yes. (Assuming you mean Tuple{Thunk, Thunk} since two arguments)
Though Tuple{Thunk, Thunk} is a super weird primal type.
I'm note sure if it should even occur during second order differentiation.
But since a Thunk at the end of the day actually represents the value it returns on being unthunked, and should be operated on as such, it is always correct and desirable to unthunk it before manipulating it
Rather than special casing collect, we might need to special case HasEltype so that if the composite backing type has thunks, it says that it is EltypeUnknown
Did you mean to say, special casing Base.IteratorEltype? Even Base.HasEltype don't accept any arguments to it.
Did you mean to say, special casing Base.IteratorEltype?
Yes