# Immutable or bitstype?

**URL:** <https://discourse.julialang.org/t/immutable-or-bitstype/2093>\
**Category:** General Usage\
**Created:** [February 14, 2017, 1:11am UTC](https://discourse.julialang.org/t/immutable-or-bitstype/2093 "2017-02-14T01:11:48Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [February 14, 2017, 1:11am UTC](https://discourse.julialang.org/t/immutable-or-bitstype/2093/1 "2017-02-14T01:11:48Z")

</div>

I want to define a subtype (say `MyInt`) of `Integer` and be able to convert between `MyInt` and other `Integers`.

I suppose I could use an `immutable` or a `bitstype`:

```julia
immutable MyInt <: supertype(Int)
    x::Int
end

Base.convert(::Type{MyInt}, a::MyInt) = a
Base.convert(::Type{MyInt}, a::Integer) = MyInt(convert(Int, a))
Base.convert{T<:Integer}(::Type{T}, a::MyInt) = convert(T, a.x)
Base.show(io::IO, a::MyInt) = show(a.x)

```

or

```julia
bitstype sizeof(Int)*8 MyInt <: supertype(Int)

Base.convert(::Type{MyInt}, a::MyInt) = a
Base.convert(::Type{MyInt}, a::Integer) = reinterpret(MyInt, convert(Int, a))
Base.convert{T<:Integer}(::Type{T}, a::MyInt) = convert(T, reinterpret(Int, a))
Base.show(io::IO, a::MyInt) = show(reinterpret(Int, a))

```

Is one approach faster/better than the other?  
Are there any other considerations?

I noticed in `Base.Enums` the use of `box` (v0.5) and `bitcast` (v0.6).  
How do these compare with `reinterpret`?

`Enums` in v0.5 uses `Core.Intrinsics.box`:

```julia
Base.convert{T<:Integer}(::Type{T}, x::Enum) = convert(T, box(Int32, x))

```

`Enums` in v0.6 uses `Core.Intrinsics.bitcast`:

```julia
Base.convert{T<:Integer}(::Type{Integer}, x::Enum{T}) = bitcast(T, x)

```

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [February 14, 2017, 8:18am UTC](https://discourse.julialang.org/t/immutable-or-bitstype/2093/2 "2017-02-14T08:18:28Z")

</div>

It would help to know something about what purpose MyInt is to serve. If you want the behaviour of a subtype and prefer to avoid redefining _everything_ related to your type, use immutable not bitstype.  
You may find this helpful.

```
import Base: convert, show,
    ==, <, <=, +, -, *, /, abs, sign

immutable MyInt <: Signed
    val::Int
end

convert(::Type{Int}, x::MyInt) = x.val
convert(::Type{MyInt}, x::Int) = MyInt(x)

show(io::IO, x::MyInt) = show(io, convert(Int, x))

# delegate comparison ops and arithmetic ops 
for op in (:-, :abs, :sign)
    @eval $op(x::MyInt) = MyInt( $op(x.val) )
end
for op in (:(==), :(<), :(<=))
    @eval $op(x::MyInt, y::MyInt) = $op(x.val, y.val)
    @eval $op(x::MyInt, y::Int) = $op(x.val, y)
    @eval $op(x::Int, y::MyInt) = $op(x, y.val)
end
for op in (:+, :-, :*)
    @eval $op(x::MyInt, y::MyInt) = MyInt($op(x.val, y.val))
    @eval $op(x::MyInt, y::Int) = MyInt($op(x.val, y))
    @eval $op(x::Int, y::MyInt) = MyInt($op(x, y.val))
end
# and division
(/)(x::MyInt, y::MyInt) = Float64(x.val) / Float64(y.val)
(/)(x::Int, y::MyInt) = x / Float64(y.val)
(/)(x::MyInt, y:Int) = Float64(x.val) / y

```

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [February 14, 2017, 11:12pm UTC](https://discourse.julialang.org/t/immutable-or-bitstype/2093/3 "2017-02-14T23:12:39Z")

</div>

Thanks for your reply.

> [@](#):
>
> It would help to know something about what purpose MyInt is to serve.

Yes, I should be more specific.  
I am really asking about the difference between Julia’s representation of a single-field `immutable` vs `bitstype`, and if there are any performance benefits, or if there are any other considerations.

In trying to answer my own question I looked at llvm (which I don’t really understand).  
I get this for `immutable`:

```julia
julia> @code_llvm convert(MyInt, 5)

; Function Attrs: uwtable
define %MyInt @julia_convert_71649(%jl_value_t*, i64) #0 {
top:
  %2 = insertvalue %MyInt undef, i64 %1, 0
  ret %MyInt %2
}

```

and this for `bitstype`:

```julia
julia> @code_llvm convert(MyInt, 5)

; Function Attrs: uwtable
define i64 @julia_convert_71658(%jl_value_t*, i64) #0 {
top:
  ret i64 %1
}

```

> [@](#):
>
> If you want the behaviour of a subtype and prefer to avoid redefining everything related to your type, use immutable not bitstype.

If I replace `x.val` and `y.val` with `Int(x)` and `Int(y)` respectively, then your code works for both `immutable` and `bitstype` definitions of `MyInt`.

The only difference is the type definition and `convert` methods:

```julia
immutable MyInt <: Signed
    val::Int
end
convert(::Type{Int}, x::MyInt) = x.val
convert(::Type{MyInt}, x::Int) = MyInt(x)

```

versus

```julia
bitstype sizeof(Int)*8 MyInt <: Signed
convert(::Type{Int}, x::MyInt) = reinterpret(Int, x)
convert(::Type{MyInt}, x::Int) = reinterpret(MyInt, x)

```

So I don’t think it’s any easier to redefine methods using immutable.

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [February 14, 2017, 11:16pm UTC](https://discourse.julialang.org/t/immutable-or-bitstype/2093/4 "2017-02-14T23:16:55Z")

</div>

> [@JeffreySarnoff](#):
>
> It would help to know something about what purpose MyInt is to serve.

But to fully answer your question, my purpose is create a module for defining enums that can be used as an `Integer`, primarily for indexing into arrays.

I realise there is already an `Enum` module in base, but I want to be able to do things like:

```julia
julia> using IntEnums

julia> @IntEnum Regions north east south west
IntEnum Regions:
  north = 1
  east = 2
  south = 3
  west = 4

julia> counts = rand(1:1000, length(Regions))
4-element Array{Int64,1}:
 436
 859
 227
 303

julia> for region in Regions
           println(region, " ", counts[region])
       end
north 436
east 859
south 227
west 303

```

I have this working by using a single-field `immutable` type, but was wondering about the difference between this and using a primitive `bitstype`.

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [February 14, 2017, 11:22pm UTC](https://discourse.julialang.org/t/immutable-or-bitstype/2093/5 "2017-02-14T23:22:43Z")

</div>

🔦  
Bitstypes are used by Julia itself to develop the primitive types we all know and relish; and a bitstype may be used occasionally by a package writer who needs deeply individuated low-level (_bit layout_) behavior. Immutable types are allocated as given in memory (the indirection of array storage is avoided). That gives us the speed of memory immediacy without plowing through aspects of getting a bitstype to be robustly useful.
