The doc section about ismutable says:

help?> ismutable
search: ismutable ismutabletype isimmutable

  ismutable(v) -> Bool

  Return true if and only if value v is mutable. See Mutable Composite Types for a
  discussion of immutability. Note that this function works on values, so if you
  give it a type, it will tell you that a value of DataType is mutable.

Standing on this word: Return true if and only if value v is mutable and also what the doc says here about strings:

As in Java, strings are immutable: the value of an AbstractString object cannot be changed. To construct a different string value, you construct a new string from parts of other strings.

is there a reason for this still returning true:

julia> ismutable("apple")
true

The above leads to bugs in code where strings are technically known not to be "changeable", but then ismutable still returns true. Moreover the ismutabletype returns true for strings as well:

julia> ismutabletype(String)
true

I'm beginning to think this behaviour for strings is similar to BigInt and BigFloat where same process happens of ismutable and ismutabletype returning true happens also. IMHO, this shouldn't be the case for strings.

0

While I agree that it would be nice if ismutable returned false for strings, my understanding is that ismutable is not very reliable in production code. For custom types, it seems that ismutable boils down to whether your type was defined as a struct or a mutable struct. Consider this example:

struct A{T} <: AbstractVector{T}
    x::Vector{T}
end

Base.size(a::A) = size(a.x)
Base.getindex(a::A, i) = a.x[i]
Base.setindex!(a::A, v, i) = (a.x[i] = v)
julia> a = A([1, 2, 3])
3-element A{Int64}:
 1
 2
 3

julia> a[2] = 100
100

julia> a
3-element A{Int64}:
   1
 100
   3

julia> ismutable(a)
false

So we see that vectors of the custom type A are mutable, but ismutable returns false, because the underlying struct is immutable. 🤷‍♂️

0

So what do we use in production code to determine what's mutable and what isn't?

0

While I don't really know the design behind all this, I'm beginning to feel the best bet is to use is isbitstype as stated from its docs:

help?> isbitstype
search: isbitstype

  isbitstype(T)

  Return true if type T is a "plain data" type, meaning it is immutable and
  contains no references to other values, only primitive types and other
  isbitstype types. Typical examples are numeric types such as UInt8, Float64, and
  Complex{Float64}. This category of types is significant since they are valid as
  type parameters, may not track isdefined / isassigned status, and have a defined
  layout that is compatible with C.

  See also isbits, isprimitivetype, ismutable.
1

Dup of https://github.com/JuliaLang/julia/issues/43229

0

I'm beginning to feel the best bet is to use is isbitstype

Quote from Keno on Discourse:

Well, the reflection functions answer questions about the system, not convention.

In other words, the reflection functions like ismutable and isbits are not really designed for everyday programming, they're designed to answer questions about the underlying objects.

So what do we use in production code to determine what's mutable and what isn't?

If you're only concerned with arrays, you can use ArrayInterface.ismutable, from ArrayInterface.jl, which is different from Base.ismutable. However, not all third party packages that implement array types necessarily use ArrayInterface.jl.

Otherwise, it depends on the context. You can add specific dispatches for the (abstract) types that you know should work. Or you can take the "let it fail" approach. In other words, just use mutation in your function, and if the input object is mutable it will work. If it's not mutable it will throw an error. That's generally the approach that generic code has to take, since there is no IsMutable trait.

1

I understand perfectly and agreed on what you said until the point of:

You can add specific dispatches for the (abstract) types that you know should work.

Inasmuch as that is cool, it shouldn't be that way, since code will show surprises between different users with same source code. If I dispatch and then teach someone with my code, chances are the worst will happen if I DON'T REMEMBER the dispatch part.

There should be a way. Possibly I'd just stick with the isbitstype for now since its reasonable enough.

0

Possibly I'd just stick with the isbitstype for now since its reasonable enough.

For what? What decision are you going to make based on the result of isbitstype?

0

With the doc string from isbitstype I find it reliable than the ismutable or ismutabletype:

help?> isbitstype
search: isbitstype

  isbitstype(T)

  Return true if type T is a "plain data" type, meaning it is immutable and
  contains no references to other values, only primitive types and other
  isbitstype types. Typical examples are numeric types such as UInt8, Float64, and
  Complex{Float64}. This category of types is significant since they are valid as
  type parameters, may not track isdefined / isassigned status, and have a defined
  layout that is compatible with C.
0

I recommend opening a thread on Discourse to get feedback on your particular use case.

0
© 2022 pullanswer.com - All rights reserved.