# Accessing data in a closure?

Learning to work with closures. This is a construct to find out what is possible.

``````foo(d, x, y) = d[x] = y

struct Test
f::Function
Test(d::Dict, f::Function = (x, y) -> foo(d, x, y)) = new(f)
end

t = Test(Dict())
``````

Whenever I call t.f(x, y) a key, value pair is added to the dict I passed with the Test constructor. So far, so good.

My question is: having t, can I access that dict somehow?

Thanks,
Stef

Found it!

``````t.f.d
``````

I love this language!

Iâ€™m just leaving it here in case anyone else is interested.

1 Like

I took me a while understanding what you did there. Interesting. I would have written it like this:

``````foo(d, x, y) = d[x] = y

struct Test
f::Function
end

Test(d::Dict) = Test( (x,y) -> foo(d,x,y) )

t = Test(Dict())

@show t

@show t.f(1,2)

@show t.f

@show t.f.d

``````

I am not completely sure why you can access the dictionary as if it was a field of the closure. I guess that is because closures are implemented functors, meaning that it is something implicitly like

``````struct F
d :: Dict
end

foo(d,x,y) = d[x] = y

(f::F)(x,y) = foo(f.d,x,y)

f = F(Dict())

@show f
@show f(1,2)
@show f.d

``````

Where clearly `f` has a `d` field. But I am not sure. That is not a common pattern to be seen (or is it?)

It is an implementation detail that variables captured by a closure can be accessed as fields of the closure object. Ideally, you should not rely on it.

7 Likes

What would be the minimal working example of that? This does not work, for example:

``````a = 2
f = x -> a*x
@show f(1).a
``````

Maybe that is a good opportunity to understand how closures work a little further.

Edit:

This works:

``````f(a,x) = x -> a*x
@show f(1,2).a
``````

Yet the analogy with the OP example does not seem exact in this case.

``````julia> adder(x) = y -> x + y
adder (generic function with 1 method)

10
``````
2 Likes

You probably should not be taking that second argument. It is immediately shadowed by the inner closure parameter name.

1 Like

Yes, thanks. I added that trying to build a â€śstandaloneâ€ť working closure. But that makes no sense.

You may find the function `dump` useful in understanding new structures, the closure in this case.

1 Like

I donâ€™t think

I donâ€™t think thatâ€™s true. The docs say: â€śA closure is simply a callable object with field names corresponding to captured variablesâ€ť, though thereâ€™s no code example of accessing it that way. (Julia Functions Â· The Julia Language).
This easy access to closed-over variable is one of the things I was happy to find in Julia, since I always felt was missing in Python. I use it quite a lot.

You are looking at the Developerâ€™s Documentation, not the Userâ€™s Manual.

Accessing captured variables as fields in a closure object is an implementation detail, we have word of god on this:

5 Likes

Yeah, youâ€™re right. I was searching the docs for â€śclosureâ€ť and didnâ€™t notice the result was in the Developer section.
Thatâ€™s pretty disappointing, cause I think itâ€™s an awesome feature.

1 Like

Feel free to use it as long as youâ€™re willing to possibly have your code break with new Julia versions.

2 Likes