Change array type in mutating function?

I am trying to define some simple functions for 2-D and 3-D rotations, and I would like to define a mutating version as well. This function

function rotate!(r, θ)
    r[:] = exp(θ*[0 1 ; -1 0])*r
end

works for arrays of floats, but fails for arrays of ints because the type of r is Array{Int64}, and I’m trying to fill it with floats.

Is there a way to have this function also mutate the array type? I tried a few things and couldn’t find a solution.

No, the type of a value can never be mutated in Julia, so there’s no way to mutate an Array{Int} into an Array{Float64}. The easiest way around this is to just not pass an Array{Int} into your function.

If you want a convenient way to operate on Int array inputs, you could consider making both a mutating and non-mutating version of the function:

function rotate!(r)
  r .= 1.5
end

function rotate(r)
  out = similar(r, promote_type(eltype(r), Float64))
  rotate!(out)
  out
end

This is a common pattern in Julia, where the non-mutating function is just a convenient wrapper to allocate some output, call the mutating version on that output, and then return the result.

No, the element type of an array is fixed.

In this specific case, the mutating function is not written properly.
It allocates a number of temporary arrays, does the multiplication and writes the result back from a temporary array to the original. Whenever you have that pattern, it’s best to just return the temporary array instead of doing extra work of writing its contents into the original.

Okay, I had a suspicion that was the case. I did write up non-mutating versions, so I might try something like you suggest.

hmmm… okay, I’ll have to keep that in mind.

Well, you can use reinterpret, and change the eltype while keeping the data. But that won’t do the right thing in this case.