help mata mm_callf()
-------------------------------------------------------------------------------

Title

mm_callf() -- Pass varying number of optional arguments to function

Syntax

setup = mm_callf_setup(f, n [, p1, p2, ..., p10])

transmorphic mm_callf(setup [, o1, o2, o3, o4, o5])

where

f: pointer scalar containing address of function; usually this is coded &funcname()

n: real scalar containing number of "active" optional arguments

p1 to p10: potential optional arguments to pass to function f

o1 to o5: non-optional arguments to pass to function f

setup: a variable used for communication between mm_callf_setup() and mm_callf(); if you declare setup, declare it to be transmorphic

Description

mm_callf_setup() and mm_callf() are helper tools to implement passing through optional arguments to functions. Up to 10 optional arguments and up to 5 non-optional arguments are supported. The tools are based on a suggestion made by Bill Gould on Statalist. See http://www.stata.com/statalist/archive/2006-06/msg00303.html.

Remarks

mm_callf_setup() and mm_callf() are useful if you are programming functions that pass on optional arguments to functions. The difficulty with passing optional arguments is that the number of arguments may not be known in advance. Usage of mm_callf_setup() and mm_callf() is illustrated by the following two examples.

Example 1: static wrapper

Say, you intend to program a function called func1() that is a wrapper for a function called func2(). Assume, that func2() has one non-optional argument, x, and two optional arguments, mean and variance. You may code:

function func1(x, | mean, variance) { transmorphic p

p = mm_callf_setup(&func2(), args()-1, mean, var)

return(mm_callf(p, x)) }

If a user specifies func1(x), then mm_callf() will simply execute func2(x). If, however, the user specifies func1(x, mean), then mm_callf() will execute func2(x, mean). Finally, if func1(x, mean, var) is specified, then mm_callf() will execute func2(x, mean, var).

The only tricky part here is the n argument in mm_callf_setup(). It should reflect the number of pass-through arguments that have been specified by the user. This number can be computed as args()-#, where # is the number of other arguments (1 in the example above, x).

Note that func1() may itself have its own optional arguments. The only important thing is that the pass-through arguments come last and that args()-# properly computes the number of specified pass-through arguments. Example:

function func1(x, | log, mean, variance) { transmorphic p

if (args()==1) log = 0

p = mm_callf_setup(&func2(), args()-2, mean, var)

if (log) return(mm_callf(p, log(x))) return(mm_callf(p, x)) }

See the source code of mm_kint() for a real example.

Example 2: dynamic wrapper

A more complicated case is when you are programming a function that receives a function as an argument and optional arguments are to be passed on to this received function. (If you have not read [M-2] ftof yet, please read it now.) Let the wrapper function again be called func1(). Assume that there are two non-optional arguments, x and w, and that the maximum number of optional arguments to be passed through is three. The code of func1() may then be:

function func1(pointer(function) scalar f, x, w, | a1, a2, a3) { transmorphic p

p = mm_callf_setup(f, args()-3, a1, a2, a3)

return(mm_callf(p, x, w)) }

See the source code of mm_bs() or mm_jk() for real examples.

Conformability

mm_callf_setup(f, n, p1, ..., p10) f: 1 x 1 n: 1 x 1 p1 etc.: (depending on function f) result: struct mm_callf_o10

mm_callf(setup, o1, ..., o5) setup: struct mm_callf_o10 o1 etc.: (depending on function f) result: (depending on function f)

Diagnostics

None.

Source code

mm_callf.mata

Author

Ben Jann, ETH Zurich, jann@soz.gess.ethz.ch

Also see