Bookmark and Share

Notice: On April 23, 2014, Statalist moved from an email list to a forum, based at statalist.org.


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

st: Using transmorphic variables to hold objects in Mata


From   "Joseph Coveney" <[email protected]>
To   <[email protected]>
Subject   st: Using transmorphic variables to hold objects in Mata
Date   Tue, 28 May 2013 00:58:49 +0900

I'm trying to relax static typing for Mata's class programming in order to be
able to interchangeably use objects that have a given method (member function)
but that are not in the same inheritance hierarchy (so-called duck typing).  At
first I considered using Mata's transmorphic element type.  In interactive mode,
this does work, but it doesn't work elsewhere:  although -eltype()-correctly
detects that the variable is holding a class, any attempt to invoke the object's
method results in the same error message, one indicating that Mata is looking
for a -struct- and not finding it.  Likewise, if I try using a generic pointer,
-eltype()-again shows that the pointer is pointing to a class definition, yet
attempting to dereference the method (member function) results in an analogous
error message.  See the first do-file's result screen below--the problematic
lines of code are commented out along with their corresponding error messages.
It also shows the tactic's working successfully only in interactive mode.

I've managed to accomplish what I want by (i) declaring a pointer that is
defined for an unrelated class that has the given method,(ii) pointing the
pointer to Null, and then (iii) pointing the pointer to the duck-typed object
(which happens to be held temporarily in a transmorphic variable).  See the
second do-file's result screen below.  The code would do Rube Goldberg proud.
Is anyone aware of a more straightforward approach to this?  Mata seems to
recognize when a transmorphic variable is holding an object under some
circumstances, but not under others.

Joseph Coveney

========== First (doesn't work) ===================

. version 12.1

. 
. clear *

. set more off

. 
. mata:
------------------------------------------------- mata (type end to exit)
----------------------------------------------------------------
: mata set matastrict on

: 
: class A {
>         public:
>                 static final void show()
> }

: void function A::show() printf("A\n")

: 
: A = A()

: A.show()
A

: 
: class B {
>         public:
>                 static final void test()
> }

: void function B::test(transmorphic scalar class_variable) {
>         eltype(class_variable)
>         /* class_variable.show()
>         "type mismatch:  exp.exp:  transmorphic found where struct expected"
*/
> }

: 
: class D {
>         public:
>                 static final void tryem()
> }

: void function D::tryem(pointer() scalar class_ptr) {
>         eltype(*class_ptr)
>         /* class_ptr->show()
>         "type mismatch:  exp->exp:  transmorphic found where struct expected"
*/
> }

: 
: 
: void function test() {
> "1"
>         class B scalar b
>         b.test(A())
> "2"
>         class D scalar d
>         d.tryem(&A())
> "3"
>         transmorphic scalar F
>         F = A()
>         eltype(F)
>         /* F.show()
>         "type mismatch:  exp.exp:  transmorphic found where struct expected"
*/
> "4"
>         pointer() scalar a_ptr
>         a_ptr = &A()
>         eltype(*a_ptr)
>         /* a_ptr->show()
>         "type mismatch:  exp->exp:  transmorphic found where struct expected"
*/
> }

: 
: test()
  1
  class
  2
  classdef
  3
  class
  4
  classdef

: 
: end
--------------------------------------------------------------------------------
----------------------------------------------------------

. 
. exit

end of do-file

============== Second (works) =====================

. version 12.1

. 
. clear *

. set more off

. 
. mata:
------------------------------------------------- mata (type end to exit)
----------------------------------------------------------------
: mata set matastrict on

: 
: class A {
>         public:
>                 static final void show()
> }

: void function A::show() printf("A\n")

: 
: class IsNotAnA {
>         public:
>                 static final void show()
> }

: void function IsNotAnA::show() printf("A\n")

: 
: class B {
>         public:
>                 static final void test()
> }

: void function B::test(transmorphic scalar is_an_a) {
>         pointer(class IsNotAnA scalar) scalar not_an_a_ptr
>         not_an_a_ptr = NULL
>         not_an_a_ptr = &is_an_a
>         not_an_a_ptr->show()
> }

: 
: void function test() {
>         class B scalar b
>         b.test(A())
> }

: 
: test()
A

: 
: end
--------------------------------------------------------------------------------
----------------------------------------------------------

. 
. exit

end of do-file

*
*   For searches and help try:
*   http://www.stata.com/help.cgi?search
*   http://www.stata.com/support/faqs/resources/statalist-faq/
*   http://www.ats.ucla.edu/stat/stata/


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