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.
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.
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.