Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Inconsistent Behavior Between Mata Functions and Identical Class Methods Toward Object Types

    This is occasioned by a thread begun by Alfonso Sánchez-Peñalver here.

    It’s been a while since I’ve last waded into Mata’s class programming, but I don’t recall its behaving like that illustrated below. A standalone Mata function respects the type of an object, but that same function, when incorporated into a Mata class as a member function (method), does not.

    .ÿ
    .ÿversionÿ16.1

    .ÿ
    .ÿlogÿcloseÿ_all

    .ÿlogÿusingÿInconsistentBehavior.smcl,ÿnomsgÿname(lo)

    .ÿ
    .ÿclearÿ*

    .ÿ
    .ÿlocalÿline_sizeÿ`c(linesize)'

    .ÿsetÿlinesizeÿ80

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

    :ÿ
    :ÿclassÿParentÿ{
    >ÿÿÿÿÿÿÿÿÿpublic:
    >ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿvirtualÿvoidÿprobe()
    >ÿ}

    :ÿvoidÿfunctionÿParent::probe()ÿprintf("Parent\n")

    :ÿ
    :ÿclassÿChildÿextendsÿParentÿ{
    >ÿÿÿÿÿÿÿÿÿpublic:
    >ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿfinalÿvoidÿprobe()
    >ÿ}

    :ÿvoidÿfunctionÿChild::probe()ÿprintf("Child\n")

    :ÿ
    :ÿclassÿSimpleFactoryÿ{
    >ÿÿÿÿÿÿÿÿÿpublic:
    >ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿclassÿParentÿscalarÿcreate()
    >ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿclassÿParentÿscalarÿpassthrough()
    >ÿ}

    :ÿclassÿParentÿscalarÿfunctionÿSimpleFactory::create()ÿreturn(Child())

    :ÿclassÿParentÿscalarÿfunctionÿSimpleFactory::passthrough(classÿParentÿscalarÿp)
    >ÿÿÿÿÿreturn(p)

    :ÿ
    :ÿ//ÿNakedÿfunctions--identicalÿtoÿclassÿmemberÿfunctionsÿ(methods)ÿabove
    :ÿclassÿParentÿscalarÿfunctionÿcreate()ÿreturn(Child())

    :ÿclassÿParentÿscalarÿfunctionÿpassthrough(classÿParentÿscalarÿp)ÿreturn(p)

    :ÿ
    :ÿ//ÿDemonstrationÿofÿinconsistency
    :ÿvoidÿfunctionÿtestClassMethods()ÿ{
    >ÿÿÿÿÿÿÿÿÿclassÿSimpleFactoryÿscalarÿf
    >ÿÿÿÿÿÿÿÿÿclassÿParentÿscalarÿp
    >ÿ"1"
    >ÿÿÿÿÿÿÿÿÿpÿ=ÿf.create()
    >ÿÿÿÿÿÿÿÿÿp.probe()
    >ÿ"2"
    >ÿÿÿÿÿÿÿÿÿpÿ=ÿf.passthrough(Child())
    >ÿÿÿÿÿÿÿÿÿp.probe()
    >ÿ}

    :ÿ
    :ÿvoidÿfunctionÿtestNakedFunctions()ÿ{
    >ÿÿÿÿÿÿÿÿÿ/*ÿclassÿSimpleFactoryÿscalarÿfÿ*/
    >ÿÿÿÿÿÿÿÿÿclassÿParentÿscalarÿp
    >ÿ"3"
    >ÿÿÿÿÿÿÿÿÿpÿ=ÿ/*ÿf.ÿ*/ÿcreate()
    >ÿÿÿÿÿÿÿÿÿp.probe()
    >ÿ"4"
    >ÿÿÿÿÿÿÿÿÿpÿ=ÿ/*ÿf.ÿ*/ÿpassthrough(Child())
    >ÿÿÿÿÿÿÿÿÿp.probe()
    >ÿ}

    :ÿ
    :ÿtestClassMethods()
    ÿÿ1
    Parent
    ÿÿ2
    Parent

    :ÿ
    :ÿtestNakedFunctions()
    ÿÿ3
    Child
    ÿÿ4
    Child

    :ÿ
    :ÿend
    --------------------------------------------------------------------------------

    .ÿ
    .ÿsetÿlinesizeÿ`line_size'

    .ÿ
    .ÿquietlyÿlogÿcloseÿlo

    .ÿ
    .ÿexit

    endÿofÿdo-file


    .


    Am I overlooking something here? If not, then this strikes me not only as inconsistent behavior, but also as a serious violation of the object-oriented programming principle of polymorphism. I suppose I could work around this by explicitly using pointers to the objects, but it seems like it ought not to be necessary to jump through such hoops inasmuch as a variable for an instantiated object I thought is already a pointer in disguise.

    I’ve attached both the do-file and resulting log file for anyone interested.

    Attached Files

  • #2
    Hi Joseph Coveney. I agree, there is inconsistency. The question rises about which is the right behavior, that in the class or that in the standalone functions. This has to do with the direction of inheritance. In Mata, it seems that inheritance only goes one way from top to bottom. Polymorphism, then, can allow the Child to behave as a Parent, but never a Parent like a Child. My understanding, then, is that the classes provide the right functionality, since you are casting the Child as a Parent, by declaring it to be a Parent, then only the Parent's functionality should be available.

    That should also happen with the standalone functions, but it doesn't and thus the inconsistency.
    Alfonso Sanchez-Penalver

    Comment

    Working...
    X