3

Background

I'm planning to create a large number of Matlab table objects once, so that I can quickly refer to their contents repeatedly. My understanding is that each table variable/column is treated in copy-on-write manner. That is, if a table column is not modified by a function, then a new copy is not created.

From what I recall of C++ as of 1.5 decades ago, I could ensure that the code for a function does not modify its argument's data by using constant-correctness formalism.

The specific question

I am not using C++ in these days, but I would like to achieve a similar effect of ensuring that the code for my Matlab function doesn't change the data for selected arguments, either inadvertently or otherwise. Does anyone know of a nonburensome way to do this, or just as importantly, whether this is an unrealistic expectation?

I am using R2015b.

P.S. I've web searched and came across various relevant articles, e.g.:

http://www.mathworks.com/matlabcentral/answers/359410-is-it-possible-to-avoid-copy-on-write-behavior-in-functions-yet

http://blogs.mathworks.com/loren/2007/03/22/in-place-operations-on-data (which I need clarification on to fully understand, but it isn't my priority just now)

However, I don't believe that I am prematurely optimizing. I know that I don't want to modify the tables. I just need a way to enforce that without having to go through contortions like creating a wrapper class.

I've posted this at: * Stack Overflow * Google groups

user36800
  • 2,019
  • 2
  • 19
  • 34
  • Related: https://stackoverflow.com/questions/1773850/constants-in-matlab – Cris Luengo Nov 25 '18 at 02:45
  • I'm not seeking a way to define constants. Just a way to ensure that a certain function isn't coded in a way to accidentally changes the data for an argument. – user36800 Nov 25 '18 at 03:02

2 Answers2

3

There is no way of making variables constants in MATLAB, except by creating a class with a constant (and static?) member variable. But even then you can do:

t = const_table_class.table;
t(1,1) = 0; % Created and modified a copy!

The reason that a function does not need to mark its inputs as const is because arguments are always passed by value. So a local modification does not modify data in the caller’s workspace. const is something that just doesn’t exist in the MATLAB language.

On the other hand, you can be certain that your data will not be modified by any of the functions you call. Thus, as long as the function that owns the tables does not modify them, they will remain constant. Any function you pass these tables to, if they attempt to modify them, they will create a local copy to be modified. This is only locally a problem. The memory used up by this copy will be freed upon function exit. It will be a bug in the function, but not affect code outside this function.

Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
  • I was afraid that would be the answer. I was hoping that there was a way to have an error or warning generated if designated argument to a function was modified. It's not for the situation in which the modification is intentional. It's to catch the cases in which I (as the coder) really wanted to not modify the data for an argument, but made a mistake in to code so that it modifies the data. That's one of the main benefits of constant correctness in C++. It tells the compiler to flag such situations. Ah well. Thanks! I now the pitfall that I have to be extra careful about. – user36800 Nov 25 '18 at 03:07
  • @user36800: In C++ you can also make a copy of a const object and modify the copy. The const keyword in C++ is, IMO, useful in function interfaces as a guarantee that the data passed into the function is not modified (the compiler enforcement of the const-ness can be thrown out the door with `const_cast` anyway). In MATLAB you will always have this guarantee (except with handle classes). – Cris Luengo Nov 25 '18 at 07:01
  • My experience with C++ is 1.5 decades old, so I just read up on the current liberties taken with constant correctness. I understand your comment. However, I consider it an adequate safeguard to have the coder explicity cast away constantness before using it. The situation I'm seeking a solution for is when the coder intends to not modify the data for an argument, and wants Matlab to inform him/her if some of the code does that. Matlab guarantees that the original data isn't impacted, but I want to prevent the creation of a local copy due to the modification. – user36800 Nov 25 '18 at 16:23
1

You can define a handle class that contains a table as it's preperty. Define a property set listener that triggers and generates error/warning when the value of the property changes.

classdef WarningTable < handle
    properties (SetObservable)
        t
    end
    methods
        function obj = WarningTable(varargin)
            obj.t = table(varargin);
            addlistener(obj,'t','PreSet',...
                @(a,b)warning('table changed!'));
        end
    end
end

This should generate warning:

mytable = WarningTable;
mytable.t(1,1) = 0;
rahnema1
  • 15,264
  • 3
  • 15
  • 27
  • Interesting idea! But of course you can still do `t=mytable.t; t(1,1)=0`... I honestly don't see how you can prevent copies in **any** programming language. – Cris Luengo Nov 25 '18 at 06:56
  • There is not problem in using copy. OP wants `const correctness` that I think the listener can be regarded as a possible solution. – rahnema1 Nov 25 '18 at 07:01
  • @CrisLuengo If table wasn't a sealed class we could subclass it with an overloaded subsasgn that warns. – rahnema1 Nov 25 '18 at 07:16
  • Yes, indeed. Have you ever tried coping the `table` class file and modifying it? Is such a thing possible? – Cris Luengo Nov 25 '18 at 08:04
  • 1
    No, but [here](https://stackoverflow.com/a/34999598/6579744) has been done. – rahnema1 Nov 25 '18 at 09:43
  • Thank you both -- I was hoping for a solution that didn't involve a wrapper class because that would have been trying too hard. I tried to get some insight into the simple-looking code above, and discovered that there is a world of events and listeners to learn about. Perhaps a long term aspiration. In terms of just using `WarningTable`, I assume that an object would created from a table argument at the start of a function, so the constructor would be modified appropriatey for this purpose, and the listener would be added after assigning to the property `t`. – user36800 Nov 25 '18 at 16:56
  • You can instead call `addlistener` in a method other than the constructor. So you can create a `WarningTable` object and then call the method later. But here calling the constructor triggers the warning. – rahnema1 Nov 25 '18 at 17:41