Create constructor for type without a default constructor

Hi there,

So suppose a function like

function model()
    a=4
    b=2
    x -> a*x+b
end

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
3 Likes

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.

3 Likes

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