General
Follow


Xiang Xu

Is struct harmful for MATLAB projects?

Xiang Xu on 6 Feb 2024
Latest activity Reply by David Young on 11 Mar 2024

Struct is an easy way to combine different types of variants. But now MATLAB supports classes well, and I think class is always a better alternative than struct. I can't find a single scenario that struct is necessary. There are many shortcomings using structs in a project, e.g. uncontrollable field names, unexamined values, etc. What's your opinion?
David Young
David Young on 11 Mar 2024
For the reasons others have given - but particularly to avoid proliferation of m-files - I use structs whenever they are sufficient. Occasionally, though, it is neater to package up properties and methods together, and then I turn to classes.
However, there are situations when classes are more efficient. If your data has a tree structure you can build a representation from structs, but if you then need to update a value deep inside the tree this will be slow because you'll have to rebuild all of the ancestors. Handle classes allow this to be done efficiently - though at the cost of losing the consistency and safety of assign-by-value.
It's worth noting too that dictionaries offer another alternative to structs. They are more versatile and sometimes more efficient. There's some good discussion in the comments on this blog.
Yair Altman
Yair Altman on 6 Feb 2024
I find that OOP is often over-rated. In many use-cases there is no specific need for data encapsulation or security, and no data-specific methods that should be enclosed with the data (rather than being available as generic code functions). In such cases, structs are much easier to code, debug, use and modify than classes that require their own separate m-files. With structs, I can keep my focus in the active file, rather than constantly switching back-and-forth between m-files.
Here's a simple example: the EventData parameter of event callbacks used to be a simple struct with easily identifiable fields. Nowadays we need to define a new subclass whose only purpose is to store 2 simple data values. This is overkill in most cases. I have better ways to use my worktime, and find that using classes rather than structs doesn't provide any real benefit that's worth the extra work, debugging etc. I rather spend my worktime making my code work better, than making it look better.
Classes do make the code more structured and assist long-term maintenance. On the other hand, they also causes software bloat which has the oposite effect: 10 lines embedded within the main code are often more readable/maintainable than a separate 100-line class file. In my experience, well-written and well-structured procedural code is actually more readable/maintainable than a poorly-designed spaghetti of interconnected classes (which is too often the case with OOP code).
[Most] everyone have heard about Design Patterns and UML designs. But how many Matlab users actually use them in practice? In my experience, most users who use OOP do not...
My advice: any data structure that is just used to store data, certainly transient/temporary data, might be better served with a simple struct (or struct array) than classes.
Walter Roberson
Walter Roberson on 6 Feb 2024
load() of a .mat file produces a struct that has potentially unknown field names. It would be a nuisance to stop and convert the struct into a class at load point.
goc3
goc3 on 6 Feb 2024
Some third-party apps also return structs or struct arrays. Being able to directly use these without conversion is helpful.
goc3
goc3 on 6 Feb 2024
I did a search for class vs. struct in MATLAB; there are a few interesting results. I will post them as replies to this comment so that they can be commented on separately.
goc3
goc3 on 6 Feb 2024 (Edited on 6 Feb 2024)
"I find OOP helpful in a situation where I'm computing something that depends on lots of different inputs - parameters, data, options or whatever - and where there are intermediate results that depend on some of these inputs but not on others. If only some of the inputs change between calls and I want to save intermediate results, it becomes complex to manage by passing structures around."
goc3
goc3 on 6 Feb 2024
One person claims: "A struct is just a christmas tree that you can hang anything off at any time you want. Very nice and convenient, but can be a nightmare for debugging, sharing code amongst others, readability, etc etc because just by looking at a piece of code you have no idea what fields are on a struct at any given moment unless it is entirely defined and limited to the scope you are looking at."
A response to that statement: "Just looking at a class object you often have a pretty poor idea of what the properties are unless you read the class definition in detail. There are properties, there are hidden properties, there are methods that look like properties, the display method can result in output that gives a fairly different interpretation of the object then what is actually present in the properties, and what looks like a straight-forward assignment can end up executing code that changes dependent properties or ends up computing something that changes program state in non-obvious ways. If you want to understand what your program is doing, do away with the OOP and stick with struct."
goc3
goc3 on 6 Feb 2024
In response to the question: "Is using classes vs. structures more computationally efficient? Especially with parallelization ?":
"Using struct has traditionally been more efficient, as searching for the correct method can be expensive."
goc3
goc3 on 6 Feb 2024
"Conceptually, there is not much difference between a structure and a class, both are a container for fields. The main difference is a that the fields of a structure are always read/write whereas some of the fields of a class can be read only (or even private). Therefore, it is always possible to convert a class to a structure (fields are guaranteed to be writeable) but the opposite may not be true."
Matt J
Matt J on 7 Feb 2024
The main difference is a that the fields of a structure are always read/write whereas some of the fields of a class can be read only (or even private).
I would say the main difference is that classes can have user-defined methods, whereas a struct can only contain data.
Yair Altman
Yair Altman on 15 Feb 2024 (Edited on 15 Feb 2024)
In some cases this distinction between structs and classes is quite vague:
1) "structs can only contain data, not methods" - structs fields can actually contain function handles and used just like class methods:
>> myStruct = struct('data',pi, 'function',@cos)
myStruct =
struct with fields:
data: 3.14159265358979
function: @cos
>> myStruct.function(pi)
ans =
-1
This technique is used extensively by Matlab's own code for various components, for example the API to access graphic objects such as imline, imrect, imellipse etc.
In recent years MathWorks has recoded many similar APIs using the classdef framework, but the basic idea of using function handles in struct fields works just as well today as 20 years ago. I'm not in charge, but I'm doubtful if the improved maintainability of classdef code is worth the refactoring cost and risks. I'd personally prefer to invest the R&D efforts to improve functionality and usability, which is not the case here.
2) "structs are always read/write; class properties can be read-only" - structs that are passed as input arguments to functions do not update the original data struct unless they are explicitely returned by the function and assigned back to the original struct variable. This is the typical bahavior of the standard "pass by value" mechanism. Class objects behave exactly the same, unless the class is explicitly defined as a handle class, which is not default. It is true that (unlike classes) no error is thrown when updating fields of input args that are structs, but the bottom line is that such struct args are just as read-only as class object args.
For example, event-data input args to asynchronous callback functions used to be implemented as structs, and were recently changed to class objects across the board (a huge R&D effort). The benefit to end-users: nil.
Matt J
Matt J on 29 Feb 2024
structs fields can actually contain function handles and used just like class methods:
I have a hard time seeing it as the same. One of the main things ablout class methods in OOP is that they have implicit access to the class instance and its property data. Your example could accomodate that if you passed mystruct explicitly to its own member function,
myStruct.function(mystruct, arg1,arg2,...,argN)
but to me that's kind of clunky.
Also, the struct framework doesn't allow you to overload the function to allow calling syntaxes like,
cos(myStruct)
goc3
goc3 on 15 Feb 2024
@Yair Altman, the example you provided for the first point is clever. Thanks for highlighting it.
Guillaume
Guillaume on 6 Feb 2024
They server different purpose and are both equally useful.
A class has a fixed set of properties (baring the use of dynamic props) with associated methods which the user cannot modify. Indeed if what you want is a fixed interface with your user, then use a class.
A class cannot be created on the fly, it needs an m file to define it. If your code needs to return structured data whose fields are unknown a priori, use a struct. See readstruct for example. A struct is a lot more lightweight than a class.
Most of my code is OOP so I use classes a lot, some of these classes do use structs to interface with the user or internally.
Matt J
Matt J on 6 Feb 2024 (Edited on 6 Feb 2024)
Are cell arrays harmful as well? Structs and cells are a lot alike, except for the way they are indexed.
Also, classes require separate classdef files, which can be a bit cumbersome, especially when there aren't any methods you wish to attach.
goc3
goc3 on 6 Feb 2024
In the past I have used cell arrays quite a bit, but I now find structs to be much better than cell arrays, at least, for my projects.
As a long-time MATLAB user that is very comfortable with procedural programming and aspects of functional programming, but not with OOP, I am curious to see what others have to say on this matter.

See Also

Tags

No tags entered yet.