# Explicit denotation of variability and immutability

**URL:** <https://discourse.julialang.org/t/explicit-denotation-of-variability-and-immutability/8686>\
**Category:** Internals & Design\
**Tags:** proposal\
**Created:** [January 30, 2018, 10:16am UTC](https://discourse.julialang.org/t/explicit-denotation-of-variability-and-immutability/8686 "2018-01-30T10:16:36Z")\
**Posts on this page:** 1\
**Showing post:** 17

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [January 30, 2018, 9:13pm UTC](https://discourse.julialang.org/t/explicit-denotation-of-variability-and-immutability/8686/17 "2018-01-30T21:13:21Z")

</div>

> [@SepandMeenu](#):
>
> But I cannot imagine how such a “generic” code would be!

```julia
julia> struct foo{T}
           x::T
       end

julia> mutable struct bar{T}
           x::T
       end

julia> g(x::foo) = foo(3x.x)
g (generic function with 2 methods)

julia> function g(x::bar)
           x.x *= 3
           x
       end
g (generic function with 2 methods)

julia> function f(x)
           g(x)
       end
f (generic function with 1 method)

julia> foo1 = foo(9.2)
foo{Float64}(9.2)

julia> bar1 = bar(9.2)
bar{Float64}(9.2)

julia> f(foo1)
foo{Float64}(27.599999999999998)

julia> f(bar1)
bar{Float64}(27.599999999999998)

julia> foo1
foo{Float64}(9.2)

julia> bar1
bar{Float64}(27.599999999999998)

julia> @code_warntype f(bar1)
Variables:
  #self# <optimized out>
  x::bar{Float64}

Body:
  begin 
      $(Expr(:inbounds, false))
      # meta: location REPL[28] g 2
      SSAValue(0) = (Base.mul_float)((Core.getfield)(x::bar{Float64}, :x)::Float64, (Base.sitofp)(Float64, 3)::Float64)::Float64
      (Core.setfield!)(x::bar{Float64}, :x, SSAValue(0))::Float64
      # meta: pop location
      $(Expr(:inbounds, :pop))
      return x::bar{Float64}
  end::bar{Float64}

julia> @code_warntype f(foo1)
Variables:
  #self# <optimized out>
  x::foo{Float64}

Body:
  begin 
      return $(Expr(:new, foo{Float64}, \:((Base.mul_float)((Base.sitofp)(Float64, 3)::Float64, (Core.getfield)(x, :x)::Float64)::Float64)))
  end::foo{Float64}

```

The function `g` was inlined into `f` both for the `f` compiled for `foo` and for the `f` compiled for `bar`.  
In the former, the argument `x` is not mutated. In the latter, it is.  
You can come up with similar examples for const vs nonconst bindings.

---

_[View the full topic](https://discourse.julialang.org/t/explicit-denotation-of-variability-and-immutability/8686)._
