Using different types of immutable indexable types can be useful, but this is very difficult (if not impossible?) to handle with generic code right now. For example, an SArray
from StaticVectors.jl is <:AbstractArray
. Many times you may want to have separate code paths for abstract arrays, like:
if typeof(a) <: AbstractArray
a .= b .+ c
else
a = b+c
end
However, there is currently no way to distinguish between immutable and mutable collections. Note that this exact case would actually be solved by
https://github.com/JuliaLang/julia/issues/19992
but that is just a bandaid for a single case. Another case for example would be choosing between fill!
ing a vector or creating a new one matching the immutable array type with zeros
. I'm not sure Julia can always automate this choice in every case, and so the ability to distinguish between these classes of types is crucial. Without a Base abstract type, this requires a dependency for each array type you want to support like this. A simple AbstractImmtableArray{T,N} <: AbstractArray{T,N}
could handle this.
Why not use a Trait?
A trait would be fine.
It would need to be some kind of Base trait added to the array interface, since the current options don't work very well. Note that a simple trait on isimmutable
wouldn't actually work in this case because a StaticArray
is counted as mutable but cannot setindex!
. A trait can be built using something like SimpleTraits and generated functions, where the generated functions try/catch
some setindex!
call and look for errors. You'd need to make sure it's calling setindex!
on something reasonable or it can set the wrong trait, and this is still kind of a hacky solution.
Wouldn't something like
struct MutableArray end
struct ImmutableArray end
MutableStyle(::AbstractArray) = MutableArray()
MutableStyle(::StaticArray) = ImmutableArray()
in StaticArrays be enough?
A trait can be built using something like ... generated functions
No, it can't. The the generated function will either lie to you or generate garbage. It operates in the same computational domain as regular functions, so there's nothing it can do that regular functions can't also do.
Yes @KristofferC, that would be exactly enough if MutableStyle
existed in Base. It's not enough if it's defined in StaticArrays, because then you'd have to expect every package who wants to handle this to have a dependency on StaticArrays, which is unnecessary. That's why I'm asking for it to be in Base.
I just want to make sure I understand where this fits at a higher API level. As I see it, given array A
, you can request:
similar
, issue https://github.com/JuliaLang/julia/issues/18161 for a more orthogonal API.sprand
and friends, issue https://github.com/JuliaLang/julia/issues/11557 to unify on rand
.A
. This is rand!
and .=
, issue https://github.com/JuliaLang/julia/issues/19992 to decide if .=
belongs here.A
. Is this this issue?Time to start allowing ‽
as an identifier for rand‽()
?
I proposed !!
as an easy to type suffix for this stuff, allowing but not requiring the reuse of storage from A
. It parses well already and indicates (rightly) that something special is going on.
i strongly support having some more traits for arrays - specifically for mutability and another to replace DenseArray
I agree working out a higher level API here would be wonderful, but it seems significantly harder...
I agree working out a higher level API here would be wonderful, but it seems significantly harder...
Yeah, that's what I was discussing with @mbauman in a Gitter chat. I would like a high level API here as well, but I don't know if it could hit every point. If there's at least the traits available, I can special case as I see fit, which would be special casing in areas Base has not made this easy. The goal of a high level API would be to make this not necessary, but I am not sure you can cover every single aspect.
Most helpful comment
Yeah, that's what I was discussing with @mbauman in a Gitter chat. I would like a high level API here as well, but I don't know if it could hit every point. If there's at least the traits available, I can special case as I see fit, which would be special casing in areas Base has not made this easy. The goal of a high level API would be to make this not necessary, but I am not sure you can cover every single aspect.