then, mymodel = model() seems to be an instantiation of a n implicitly defined struct, and the type itself can be obtained with typeof(mymodel). However, unlike concretely defined types where one can obtain the constructor methods with, say, for a type A with methods(A), when doing methods(typeof(mymodel)) we get Type has no methods, implying these implicit types do not have constructors.
How would one go around defining a constructor for these types, when they do not have a default one?
What you are returning there is a closure. I am not sure what you mean by “constructor for these types”?
You can also define a struct and derive it from Function, this way you can explicitly define the closure and other methods:
julia> struct Model <: Function
a
b
end
julia> (m::Model)(x) = m.a * x + m.b
julia> mymodel = Model(4, 2)
(::Model) (generic function with 1 method)
julia> mymodel(5)
22
julia> methods(Model)
# 1 method for type constructor:
[1] Model(a, b) in Main at REPL[5]:2
You’re correct that a closure is implemented as a struct, but I’m not aware of any way to manually construct an instance of that type except through the normal mechanism of creating the closure itself. I think this is by design: closures were not always implemented as structs, and i don’t think the language explicitly promises that they will behave exactly like them.
Once you start wanting more struct-like behavior, I would agree with @tamasgal’s advice to define an actual struct and make it callable.
Thanks @tamasgal and @rdeits for clarifying out the difference between a struct and a closure, I can understand they likely have different features by design and that I’d be better off sticking to an actual struct