# Inspecting closures

**URL:** <https://discourse.julialang.org/t/inspecting-closures/2397>\
**Category:** General Usage\
**Tags:** question\
**Created:** [March 2, 2017, 1:57am UTC](https://discourse.julialang.org/t/inspecting-closures/2397 "2017-03-02T01:57:44Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![zabolekar](https://avatars.discourse-cdn.com/v4/letter/z/e79b87/32.png) [@zabolekar](https://discourse.julialang.org/u/zabolekar)\
**Post date:** [March 2, 2017, 1:57am UTC](https://discourse.julialang.org/t/inspecting-closures/2397/1 "2017-03-02T01:57:44Z")

</div>

Is there a way to inspect and modify the environment of a function, like `environment` in R or the (admittedly ugly, but working) combination of `. __code__.co_freevars`, `. __closure__ [idx].cell_contents` and `ctypes.pythonapi.PyCell_Set` in Python?

For example:

```
function f()
   x = 0
   () -> x
end

g = f()

```

Is there a way to modify the return value of `g` without redefining `f` and `g`?

---

<div class="post-metadata">

**Author:** ![ihnorton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ihnorton/32/26_2.png) [@ihnorton](https://discourse.julialang.org/u/ihnorton)\
**Post date:** [March 2, 2017, 1:58am UTC](https://discourse.julialang.org/t/inspecting-closures/2397/2 "2017-03-02T01:58:46Z")

</div>

No.

---

<div class="post-metadata">

**Author:** ![zabolekar](https://avatars.discourse-cdn.com/v4/letter/z/e79b87/32.png) [@zabolekar](https://discourse.julialang.org/u/zabolekar)\
**Post date:** [March 2, 2017, 1:59am UTC](https://discourse.julialang.org/t/inspecting-closures/2397/3 "2017-03-02T01:59:24Z")

</div>

Ok, thanks.

---

<div class="post-metadata">

**Author:** ![ihnorton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ihnorton/32/26_2.png) [@ihnorton](https://discourse.julialang.org/u/ihnorton)\
**Post date:** [March 2, 2017, 2:11am UTC](https://discourse.julialang.org/t/inspecting-closures/2397/4 "2017-03-02T02:11:23Z")

</div>

To expand a little bit, try:

```
g = f()
fieldnames(g)

```

Notice that `x` is a field of the (immutable) type of the closure returned by `f`. So it can be inspected, but not modified. Julia is not designed to permit the level of local dynamism that is possible in some other languages.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [March 2, 2017, 2:41am UTC](https://discourse.julialang.org/t/inspecting-closures/2397/5 "2017-03-02T02:41:46Z")

</div>

You can set it if it’s boxed because the compiler can see some mutation of it, but if the compiler has decided that it’s an unmodified binding then it will be immutable. This is fairly essential to code running fast.

---

<div class="post-metadata">

**Author:** ![andyferris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/andyferris/32/235_2.png) [@andyferris](https://discourse.julialang.org/u/andyferris)\
**Post date:** [March 3, 2017, 10:03am UTC](https://discourse.julialang.org/t/inspecting-closures/2397/6 "2017-03-03T10:03:29Z")

</div>

Was immutability a semantic decision or a performance one? Would this change if such mutables could be inlined on the stack?

(Also is changing a field of an immutable on the heap “officially” supported? If it’s boxed are we guaranteed the compiler won’t make any optimizations assuming immutavilities that we might violate in doing so?)

---

<div class="post-metadata">

**Author:** ![jameson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jameson/32/23_2.png) [@jameson](https://discourse.julialang.org/u/jameson)\
**Post date:** [March 8, 2017, 7:28pm UTC](https://discourse.julialang.org/t/inspecting-closures/2397/7 "2017-03-08T19:28:07Z")

</div>

A semantic decision.

> field of an immutable on the heap “officially” supported

No. They are immutable. It’s also not unofficially supported. If it is boxed, we do many compiler optimizations that would be violated by doing so.

---

<div class="post-metadata">

**Author:** ![andyferris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/andyferris/32/235_2.png) [@andyferris](https://discourse.julialang.org/u/andyferris)\
**Post date:** [March 8, 2017, 8:39pm UTC](https://discourse.julialang.org/t/inspecting-closures/2397/8 "2017-03-08T20:39:40Z")

</div>

That’s what I thought, but what does Stefan mean by this, if not changing the field of a boxed immutable?

> You can set it if it’s boxed because the compiler can see some mutation of it

---

<div class="post-metadata">

**Author:** ![jameson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jameson/32/23_2.png) [@jameson](https://discourse.julialang.org/u/jameson)\
**Post date:** [March 8, 2017, 8:41pm UTC](https://discourse.julialang.org/t/inspecting-closures/2397/9 "2017-03-08T20:41:08Z")

</div>

“boxed” is an overloaded term. In this case, he means that a `Box` instance was allocated for it.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [March 8, 2017, 11:01pm UTC](https://discourse.julialang.org/t/inspecting-closures/2397/10 "2017-03-08T23:01:22Z")

</div>

Yes, in this case, it’s literally wrapped in a mutable `Core.Box` type.

---

<div class="post-metadata">

**Author:** ![andyferris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/andyferris/32/235_2.png) [@andyferris](https://discourse.julialang.org/u/andyferris)\
**Post date:** [March 8, 2017, 11:10pm UTC](https://discourse.julialang.org/t/inspecting-closures/2397/11 "2017-03-08T23:10:48Z")

</div>

So just to be 100% clear, you wouldn’t actually recommend trying to mutate such an immutable boxed object, would you Stefan? It seems it would be susceptible to compiler improvements (such as better inference removing the `Box`).

(Is it correct to assume that the case of using pointers to mutate a field of an element of an `Array{T}` where `isbits(T)` is reasonably safe (given the usual caveats with pointers)?)

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [March 8, 2017, 11:31pm UTC](https://discourse.julialang.org/t/inspecting-closures/2397/12 "2017-03-08T23:31:32Z")

</div>

The box is mutable, that’s the point of the wrapper for captured variables that can change:

```julia
julia> accumulator(n=0) = (d=0) -> n += d
accumulator (generic function with 2 methods)

julia> a = accumulator()
(::#381) (generic function with 2 methods)

julia> a()
0

julia> a(1)
1

julia> a(-3)
-2

julia> a.n
Core.Box(-2)

julia> a.n.contents
-2

julia> a.n.contents = 3
3

julia> a()
3

```

If the captured binding is not mutable then you cannot change it. Well, not officially, but you can change it by poking around in memory, but this definitely seems like asking for trouble:

```julia
julia> adder(a) = b -> a + b
adder (generic function with 1 method)

julia> a = adder(3)
(::#385) (generic function with 1 method)

julia> a(4)
7

julia> a.a
3

julia> unsafe_load(convert(Ptr{Int}, pointer_from_objref(a)))
3

julia> unsafe_store!(convert(Ptr{Int}, pointer_from_objref(a)), 7)
Ptr{Int64} @0x0000000107c8bb00

julia> a(4)
11

```

Although it does happen to work in this case.
