The idea is to create a callable type. The type of the called type is any type that has a "call". The function f is a callable type because you can call it: f(x) for example. However, functions are not the only things that can act as functions. Indeed, in Julia, functions are basically callable types, which are <: Function .
So, let's build one for your example. Enter your data type that you want:
type Params b1::Float64 b2::Float64 end
Now add a call to Params . Say we want to make x*b1 + b2 . We can make a call that does this:
(p::Params)(x) = x*p.b1 + p.b2
Let's see how it works. Make pairs:
p = Params(2.0,3.0)
Now we can calculate the formula using its call:
p(4)
Now let's see that p acts as a function that uses internal data. It is he.
The rest is built from the same foundation. You must respect the fact that Julia's types are not dynamic. This is for good reason. However, let me say that you do not know how much you want. Then you can just have a field like array b :
type Params b::Vector{Float64} end (p::Params)(x) = x*b[1] + b[2]
Now say that you wanted to change the formula. Then you can have a formula field:
type Params formula b::Vector{Float64} end
and make a call by entering values ββinto this:
(p::Params)(x) = p.formula(x,b)
Now, if the user has done:
p = Params((x,b)->x*b[1]+b[2],2.0,3.0)
then as before:
p(4)
Yay acts the same and still uses internal data.
But since p is just any ol type, we can change the fields. So we can change:
p.formula = (x,b)-> x*b[1]+x*b[2]+b[3] push!(pb,2.0)
and call again, now using the updated fields:
p(4)
Indeed, as @LyndonWhite pointed out, ParameterizedFunctions.jl implements something similar. The strategy for this is called types.
Additional small detail
Some libraries were built (incorrectly), requiring the user to pass a function. So here we have p that "acts as a function", but some libraries do not accept it.
However, there is a quick fix. Just do it <:Function . Example:
type Params <: Function b1::Float64 b2::Float64 end
Now things that require a function will take your p , since that is <:Function . This is the only way to indicate that in Julia Function is an abstract type, and each Function is just a callable type, which is a subtype of Function .