Concepts in C++ that does not apply to Python or MATLAB

Static Data Members

In Python/MATLAB, data members are called properties. It’s called (data) member in C++. I’ll use these names interchangably when comparing these languages.

Python and MATLAB have the concept static methods, but static properties (data members) doesn’t really exist in either language.

Python’s properties has a split personality (class AND instance), so it’s not like C++ that you choose between class XOR instance. Therefore I call those class variables because in C++, static variables do not have split personality: either you are classwise (static) or not. In C++ (or MATLAB) you don’t have both cases sharing the same variable name so a class variable can be shadowed by an instance variable.

As for MATLAB, there’s no Static property. The only classwise properties allowed is Constant property. TMW (creator of MATLAB) decided not to allow non-Const classwise/static properties because of this web of rules:

  • A.B = C can either mean
    1) [Variable] write a new struct A with field B, or
    2) [Class] attempt to write to property B of class (not instance of) A.
  • If a class (definition) A is loaded into the current workspace, allowing case #2 might throw users who intended to make a struct A with field B out of nowhere off.
  • MATLAB gives variables higher priorities than function/classes, so case #2 has to be struck down to make it unambigious.
  • By making A.B, a classwise access to field B, either read only (Constant) or tied to instances a=A(); a.B=C, MATLAB avoided the situation of A.B=C while A is a class (case#2) so A.B=C is unambiguously writing to a struct field (case#1).

I know. This is quite lame. Matrices are first class citizens in MATLAB while classes are an after-thought that isn’t really a thing until 2008. You win some and you lose some.

The official TMW workaround is to use a Static method getter/setter (not dependent properties because it only works for instances or if what it dependended are exclusively Constant properties) with persistent variable holding the internally data that’s meant to be static. This is very convoluted and it sucks. I’d call it a weakness of MATLAB.

Constant properties in MATLAB are static const (classwise-only)

In C++, const properties (data members) can be either instance bound or classwise (static), which means instances could be initialized with a different set of constants.

Instance-wise constant data members is possible in C++ through (member) initializer lists, which happens to be the only route for private constants as public constants could also be list (including brace) initialized (in newer C++ such as C++11).

Constructor is not a first-hand initializer in C++ (directly assigning memory with predefined values). Members are fully constructed in C++ (just not necessarily with the values you wanted) by the time you get inside the constructor function. Therefore, in C++, constants and references (things that cannot be changed) for instances must be done in (member) initializer lists right before the constructor.

Only static const can be optionally defined directly at the class with = sign since C++11. Before then it only worked for integers as it was enum under the hood with a primative compiler design. Otherwise you forward declare the data member (without specifying the details) in the class C such as static const T x, then define it (assign the value) like T C::x = 42 outside the class definition.

In MATLAB, Constant properties are classwise-only (in fact, it’s the only kind of Static property allowed as discussed in the first section). You simply declare the value at the class definition with = sign just like the fast way to type static const in C++11 because there is no concept of (member) initializer list in MATLAB so you can modify how consts and refs are stamped out, not remodel them in the constructor after they are already made.

Accessing constant properties with an object instance has to be a shortcut for classwise constant in MATLAB, while it depends on whether the const is static in C++.

In Python, everybody is a consenting adult. Scream your constants in ALL CAPS and hope everybody act like a gentleman and not touch them. Lol

Static Native Getters/Setters

C++ does not have native getter or setter using a data member’s name so the said data member do not store states but instead act as a proxy (potentially interacting to other state-holding data members).

Let’s say the variable with a native getter/setter in question is x.

In MATLAB, this feature is called Dependent properties, where you define members under properties (Dependent) and the getter function is named function get.x(self, ...).

In Python, @property decorator mangles your function with the same name as the dependent member, aka def x(self, ...) so the functior can call the corresponding getter/setter without the function call round brackets ().

However, both in MATLAB and Python, dependent data members are mainly aimed for instances (objects created), not class-wise!

In Python, it’s simply impossible to stack @staticmethod or @classmethod with @property. I tried doing that and Python just declared the function name (dependent property name) a property object so when I call it (without round brackets for function calls of course), it merely shows “<property at 0x...>‘.

The case of MATLAB is a lot weirder. It’s a web of rules for that are based on seemingly unrelated reasons which created a catch-22 to mean dependent properties are instance-bound without means to access it classwise:

  1. MATLAB doesn’t have classwise properties that are not Const properties (aka no Static data members/properties) to avoid breaking backward compatibility (see the first section of this post for the web of rules that caused it).
  2. In C++’s lingo, MATLAB has no (mutable) static data member. The only nearest thing is (immutable) static const data member (which is called Constant property in MATLAB).
  3. MATLAB does not have instance-wise constants (see above)
  4. Dependent property in MATLAB is neither classwise or instance-wise, because the concept itself is a method (function member) pretending to be a property (data member). More precisely, it’s an extra level of indirection that dispatches getters or setters depending on whether it’s ‘read’ or ‘written’
  5. MATLAB not treating properties (data member) and methods (function member) the same way (when it comes to whether it’s class-bound or instance-bound) created an dilemma (identity crisis) for Dependent property.
  6. Despite Dependent property is really a method in disguise, its getters/setters not allowed to take on a Static role like other methods because it claimed to be a property (data member) so it’s stuck following the more restrictive rules that applies to properties (aka no static)

Without knowing the underlying rules above, the implications are less than intuitive (makes perfect sense if you know what constraints MATLAB is working under that made it nearly impossible for a sensible use case where the user simply wants to create a shortcut for computing with classwise/Const properties):

  1. MATLAB’s rules requires any property that are not Constant to be accessed exclusively through instances.
  2. A Dependent property is not a Const property, so it’s considered an instance-based member.
  3. This implies Dependent data member can only be called from an instance (regardless of whether you’re trying to do it from within the same class or outside the class).
  4. Since Dependent property is defined to be instance-bound, the instance object (self) is passed to getters/setters as the first argument and the definition of the getters/setters has to expect it so it’d be like function get.x(self, ...), just like all instance-bound methods.
  5. There’s nothing that says such getters/setters must use the self passed to it. However, if you use constant properties, it doesn’t matter where you call from the self (object instance) or the class name since constants are classwise-only in MATLAB to both syntax refers to the same thing.

RAII available in C++ and MATLAB but not Python

Garbage collector is a concept only when you are allowed to make multiple aliases for the same underlying data, and don’t want to meticulously keep track of who’s ultimately responsible for winding it down and when.

In particular, garbage collector has the lattitude to not clean the object right away when the reference count goes down to zero. shared_ptr (an automatic memory management technique) promptly cleans the object when the reference count touches zero. Therefore garbage collector can procrastinate painful release (cleanup) process so the program doesn’t have to frequently stumble to do the cleanup.

C++ choose not to use garbage collectors (as class destructors running at a non-deterministic time breaks RAII). Python choose to embrace it at the expense of breaking RAII. MATLAB is kind of in between yet the way MATLAB does it does not break RAII, but it’s not obvious.

MATLAB language has a very unique design choice (mental model) that users see/reason variables as deep copies of stack objects, so there are no concept of aliases (let along reassignable aliases) in the first place to need garbage collection in user-servicable mental model for memory management.

There are people talking about JVM’s garbage collection in MATLAB, but that garbage collector only handle Java objects (which I almost never use unless it’s through Yair Altman’s code). Anything else is handled by MATLAB’s engine.

Since MATLAB’s engine manages how the underlying data are shared, along with allocating and freeing, some people argue that it’s garbage collection.

The popular mental picture of garbage collection is reference counting WITHOUT tracking the real owner (often the first creator): when the last guy drops the link (reference) to the underlying data, the data becomes orphaned and is ready to be garbage collected.

For conventional garbage collectors, timing of object destruction (when the destructor is called) is not deterministic because the object does not die with its original creator. The ‘ownership’ is effectively transferred to the last user of the underlying data.

TMW specifically said they are not garbage collecting (at least for classes since the article is for classes), so whatever they are doing under the hood is not exactly garbage collection in the conventional sense (https://www.mathworks.com/company/technical-articles/inside-matlab-objects-in-r2008a.html)

Given MATLAB is using copy-on-write, and Loren dropped a clue that the copy-on-write won’t be triggered for the entire struct when only one field is changed (only the changed field is copied):

This would imply that if MATLAB does anything close to garbage collecting or managing allocation and deallocation, it can only be done on whatever pieces (my guess would be PODs, simple native data types) that doesn’t involve a user-defined destructor.

Decoupling automatic memory management from classes has the advantage of keeping RAII because user-defined destructors are called deterministically. It’s only after the destructors are unwounded down to the simple data types (some classes contain other complex objects, so their destructors are chain-called deterministically) with no more user-defined destructors attached to it (down to the leaves of a tree), the automatic memory management mechanism can decide how long it’d keep these simple chunks (if somebody else is still using it, an extra copy doesn’t need to be made).

In Python, everything is perceived as (class) objects, even the PODs. MATLAB and C++ distinguishes between PODs and user-defined classes. This means if Python choose to do garbage collection, it has to do it to classes with user-defined destructor as well, thus breaking RAII.

Loading