There are many built-in functions that return a function object, such as Interpolation[], BSplineFunction[] ,LinearSolveFunction[] and so on.

Now given that I want to build a function called CAGDBSplineFunction[] like the built-in BSplineFunction[] with the help of Cox-DeBoor algorithm.
First trial, please see here
To achieve the dynamic effect and check the validity of the option like the built-in BSplineFunction

I refactored it as below:
CAGDBSplineFunction::invknots =
"Value of option SplineKnots \[Rule] `1` should be a non-decreasing \
real sequence of length `2`, or a symbol Automatic.";
Options[CAGDBSplineFunction] =
{SplineDegree -> Automatic, SplineKnots -> Automatic};
CAGDBSplineFunction /:
MakeBoxes[CAGDBSplineFunction[pts_, opts : OptionsPattern[]], _] :=
Module[{n, sk, sd, range},
n = Length@pts - 1;
sk = OptionValue[SplineKnots];
sd = OptionValue[SplineDegree];
(*check the validity of the option SplineKnots*)
If[sk =!= Automatic,
If[n + 1 + sd != Length[sk] - 1,
Message[CAGDBSplineFunction::invknots, sk, n + 2 + sd];
Return[$Failed]];
range = Through[{First, Last}@sk],
range = {0, 1}
]
]
InterpretationBox[
RowBox[{"CAGDBSplineFunction", "[", "{", #1, ",", #2, "}", ",",
"\"<>\"", "]"}], CAGDBSplineFunction[pts, opts]] & @@ range
]
TEST
pts = {{0, 0}, {1, 1}, {2, -1}, {3, 0}, {4, -2}, {5, 1}};
f = CAGDBSplineFunction[pts]

However, it seems that the option value cannot be achieved in a MakeBoxes construct.
J.M. gives me the following suggestion:
Don't try to do both display and processing at once. Set a definition for evaluating
CAGDBSplineFunction[], and then set a definition for displaying, viaMakeBoxes
According to the J.M.'s hint, I add the defintion to CAGDBSplineFunction[]
CAGDBSplineFunction /:
MakeBoxes[CAGDBSplineFunction[pts_, opts : OptionsPattern[]], _] :=
InterpretationBox[
RowBox[{"CAGDBSplineFunction", "[", "{", #1, ",", #2, "}", ",",
"\"<>\"", "]"}], CAGDBSplineFunction[pts, opts]] & @@
CAGDBSplineFunction[pts, opts]
CAGDBSplineFunction[pts_, opts : OptionsPattern[]] :=
Module[
{n, sk, sd, range},
n = Length@pts - 1;
sk = OptionValue[SplineKnots];
sd = OptionValue[SplineDegree] /. Automatic -> 3;
(*check the validity of the option SplineKnots*)
If[sk =!= Automatic,
If[n + 1 + sd != Length[sk] - 1,
Message[CAGDBSplineFunction::invknots, sk, n + 2 + sd];
Return[$Failed]];
range = Through[{First, Last}@sk],
range = {0, 1}
]
]



constructor[pts_, deg_] := excecutor[someStructure[pts, deg]]; excecutor[someStructure[pts_, deg_]][t_] := doSomething[someStructure[pts, deg, t]]; myfun = constructor[{{1, 1}, {2, 2}}, 1]; myfun[t]? – Dr. belisarius Oct 12 '15 at 06:12makemyfn[stuff_]to return objectmyfn[data]. (2) Formatmyfnwith withMakeBoxesas in the linked questions in the comments. (3) Computation: Define sub-valuemyfn[datastructure_][input_] := (* computation *)for the computation, using whatever patterns fordatastructurethat are appropriate. -- Which is what belisarius said, but seems to have been ignored? – Michael E2 Oct 12 '15 at 10:25Interpolationis distinct fromInterpolatingFunction. The insides of the latter are of no concern to users, thus there's no need to do syntax checking on them. – Szabolcs Oct 18 '15 at 15:23BSplineFunctionindeed do the syntax checking. For instance,f = BSplineFunction[{{1, 1}, {2, 3}, {3, -1}, {4, 1}, {5, 0}}, SplineKnots -> {1, 2, 3}]throws the error infoBSplineFunction::invknots– xyz Oct 18 '15 at 15:41BSplineFunction[pts_, opts : OptionsPattern[]] := Module[{(* stuff *)}, (* stuff *) If[testQ[OptionValue[SplineKnots]], (* throw messages *)]; (* more stuff *) BSplineFunction[(* internal data *)]]. The idea is to have two definitions forBSplineFunction[]: one where it processes data into a definite internal format, and one where its arguments are already in the internal format. The formatting rules are then applied to the latter one. – J. M.'s missing motivation Oct 18 '15 at 16:42