Stata 15 help for m2_doppelganger


[M-2] doppelganger -- Ghostly library double of built-in function


{function | type} (doppelganger) functionname(...) { .... }


Doppelgangers are used by StataCorp in maintaining compatibility across releases. They have no other use.


Assume you work for StataCorp and you have been assigned the task of improving Mata function sinh(). You discover that sinh() is currently a library function, meaning the code for sinh() is itself written in Mata. After careful consideration, you decide that you wish to move sinh() from the library to being a built-in function written in C. If you do this, you also need to create a doppelganger of sinh(), for inclusion in the library, that reads

numeric matrix (doppelganger) sinh(Z) return(sinh(Z))

You must do this so that once your change is released to Stata's users, they do not have to recompile any existing Mata code they may have written that uses the sinh() function.

After you install the new built-in function sinh() into Mata, the Mata compiler will code a link to your new built-in function wherever the function is used in Mata code. Previously, the compiler coded a call to the external function named "sinh".

What Mata did previously is important because Mata users who do not recompile their own Mata source code will still have a call to the external function named "sinh" in their old compiled code. You might be tempted to leave the old sinh() code in the library to handle that contingency, but there are two problems with that: 1) Just because users have not recompiled, they still will want to get the benefit of your improvement and 2) Mata itself will not let you. The next time someone at StataCorp attempts to recompile the library that contains the old sinh() code, Mata will issue an error saying that function sinh() is built in and thus a library function cannot be compiled with the same name.

Directive doppelganger informs Mata that you want Mata to reverse its check, that is, to verify that a built-in function of the same name does indeed exist, and then go ahead and compile a function of the same name. In our example, the function reads

numeric matrix (doppelganger) sinh(Z) return(sinh(Z))

Thus the entire code for the doppelganger sinh(Z) is return(sinh(Z)). The sinh() in the code on the right is interpreted as a link to the new built-in function you have written because a modern Mata can interpret it no other way. Thus the statement means that, should a call to a library function named "sinh" be executed, the result is to be execution of the built-in sinh().

Because modern Matas cannot interpret an invocation of sinh() as meaning anything other than executing the built-in sinh(), no modern code will ever call the doppelganger sinh(). The doppelganger will be invoked only by old code that has not been recompiled. As time passes, more and more code will be recompiled by more modern Statas, and use of the doppelganger will decrease and ultimately vanish.

© Copyright 1996–2018 StataCorp LLC   |   Terms of use   |   Privacy   |   Contact us   |   What's new   |   Site index