struct Foo
function Foo(f)
foo = new()
(foo)(x) = f(x)
return foo
end
end
foo = Foo(x->5)
@show typeof(foo)
struct Bar
function Bar(f)
bar = new()
return bar
end
end
bar = Bar(x->5)
@show typeof(bar)
I get, paraphrasing:
typeof(foo) = getfield(Main, Symbol("#foo#3")){getfield(Main, Symbol("##4#5"))}
typeof(bar) = Bar
Note the presence of two calls to new; the first one constructs a Foo struct and the second one constructs something else (I have to admit, I’ve no idea what).
It looks to me that you are trying to achieve something like
julia> struct Foo
f
end
julia> (foo::Foo)(x...) = foo.f(x...)
julia> foo = Foo(x -> 5x)
Foo(getfield(Main, Symbol("##7#8"))())
julia> foo(3)
15
though it is probably better to parameterise on the function type if you are more concerned about runtime speed over compile times, i.e.,
That is how I’m currently implementing my working version but was thinking about how to do away with holding f on the struct. Hence my inner constructor on Foo.
How is your struct going to know what function to call if it doesn’t hold onto it? It kinda looks like you’re meaning to write (::typeof(foo))(x) = 5x — but that’s not what you want here. That’ll mean that calling every instance of foo will result in 5x, so you definitely don’t want to do that in a constructor.
Just remember that Julia dispatches to functions based on their types, not their values. So you can’t define a function (even a call overload) to dispatch on a particular value like you had hoped.
In global scope defining a function foo or any const binding when foo already had a value would be an error, but we don’t have const in local scope so it’s allowed.