Many thanks for the clarifications, Bill. Using pointers is exactly what
I did in my program. I will be looking forward to the revised
findexternal() function.
I will shut up now and stop asking complicated Mata questions. Why is it
that I always stumble over the 0.01% of problems.
ben
> -----Original Message-----
> From: [email protected]
> [mailto:[email protected]] On Behalf Of
> William Gould, Stata
> Sent: Friday, August 26, 2005 3:48 PM
> To: [email protected]
> Subject: Re: st: [Mata] passing a function to mata (new question)
>
>
> Do you want to read this?
> -------------------------
>
> Mata is new and many of you have not tried it yet.
>
> I fear that if you read this question and answer, you will
> never use Mata.
> You will come to the conclusion that Mata is suitable only
> for advanced
> programming problems and that using Mata requires knowledge
> that you do
> not have, nor much care to gain.
>
> That would be unfortunate, because Mata really is easy to use
> and is worth
> learning. 99.99% of all problems that will ever be
> approached using Mata will
> not involve the topics discussed below. Do not hold it
> against Mata that it
> can deal with the 0.01% of problems, too.
>
> All that said, what follows really is not difficult, it is
> merely unlikely
> that the majority of Statalisters would ever face the problem.
>
>
> Question and response
> ---------------------
>
> The subject is passing funtions to functions in Mata, and Ben Jann
> <[email protected]> imagines a situation where the
> function he wants
> to pass is given by a string variable:
>
> function me1(string scalar he)
> {
> ...
> if (he=="he1") y = me2(x, &he1())
> else if (he=="he2") y = me2(x, &he2())
> else if (he=="he3") y = me2(x, &he3())
> ...
> return(...)
> }
>
> Benn wonders if it is possible to code the above in such a
> way that the value
> of string scalar he is used directly. As Benn says,
>
> > If Mata had macro expansion, I would type
> >
> > function me1(string scalar he)
> > {
> > ...
> > y = me2(x, &`he'())
> > ...
> > return(...)
> > }
>
>
> Comment 1, "If Mata had macro expansion..."
> -------------------------------------------
>
> My recommendation is to stop thinking like that, although I know that
> after years of ado programming, that is difficult.
>
> What makes Mata faster than ado? It is the fact that Mata
> programs are
> compiled, whereas ado programs are interpreted. When you
> think in terms
> of macro expansion, you are thinking interpretive.
>
> Mata in fact does have macro expansion but you have to
> distinguish between
> expansion at compile time and expansion at run time. The
> little bit of code
> Benn produced would expand `he' at compile-time, and that is
> *NOT* what Benn
> wants.
>
> Expansion at run-time requires writing lots of code. Don't go there.
>
>
> Comment 2: Can the string scalar be used directly?
> ---------------------------------------------------
>
> No, not right now. I have more to say on this, but let's go
> with the "No"
> answer right now.
>
> The most efficient thing to do is just what Benn said,
>
> function me1(string scalar he)
> {
> ...
> if (he=="he1") y = me2(x, &he1())
> else if (he=="he2") y = me2(x, &he2())
> else if (he=="he3") y = me2(x, &he3())
> ...
> return(...)
> }
>
> Now imagine you had 15 places in your code where you wanted
> to execute
> function `he'() (excuse the macro notation). You could do this:
>
>
> function me1(string scalar he)
> {
> ...
> if (he=="he1") p = &he1()
> else if (he=="he2") p = &he2()
> else if (he=="he3") p = &he3()
> ...
> ...
> y = me2(x, p) (1st call)
> ...
> y = me2(x, p) (2nd call)
> ...
> ...
> y = me2(x, p) (15th call)
> }
>
> In the above, p is a pointer. If you felt like delcaring it, you
> could delcare it
>
> pointer(function) p
>
> The point of the above is that something like &he1() is just
> an address,
> and pointers hold addresses, and so you can use pointer variables to
> hold addresses of functions just as you can use them to hold addresses
> of matrices, vectors, and scalars.
>
>
> Comment 3: Can the string scalar be used directly?
> ---------------------------------------------------
>
> "No," I just said.
>
> Have you seen the function [M-5] findexternal()? Quoting from the
> documentation,
>
>
> findexternal(name) returns a pointer to the external global
> matrix, vector, or scalr whose name is specified by name;
> it returns NULL if the external global is not found.
>
>
> Thus, findexternal("x") returns the address of global x, if it exists.
>
> findexternal("he1()") ought to return the address of function he1().
> It does not, but it ought to, and I feel so strongly about
> that, I have
> just recorded it as a bug that it does not.
>
> So let's imagine the "bug" is fixed. Then Benn could code,
>
>
> function me1(string scalar he)
> {
> ...
> p = findexternal(he+"()")
> ...
> y = me2(x, p)
> ...
> }
>
> Presumably, Benn ought to worry about p being NULL.
>
> -- Bill
> [email protected]
> *
> * For searches and help try:
> * http://www.stata.com/support/faqs/res/findit.html
> * http://www.stata.com/support/statalist/faq
> * http://www.ats.ucla.edu/stat/stata/
>
*
* For searches and help try:
* http://www.stata.com/support/faqs/res/findit.html
* http://www.stata.com/support/statalist/faq
* http://www.ats.ucla.edu/stat/stata/