I’m trying to write a function that will accept an argument that implements the AbstractArray interface. I’m finding that I need to write one implementation for mutable AbstractArrays and another for immutable AbstractArrays. I see the isimmutable function, but after experimenting, it seems that it doesn’t get optimized away at compile time as I hoped it would.
What is the right way to have separate implementations for mutable and immutable objects?
mutable object can be read only array and immutable object can be mutable arrays so you must not use the mutability of the object to decide if the array is mutable. You should not define an API that conditionally mutate an input array so you shouldn’t need to do this.
In Julia, it is good practice to append an exclamation point to any function that mutates its arguments. This means that your use case is usually solved by writing two functions foo and foo!. Then your user can decide if they want to use the mutating or non-mutating version of your function.
For now just assume that they will be <:SArray if they are immutable arrays.
No. How else do you write a fast algorithm on arrays that works with both StaticArrays and regular arrays? You might just be using the mutation internally, but it still matters. If you don’t care about performance, sure simply always do the mutating form. Or you can specialize only on Array, but that leaves out most other AbstractArray types which are mutable. Or you do y = internally_mutable_f(x) and y = internally_immutable_f(x), i.e. let it be user choice (which is what DiffEq is silently doing), but it’s pretty clear this should be using dispatch and we are just missing a feature…
That will definately not work, there are lots of array types in base that do not satisfy this.
Yes, that sounds much better.
The missing feature is to be able to pass a reference of a stack reference to a function. You should be able to just work on the mutable container since that’ll be how it’s mutated and a much more efficiently way to pass it around anyway.