Common | C | C++ | MATLAB | Python | ||
Variable arguments | <stdarg.h> T f(...) Packed in va_arg | Very BAD! Cannot overload when signatures are uncertain. | varargin varargout Both packed as cells. MATLAB does not have named arguments | *args (simple, stored as tuples)**kwargs (specify input by keyword, stored as a dictionary) | ||
Referencing | N/A | operator[] | (_) is for referencessubsindex [_] is for concat {_} is for (un)pack | __getitem__() | ||
Logical Indexing | N/A | N/A | Native (first-class) | List comprehension (Raw Python) Boolean Indexing native with numpy/pandas | ||
Default values | N/A | Supported | Not supported. Manage with inputParser() | Non-intuitive static data behavior. Stick to None or immutables. | ||
Major Dimension | Row | Row | Column | Row (Native/Numpy) Column for Pandas | ||
Constness | const | const | Only in classes | N/A (Consenting adults) | ||
Variable Aliasing | Pointers | References | NO! Copy-on-write | References | ||
= assignment | Copy one element | Values: Copy References: Bind | New Copy Copy-on-write | NO VALUES Bind references only (could be to unnamed objects) | ||
Chained Operations | N/A Assignment’s value is assigned value | Difficult to get it right | Difficult to get it right. MATLAB had some chaining bugs with dataset() as well. | Chains correctly natively | ||
Iterators | Pointers | iterator inSTL containers | MATLAB doesn’t do references | iter(): __iter__() next(): __next__() Python only iterates in 1 direction | ||
Generators | Input iterators | output only per iteration with yield | ||||
Coroutines | C++20 <coroutine> |
Data Types
Common | C | C++ | MATLAB | Python |
Sets | N/A | std::set | Only set operations, not set data type | { , , ...} |
Dictionaries | std::unordered_map | – Dynamic fieldnames (qualified varnames as keys) – containers.Map() or dictionary() since R2022b | Dictionaries{key:value} (Native) | |
Heterogeneous containers | cells | lists (mutable) tuples (immutable) | ||
Structured Heterogeneous | table() dataset() [Old] | Pandas Dataframe | ||
Array, Matrices & Tensors | Native [ , ; , ] | Numpy/PyTorch | ||
Records | struct | class (members) | dynamic field (structs) properties (class) getfield()/setfield() | No structs (use dicts) attribute (class) |
orderly-set
package.Editor Syntax
Common | C | C++ | MATLAB | Python | ||
Commenting | /* ... */ // (only for newer C) | // (single line)/* ... */ (block) | % (single line)(Block): %{ | # (single line)""" or ''' is docstring which might be undersirably picked up | ||
Reliable multi-line commenting (IDE) | Ctrl+(Shift)+R (Windows), / (Mac or Linux) | [Spyder]: Ctrl+ 1 (toggle), 4 (comment), 5 (uncomment) | ||||
Code cell (IDE) | %% | [Spyder]: # %% | ||||
Line Continuation | \ | \ | ... | \ |
Object Oriented Programming Constructs
Common | C++ | MATLAB | Python | ||
Getters Setters | No native syntax. Name mangle (prefix or suffix) yourself to manage | Define methods:get.x set.x | Getter:@property Setter: @x.setter | ||
Deleters | Members can’t be changed on the fly | Members can’t be changed on the fly | Deleter (removing attributes dynamically by del ) | ||
Overloading (Dispatch function by signature) | Overloading | Overload only by first argument | @overload (Static type)
| ||
Initializing class variables | Initializer Lists Constructor | Constructor | Constructor | ||
Constructor | ClassName() | ClassName() | __init__() | ||
Destructor | ~ClassName() | delete() | __del__() | ||
Special methods | Special member functions | (no name) method that control specific behaviors | Magic/Dunder methods | ||
Operator overloading | operator | operator methods to define | Dunder methods |
Functional Programming Constructs
Common | C++ | MATLAB | Python | ||
Function as variable | Functors (Function Objects) operator() | Function Handle | Callables (Function Objects) __call__() | ||
Lambda Syntax | Lambda (C++11) | Anonymous Function | Lambda | ||
Closure (Early binding): an instance of lambda | Capture [] only as necessary.Early binding [=] is capture all. | Early binding ONLY. Takes snapshot of workspace values involved when instantiated (anonymous function object is created) | Late binding* by default. Can capture Po through default valueslambda x,P=Po: x+P (We’re relying users to not enter the captured/optional input argument) |
An instance of a function object is not a closure if there’s any parameter that’s late bound. All lambdas (anonymous functions) in MATLAB are early bound (at creation).
The more proper way (without creating an extra optional argument that’s not supposed to be used, aka defaults overridden) to convert late binding to early binding (by capturing variables) is called partial application, where you freeze the parameters (to be captured) by making them inputs to an outer layer function and return a function object (could be lambda) that uses these parameters.
Currying is partial application one parameter at a time, which is tedious way to stay faithful to pure functional programming.