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

Should setindex(x::AbstractArray, v, i) use mutate-or-widen strategy? #16

Closed
tkf opened this issue Jul 31, 2019 · 3 comments
Closed

Should setindex(x::AbstractArray, v, i) use mutate-or-widen strategy? #16

tkf opened this issue Jul 31, 2019 · 3 comments

Comments

@tkf
Copy link
Member

tkf commented Jul 31, 2019

Current implementation of setindex(x::AbstractArray, v, i) does not support widening of the element type:

https://github.com/JuliaDiffEq/ArrayInterface.jl/blob/c8513cbc0b9dc24e6674206255838abec553b854/src/ArrayInterface.jl#L22-L26

I think it would be useful to support eltype-widening so that setindex([0], 1.2, 1) works. I implemented this in BangBang.jl internally (BangBang.jl provides a uniform API for mutable and immutable containers). It is useful to have type-changing setter because you can use it to, e.g., implement map based on mutate-or-widen strategy.

Actual code is pretty simple (from https://github.com/tkf/BangBang.jl/blob/94eab8d728194fac0fa41c840ca398600a50f903/src/NoBang/base.jl#L99-L107):

function _setindex(xs::AbstractArray, v, I...)
    T = promote_type(eltype(xs), typeof(v))
    ys = similar(xs, T)
    if eltype(xs) !== Union{}
        copy!(ys, xs)
    end
    ys[I...] = v
    return ys
end

One disadvantage of this approach is that it fails when there is an undef element. That's why Union{} was special-cased above. To support more general cases, I think we need something like copy_if_defined! (or maybe Base.copy! should do it automatically?).

@ChrisRackauckas
Copy link
Member

I am not sure we want to change the element type? I would assume it would have array-like semantics.

@tkf
Copy link
Member Author

tkf commented Jul 31, 2019

But what is an array-like semantics? I think we still can define semantics for corner cases?

The type-widening API is more-or-less [1] a strict superset of the non-type-changing API because the type-widening API turns error cases in non-type-changing API to valid cases. The type-widening immutable API is a useful building block for the mutate-or-widen strategy. Sometimes you need it for writing generic algorithm without relying on the inference API.

[1] There is a change in how setindex([0], 1.0, 1) works. In non-type-changing API it returns [1] while in type-widening API it returns [1.0].

@ChrisRackauckas
Copy link
Member

I guess yes it makes sense on static arrays so it probably makes sense here.

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