How are functors useful?

Interesting. This may just be an implementation detail — internally closures are lowered into a struct with a field for each capture:

So while you can currently get the captures out by name (and can even introspect them with fieldnames) I’m not sure it’s going to stay this way.

trying to repost here…

sure here it is, it is not very styled as it is not public

fprint_runtime(g,n) = begin
    acum = 0.0
    counter = 0
    last_print_time = time()
    (args...) -> begin
        t = time()
        ret = g(args...)
        acum += time() - t;
        counter += 1
        if (t - last_print_time > n)
            avg = round(1e3*acum/counter)
            print("Average runtime of $(counter) runs : $avg ms\n")
            last_print_time = time()
            acum = 0.0
            counter = 0
export fprint_runtime

it accepts g a general function and n the minimal amount of seconds between console runtime logging,
and return a function that behaves like g that also logs its own runtime.


But x isn’t in the scope at all:

julia> x
ERROR: UndefVarError: x not defined

You are calling

getproperty(f, :x)

to extract a value via an implementation detail:

julia> fieldnames(typeof(f))

You are calling getproperty(f, :x) to extract a value via an implementation detail

Right. It’s just that here is the first place I’ve found out that there is a function to access the list of captured symbols and their values for a given closure.

This is documented in

but, most importantly, you are talking about internals of the language, not something you should rely on in normal usage.

If you want the fields, really do use a struct. Otherwise, future changes to the internal representation could easily break your code — for example, the compiler could change the names of the variables closed over at any point.


Or decide on different types for the fields of the closure. Or decide that they will not change whereas that may not previously have been figured out.

1 Like