# Cross language polymorphism

**URL:** <https://openturns.discourse.group/t/cross-language-polymorphism/342>\
**Category:** Development\
**Created:** [February 7, 2024, 2:40pm UTC](https://openturns.discourse.group/t/cross-language-polymorphism/342 "2024-02-07T14:40:18Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![josephmure](https://yyz2.discourse-cdn.com/free1/user_avatar/openturns.discourse.group/josephmure/32/114_2.png) [@josephmure](https://openturns.discourse.group/u/josephmure)\
**Post date:** [February 7, 2024, 2:40pm UTC](https://openturns.discourse.group/t/cross-language-polymorphism/342/1 "2024-02-07T14:40:18Z")

</div>

A cool feature would be to be able to define derived classes from the Python interface. This is already possible to some extent for Distributions and Functions (with `PythonDistribution` and `OpenTURNSPythonFunction` respectively), but could maybe be extended to other classes.

It seems to me that SWIG offers a generic way to do this with its “director” feature. See the following links:

- [Derive from C++ base class in SWIGged Python - Stack Overflow](https://stackoverflow.com/a/39273055)
- [How can I implement a C++ class in Python, to be called by C++? - Stack Overflow](https://stackoverflow.com/a/9042139)
- [SWIG-4.2 Documentation](https://www.swig.org/Doc4.2/SWIGDocumentation.html#Python_directors)

---

<div class="post-metadata">

**Author:** ![josephmure](https://yyz2.discourse-cdn.com/free1/user_avatar/openturns.discourse.group/josephmure/32/114_2.png) [@josephmure](https://openturns.discourse.group/u/josephmure)\
**Post date:** [February 7, 2024, 6:30pm UTC](https://openturns.discourse.group/t/cross-language-polymorphism/342/2 "2024-02-07T18:30:02Z")

</div>

EDIT: Thanks to Jean-Christophe Houdebine for pointing out the role of the `clone()` method.

So I played around with directors and was able to produce a minimal example (to get it to do something interesting much more work would be needed I suppose).

Let’s say we want to emulate what `PythonDistribution` does: we want to be able to define child classes of `DistributionImplementation`.

## Step 0 : expose clone() to Python

In `python/src/OTtypes.i` remove the line that tells SWIG to ignore `clone()` methods:

~~%ignore \*::clone() const;~~

## Step 1 : enable directors at module level

In `python/src/model_copula_module.i`, replace the `%module` directive with:

```python
%module(package="openturns", docstring="Copulas.", directors="1") model_copula

```

## Step 2 : create directors for the parent class

In `python/src/DistributionImplementation.i`, before

```cpp
%include openturns/DistributionImplementation.hxx

```

add the following line:

```cpp
%feature("director") DistributionImplementation;

```

## Step 3 : implement a child class that overrides the clone() method

The following Python script:

```python
import openturns as ot

class Stupid(ot.DistributionImplementation):

    def __init__ (self):
        super(). __init__ ()

    def clone(self):
        return self
    
    def getRealization(self):
        return ot.Point([0.123])
    
s = Stupid()
print(s.getSample(3))
rv = ot.RandomVector(s)
print(rv.getRealization())
print(rv.getSample(2))

```

produces:

```auto
    [X0]
0 : [0.123]
1 : [0.123]
2 : [0.123]
[0.123]
    [X0]
0 : [0.123]
1 : [0.123]

```

Without directors, it would produce the following error:

```auto
RuntimeError: NotYetImplementedException : In DistributionImplementation::computeCDF(const Point & point) const

```

Without overriding the `clone()` method, this error would also be produced when `getRealization()` is called from the `RandomVector`.

---

<div class="post-metadata">

**Author:** ![schueller](https://yyz2.discourse-cdn.com/free1/user_avatar/openturns.discourse.group/schueller/32/3_2.png) [@schueller](https://openturns.discourse.group/u/schueller)\
**Post date:** [February 12, 2024, 3:37pm UTC](https://openturns.discourse.group/t/cross-language-polymorphism/342/3 "2024-02-12T15:37:32Z")

</div>

I just retried, doesnt build either due to a simple syntax error, which swig version are you using ? I have 3.0.12, I guess it was fixed in 4.x

then it works, but we cannot wrap it in a Distribution object, so it means we wont be able to combine in higher level objects (Composed, RV, …), sad

---

<div class="post-metadata">

**Author:** ![josephmure](https://yyz2.discourse-cdn.com/free1/user_avatar/openturns.discourse.group/josephmure/32/114_2.png) [@josephmure](https://openturns.discourse.group/u/josephmure)\
**Post date:** [February 15, 2024, 3:12pm UTC](https://openturns.discourse.group/t/cross-language-polymorphism/342/6 "2024-02-15T15:12:10Z")

</div>

@schueller Jean-Christophe Houdebine has given me a tip to make this work (see the update to my original post): the child class needs to implement `clone()`, which implies that this method must be exposed to Python.

He warns us that conting references might get tricky with directors.  
A possible solution would be to use `disown()` to let C++ take care of memory alone.
