Description
The code above creates a method function that takes up to four arguments, looking up the appropriate method according to the classes of the arguments, with inheritance. To install a method for two arguments, (x,y), of classes X and Y, use code like this: f(X,Y) := (x,y) -> ...
where '...' represents the body of the function you wish to install. The syntax for one or three arguments is analogous. See := for details.
i1 : f = method()
o1 = f
o1 : MethodFunction
|
i2 : f ZZ := x -> -x;
|
i3 : f(ZZ,String) := (n,s) -> concatenate(n:s);
|
i4 : f(String,ZZ,String) := (s,n,t) -> concatenate(s," : ",toString n," : ",t);
|
i5 : f 44
o5 = -44
|
i6 : f(5,"abcd ")
o6 = abcd abcd abcd abcd abcd
|
i7 : f("foo",88,"bar")
o7 = foo : 88 : bar
|
In the following example we install a asymmetric method to illustrate the left-associative order of evaluation for a binary method function.
i8 : p = method(Binary => true, TypicalValue => List)
o8 = p
o8 : MethodFunctionBinary
|
i9 : p(ZZ,ZZ) := p(List,ZZ) := (i,j) -> {i,j}
o9 = -*Function[stdio:9:32-9:38]*-
o9 : FunctionClosure
|
i10 : p(1,2)
o10 = {1, 2}
o10 : List
|
i11 : p(1,2,3,4,5,6)
o11 = {{{{{1, 2}, 3}, 4}, 5}, 6}
o11 : List
|
By default, at most four arguments (in a sequence) can be handled by a method function, and the types have to be considered separately when installing methods. In this example, we define a method function that treats a sequence as a single argument, and we install a method for handling such arguments.
i12 : g = method(Dispatch => Thing);
|
i13 : g ZZ := i -> -i;
|
i14 : g Sequence := S -> reverse S;
|
i15 : g 44
o15 = -44
|
i16 : g(3,4,5,6)
o16 = (6, 5, 4, 3)
o16 : Sequence
|
Here we define a method whose first argument is to be a type. It will convert its second argument to that type.
i17 : h = method(Dispatch => {Type})
o17 = h
o17 : MethodFunction
|
i18 : h(QQ,ZZ) := (QQ,n) -> n/1;
|
i19 : h(RR,ZZ) := (RR,n) -> n + 0.;
|
i20 : h(ZZ,ZZ) := (ZZ,n) -> n;
|
i21 : h(ZZ,14)
o21 = 14
|
i22 : h(QQ,14)
o22 = 14
o22 : QQ
|
i23 : h(RR,14)
o23 = 14
o23 : RR (of precision 53)
|
In the next example we make a linear function of a single real variable whose coefficients are provided as optional arguments named Slope and Intercept, with default value 1.
i24 : r = method(Options => {Slope => 1, Intercept => 1})
o24 = r
o24 : MethodFunctionWithOptions
|
The methods installed for this method function should be written in the form opts -> args -> (...). The argument opts will be assigned a hash table of type OptionTable containing the optional argument names and their current values. For example, in the body of the function, the current value for the argument named b can be recovered with opts#b, or with opts.b, in case b is known to be a global symbol. Be careful not to change the value of b, or the code will stop working; it would be a good idea to protect it.
i25 : r RR := o -> x -> o.Slope * x + o.Intercept
o25 = -*Function[stdio:25:10-25:34]*-
o25 : FunctionClosure
|
i26 : r(5.)
o26 = 6
o26 : RR (of precision 53)
|
i27 : r(5.,Slope=>100)
o27 = 501
o27 : RR (of precision 53)
|
The default option table for r can be recovered with the function options. The options given to method can be recovered with methodOptions.
i28 : options r
o28 = OptionTable{Intercept => 1}
Slope => 1
o28 : OptionTable
|
i29 : methodOptions r
o29 = OptionTable{Binary => false }
Dispatch => {Thing, Thing, Thing, Thing}
Options => {Slope => 1, Intercept => 1}
TypicalValue => Thing
o29 : OptionTable
|
In the next example we define a method function that leaves option processing to the individual methods.
i30 : s = method(Options => true)
o30 = s
o30 : MethodFunctionWithOptions
|
i31 : s ZZ := { Slope => 17 } >> o -> x -> o.Slope * x
o31 = -*Function[/usr/share/Macaulay2/Core/option.m2:15:19-17:33]*-
o31 : FunctionClosure
|
i32 : s RR := { Intercept => 11 } >> o -> x -> x + o.Intercept
o32 = -*Function[/usr/share/Macaulay2/Core/option.m2:15:19-17:33]*-
o32 : FunctionClosure
|
i33 : s 100
o33 = 1700
|
i34 : s 1000.
o34 = 1011
o34 : RR (of precision 53)
|
i35 : options s
|
i36 : options(s,ZZ)
o36 = OptionTable{Slope => 17}
o36 : OptionTable
|
i37 : options(s,RR)
o37 = OptionTable{Intercept => 11}
o37 : OptionTable
|
For now, one installs a method function for s with no non-optional arguments using installMethod:
i38 : installMethod(s,{ Slope => 1234 } >> o -> () -> o.Slope)
o38 = -*Function[/usr/share/Macaulay2/Core/option.m2:15:19-17:33]*-
o38 : FunctionClosure
|
i39 : s()
o39 = 1234
|
i40 : s(Slope => 4)
o40 = 4
|