How to get a function instance from a function type?

How can we get a function instance from a function type eg.
let’s suppose that we def ft = typeof(abs) , how can we get abs again ?

Currently, i have the following code that runs

ft = typeof(abs)

using Test
@test abs == getfield(@__MODULE__, ft.name.mt.name)

But i don’t want to rely on something that seems so much awkward.
Is there something better that can be safely use ?

No, because not all functions have a one-to-one relationship with their types. For instance,

f = let x = 1
   y -> x + y
end

captures runtime data and cannot be reconstructed from it’s type alone.

That said, in the case of functions which are singleton instances, you could do

if isdefined(tf, :instance)
    ft.instance
else
    error("This type does not have a single instance")
end
1 Like

I was looking for an instance fld like for enum . And it was here :slight_smile:
Thanks for pointing out it quickly !

BTW

using Test
@test f.x == 1 # agree, one needs data out of typeof(f)
@test length(typeof(f).name.mt |> Base.MethodList) == 1 # but will be true forever

kind of all(typeof(f).name.mt) do m; m.x==1 end
it’s more a question of storage location than of multiple instance isn’t it ?

1 Like

Nope :slight_smile:

julia> f = let x = 1
          y -> x + y
       end
#5 (generic function with 1 method)

julia> (f::typeof(f))(x, y) = x + y - f.x

julia> length(typeof(f).name.mt |> Base.MethodList)
2

Regarding this:

That’s not what’s meant by instance here. Instance is always a matter of storage, never about the number of methods. E.g.

julia> length(methods(+))
208

Yet, + only has one single instance:

julia> typeof(+).instance
+ (generic function with 208 methods)

Rather, what’s important here is that I can make new copies of f that have the same type, but are distinct:

julia> macro new(T, args...)
           Expr(:new, T, args...)
       end
@new (macro with 1 method)

julia> f2 = @new typeof(f) 2
#5 (generic function with 2 methods)

julia> f2.x
2

julia> typeof(f2) == typeof(f)
true

julia> f2 == f # <--- This is the really important part
false

Now, in reality, you probably shouldn’t be doing this with closures, it’s not really something you’re intended to be doing, but keep in mind that any user defined struct could be a function if you want:

julia> struct Foo <: Function
           x::Int
       end

julia> (foo::Foo)(x) = foo.x + x

julia> Foo(1)(2)
3
2 Likes