Ideas
Follow


Andrew Janke

What should go in a next-generation MATLAB X?

Andrew Janke on 11 Sep 2021
Latest activity Reply by David Young on 13 Mar 2024

Let's say MathWorks decides to create a MATLAB X release, which takes a big one-time breaking change that abandons back-compatibility and creates a more modern MATLAB language, ditching the unfortunate stuff that's around for historical reasons. What would you like to see in it?
I'm thinking stuff like syntax and semantics tweaks, changes to function behavior and interfaces in the standard library and Toolboxes, and so on.
(The "X" is for major version 10, like in "OS X". Matlab is still on version 9.x even though we use "R20xxa" release names now.)
What should you post where?
Wishlist threads (#1 #2 #3 #4 #5): bugs and feature requests for Matlab Answers
Frustation threads (#1 #2): frustrations about usage and capabilities of Matlab itself
Missing feature threads (#1 #2): features that you whish Matlab would have had
Next Gen threads (#1): features that would break compatibility with previous versions, but would be nice to have
@anyone posting a new thread when the last one gets too large (about 50 answers seems a reasonable limit per thread), please update this list in all last threads. (if you don't have editing privileges, just post a comment asking someone to do the edit)
David Young
David Young on 13 Mar 2024
The first change I would make would be to scrap the special treatment of Nx1 and 1xN matrices. These are given special status (as "column vectors" and "row vectors"), which must, I suppose, be helpful sometimes, but in practice it's confusing (that is, it confuses me) and makes general code much more complex than it should be.
For example, if you write c = a(b) where the values of all the variables are numeric arrays, the rule is that c will be the same shape as b except when a or b is a column vector and the other is a row vector. An exception to a general rule is, as a general rule, a bad thing. One that affects as fundamental an operation as indexing an array is a very bad thing.
Another exception: size truncates trailing 1s except in the case of column vectors, and ndims returns 2 for column vectors. General code therefore has to handle this case specially. For an example of code that could be simpler without these complexities see exindex.
It makes for messy code in other ways: my arguments blocks are peppered with (1,1) to indicate scalars, when (1) would be easier to read and should be sufficient.
It's not as if row vector and column vectors are always treated the same as each other. Matrix multiplication distinguishes between them of course, as does the loop construct for. Making them a special category, when they're actually just different shapes of arrays, simply adds complexity.
Can anyone make a case for keeping this peculiarity?
Jim Svensson
Jim Svensson on 19 Sep 2023
Some simple things would be nice:
  1. counter += 1; salery *= 2 % operator assignment, or whatever it is called
  2. y = (x < 0) ? 3 : 2*x; % ternary operator
Walter Roberson
Walter Roberson on 19 Sep 2023
y = (x < 0) ? 3 : 2*x
Would that be:
y = zeros(size(x), 'like', x); %option 1
y(x<0) = 3;
y(~(x<0)) = 2*x(~(x<0));
or would it be
y = zeros(size(x), 'like', 3); %option 2
y(x<0) = 3;
y(~(x<0)) = 2*x(~(x<0));
or would it be
if any(x < 0, 'all') %option 3
y = 3;
else
y = x;
end
Or would it be
if all(x < 0, 'all') %option 4
y = 3;
else
y = x;
end
or should it be
if isempty(x)
y = x;
else
if x(1) < 0 %option 5
y = zeros(size(x), 'like', 3);
else
y = zeros(size(x), 'like', x);
end
y(x<0) = 3;
y(~(x<0)) = 2*x(~(x<0));
end
Option 1 has a result that is always class(x); option 2 has a result that is class double (because 3 is double). Option 3 and Option 4 force a scalar test and have a class that depends upon which way the test gets answered. Option 5 has a result that is the same class as the first result.
Suppose you had
y = (x < 0) ? ones(1,10,'uint8') : x
and suppose that x is non-scalar that does not happen to be 1 x 10. Does the statement make sense? It potentially does if, as is consistent with if and while you interpret it as a test over "all" of x . But that would only be consistent if you treat the ?: operator as syntax that can only occur as a syntactical shortcut for if/elseif with an assignment always needed. If you treat ?: as operators then for consistency you need the ?: test to be vectorized, more like
(x<0).*3 + (~(x<0)) .* x
(except that expression doesn't work for cases where x might contain infinity, since infinity times 0 is nan rather than 0)
Jim Svensson
Jim Svensson on 19 Sep 2023
Yes this is what I mean.
Rik
Rik on 19 Sep 2023
I would suggest expanding your answer with an explanation of what your syntax should do, e.g.:
% counter += 1; salery *= 2
counter = counter + 1;
salery = salery * 2;
and
% y = (x < 0) ? 3 : 2*x;
if x < 0
y = 3;
else
y = 2*x;
end
Is this indeed the correct interpretation?
Simon
Simon on 6 Sep 2023
Insert 'parfor' option into splitapply( ), grouptransform( ) or create separate parallel versions of those two functions.
Right now the groupbased functions run through groups with for-loop. It's very slow for data with large number of groups. When the said data set was run through with parfor-loop, it was 5 to to 10 times faster.
functional programming hiding looping details makes the coding process closer human cognition. And parfor is a really powerful beast. The combination of these two infowar-horses will make Matlab take a decise lead ahead of sluggish reptile.
Clay Swackhamer
Clay Swackhamer on 5 Sep 2023
My wish list:
  • A real, beautiful dark theme
  • Improving the appearance of figures. Reduce padding around subplots, set default axis and tick mark color to black, adjust default linewidth and font sizes to be a bit larger. In general, try to make figures made quickly with default settings look better.
  • Multi-start options for all solvers in the optimization/curve fit toolbox.
  • Consistent arguments for plotting functions. I think some still use different capitalization schemes (like "LineWidth" vs "linewidth").
Clay Swackhamer
Clay Swackhamer on 6 Sep 2023
This is exactly what I was thinking of. I use both methods to change plot attributes. Maybe I should pick one method and stick with it...
Walter Roberson
Walter Roberson on 5 Sep 2023
When you use name/value pairs for the plotting functions, then the comparisons done are case-insensitive. The same is true when you use set() calls.
When you use dot-syntax like
h.LineWidth = 2.5;
then the comparisons done are case sensitive
At the moment I do not know whether you need to use case-sensitive when you use name=value calling syntax.
Andrew Janke
Andrew Janke on 4 Sep 2023
Yeah, @Rik and/or @Paul, go for creating a new "Matlab X Part 2" question; my browsers are also having trouble dealing with how big this question has gotten. I don't see a way I can lock this question; dunno if that's a moderator-only action or I just don't have enough rep.
Rik
Rik on 4 Sep 2023
The current thread is fairly close to my arbitrary suggested limit of 50 answers. If you think it makes more sense to start a new thread, go ahead. I'm happy to start a new one, but you can also do it and add it to the list of threads (don't forget to edit the other threads as well).
In an attempt to discourage new answers (while waiting for the ability to soft-lock threads), I have started editing the older questions by putting '[DISCONTINUED]' at the start of the question.
Paul
Paul on 4 Sep 2023
This wonderful thread is becoming unwieldy and slow to respond to editing on both laptop and desktop for me. If others are having the same problem, perhaps this Question should be locked, at least for new Answers (is that possible?), and a new Question opened for new Answers?
Simon
Simon on 1 Sep 2023
My wish list, not about code improvement but about official tutorials.
  • a tutorial of using splitapply to take advantage of parallel computation.
  • a tutorial of assignment and indexing involving comma-seprated list, cell array. It not only shows what works, but also explains what syntax would go wrong, and why it go wrong.
For example, x = ["a", "b"] is a 1x2 string array. But then x(:) becomes a column vector, then x{:} is a comma-seprated list; then [x{:}] is a character vector 'ab'. Such 'delicate' usage is the biggest bottleneck for my coding process. @Stephen23 has written a tutorial of comma-separated list. I hope Mathworks staff can take from there to expand it, covering the use cases of table. For example, if T is a table. T(1,:) is a single-row table. But then T{1,:} sometimes works if variables' data type can be lumped together; sometimes fails if variables have mixed data types. But then when it works, say, all table variables are 'string'. Why then T{1,:} is a string array, intead of a comma-separated list? Two similar syntaxes, x{:} and T{1,:}, have two different semantic meaning. That really causes workflow jam in my coding.
Andrew Janke
Andrew Janke on 5 Sep 2023
@Simon - I do cast some of my table variables to categorical, and have also noticed things go slower than I expected with them. (Kinda the whole point of categoricals is that they're small and fast compared to strings, right?) I have no idea what would cause categoricals in table variables to go slow.
Simon
Simon on 5 Sep 2023
@Andrew Janke Do you cast your table variables to categorical? In my case, if a task is to process strings, it will be many-times slower if variables are casted as categorical. I don't know why. What you think might have caused that?
Andrew Janke
Andrew Janke on 4 Sep 2023
> Sounds like you're fairly satisfied with the Matlab table implementation, except for the {} indexing.
Oh yes. I think the Matlab table array implementation is quite good. I'm not even sure the {}-indexing behavior is a problem; I use the multi-variable form of it seldom enough that I don't really have an opinion on whether its concatenation-instead-of-comma-separated-list behavior is an issue. I was just saying it is inconsistent with the {}-indexing behavior of cells and strings and thus unintuitive for a Matlab programmer new to tables; I don't know if that makes it bad.
The main thing about table arrays I think is not great is speed in some cases: addressing variables inside a table, and doing chained/multi-level indexing in to them, is not as fast as with structs, which makes tables unsuitable for some performance-sensitive contexts. (As of R2019b; I haven't benchmarked newer versions.) And I believe that the in-place-modification optimization ("IPMO") of Matlab's execution engine does not work for variables/columns inside a table array, even if the table array is in a local variable and there are no shared references to its underlying variables' data. (I believe that structs, cells, and objects in general share this no-IPMO-on-field-contents limitation, so it's not a weakness unique to table arrays.) And concatenating several tables can be kind of slow.
Paul
Paul on 4 Sep 2023
Thanks for the detailed response. Sounds like you're fairly satisfied with the Matlab table implementation, except for the {} indexing.
Paul
Paul on 4 Sep 2023
Referring to my own comment, timetable can also be accessed via curly bracing.
Also, as of 2023a, dictionary can also be referenced with curly braces to access cell elements of dictionary entries
vals = {1:3 , "Bicycle" , @sin};
keys = [1 2 3];
d = dictionary;
d(keys) = vals
d =
dictionary (doublecell) with 3 entries: 1 ⟼ {[1 2 3]} 2 ⟼ {["Bicycle"]} 3 ⟼ {@sin}
d{1}
ans = 1×3
1 2 3
d{2}
ans = "Bicycle"
d{3}
ans = function_handle with value:
@sin
Apparently curly brace indexing is returning a CSL of the elements stored in the dictionary value cells, rather than a CSL of the dictionary elements themselves, which would be a CSL of cells.
d{1:2}
ans = 1×3
1 2 3
ans = "Bicycle"
Andrew Janke
Andrew Janke on 4 Sep 2023
> When you wrote your own table implelmentation, if {} returned a table, what did () indexing return?
()-indexing also returned a table. This was one of the big differenes between my table array design and Matlab's design: My table array was an array of tables, where each element was a whole table (aka relation), and an array of tables could be of arbitrary size, as opposed to a table array always being a 2-D array of the rows & columns/variables inside that single table like Matlab's does. Like, if you call size(t) on a Matlab table array and it returns [2, 5], you're looking at a "single" table of 2 rows and 5 variables/columns.But a size of [2, 5] in my design is an array of 10 tables, each of which might have different numbers of rows and differnt numbers/names/types of columns. So you could do things like joins or projections with a single method call, and have them apply to many tables at once, with scalar expansion. My table array was more of a container with "stronger" encapsulation of its contents, and each element of a table array was a container that held a whole table/relation, kind of like how in a Matlab cell array, each element of the cell array contains a whole arbitrary-size-and-type array.
I don't think my approach of "array of tables with multi-table function application" ended up being very useful, and I'd probably just do the sizing and ()-indexing Matlab's way if I had to do it all over again. Doing operations over a plain list or array of tables, as opposed to a set of named tables, doesn't seem to happen much in practice, and you can always just slap them in a cell array if you need to do that.
I also had a different approach to dot-indexing. Instead of tbl.Foo being the column/variable Foo inside the table array, I had a special "cols" property that contained the columns for dot-indexing, so it would be tbl.cols.Foo. This meant that methods on table arrays could be called like tbl.meth(...) and you could use tab-expansion on them, and address table-level properties as tbl.Blah instead of tbl.Properties.Blah. I still don't know which of these ways I like better. Probably Matlab's, because column access is such a common operation, and Matlab's direct-column-addressing approach means you can use table arrays as drop-in replacements for structs in many places.
Simon
Simon on 4 Sep 2023
@Stephen23. "x is numeric. It has no comma-separated list syntax because it is not a container". I didn't really mean Matlab should do that kind of crazy thing. Just from a mathematical point of view, a scalar can be seen as a vector (so can be implemented as a container). Even Lisp, which construts almost everything as list, doesn't render scalar as list.
@Stephen23. "**There are some subtleties/differences due to the need to refer to rows: unllike other container types, with tables it is useful to be able to refer to rows (which refer to the content not the container itself)."
"assigning a row of different data types to a table, a challenge I have seen several times on this forum."
Absolutely agreed. At first, I had not been paying enough attention to different levels of extraction from table rows, causing self-doubt :-).
@Walter Roberson. "A few days ago I was trying to write some splitapply code that would have gone notably easier if {} indexing of tables returned comma separated values (or if there had been other syntax that did that.)"
Sharing your frustration. Recently I was trying to shift toward functional programming, and table row stands in the way like a Matryoshka doll--can't access the innermost one without stripping away the outer ones first. Reminder to myself:
  1. T(row,:); a single row table
  2. C = table2cell(T(row,:); a cell array
  3. C{:}; a comma-separated list.
Paul
Paul on 3 Sep 2023
Referring to this comment ...
When you wrote your own table implelmentation, if {} returned a table, what did () indexing return?
Are there other classes in base Matlab besides cell, table, and string that accept curly brace indexing?
I wonder if there are any toolbox classes that accept brace indexing and how that works, i.e., does {} return addressed elements or something else.
Andrew Janke
Andrew Janke on 3 Sep 2023
> A few days ago I was trying to write some splitapply code that would have gone notably easier
I hear that. Matlab's splitapply, join, and similar table functions have never really felt quite "right" to me, in terms of their interfaces. I usually end up writing my own wrapper functions on top of them that translate them to interfaces that feel more natural to me. But I'm an old SQL/table-head, maybe my tastes in code are just weird here.
Bruno Luong
Bruno Luong on 3 Sep 2023
A work around to do comma list on table content in single command
person=["maman"; "papa"; "moi"];
x=rand(3,1);
T=table(person,x)
T = 3×2 table
person x _______ ________ "maman" 0.028974 "papa" 0.20146 "moi" 0.3114
struct('dummy',num2cell(T{:,1})).dummy
ans = "maman"
ans = "papa"
ans = "moi"
struct('dummy',num2cell(T{:,2})).dummy
ans = 0.0290
ans = 0.2015
ans = 0.3114
Unfortunately I don't know how to put this little command in a function, since it will return only the first element of the comma list.
Walter Roberson
Walter Roberson on 3 Sep 2023
A few days ago I was trying to write some splitapply code that would have gone notably easier if {} indexing of tables returned comma separated values (or if there had been other syntax that did that.)
Andrew Janke
Andrew Janke on 3 Sep 2023
Anyway, FWIW, I am similarly bothered as @Simon about how "{...}" brace indexing in to a table array returns a single array (subject to concatenation of the addressed elements) in a single variable/argout instead of a comma-separated list. I think this is probably the more-commonly-used case, so on the one hand it makes sense there. ("{}"-indexing is just an operation you can override or define however you want, at least in user-defined classes.) But there's just no precedent for it in the Matlab base language or standard library. I can't think of any other datatype that accepts brace-indexing and doesn't return a comma-separated list containing "addressed elements" in return. And the inverse as an lvalue.
Back when I implemented table arrays in my own Matlab library, I overrode {}-indexing to subset tables, producing tables. (Because I thought, who would do brace-indexing across multiple columns in a table array, and want it back as a comma-separated list? Why would you even do that?) And my {}-indexing was even weirder: it accepted a string with a SQL-style "WHERE" clause predicate, so you could do like t2 = t{'Date > now-7 && NumErrors > 1'} if you want to see things that blew up recently. Which was clever and concise. But I came to regret it: in standard Matlab usage, brace-indexing is such a specific thing with certain semantic/low-level effects, that I think it's best to just not devaite from that, even if it seems like a really useful thing to do. If I were doing it again today, I would have skipped the {}-indexing override and just used a really short method name, like "q()"`.
Andrew Janke
Andrew Janke on 3 Sep 2023
> It already does, that is exactly what happens
Yes. This is maybe a rhetorical issue. I was doing the British-style thing of "oh, perhaps there are reasons this thing works the way it does, and we should try to understand and think about those, instead of just getting grumpy and demanding it work in a different manner" thing. Like, I'm not actually wondering if there's perhaps a reason for that; I am somewhat familiar with those reasons and it's more of a Socratic dialog thing.
Sorry if that approach is condescending; I didn't mean it to be an insult.
Stephen23
Stephen23 on 3 Sep 2023
@Simon: "I don't mean that Matlab should change the meanings of x{:} and T{1,:}"
Yet later you state that you want "Suppose T is a table. T{1,:} returns the first row's contents as a comma-separated list.". That would be a change of meaning of curly braces for tables.
Stephen23
Stephen23 on 3 Sep 2023
"If you've got string arrays in table variables, then I think maybe T{x,y} should return a string array there, and then if you want to get at the "contents" of that string array in terms of char vectors, then you should hit that string array with an additional level of {...} indexing..."
It already does, that is exactly what happens:
one = ["hello";"world"];
two = [pi;NaN];
T = table(one,two)
T = 2×2 table
one two _______ ______ "hello" 3.1416 "world" NaN
out = T{1:2,1}
out = 2×1 string array
"hello" "world"
class(out)
ans = 'string'
out{:} % content of string container in a comma-separated list
ans = 'hello'
ans = 'world'
Andrew Janke
Andrew Janke on 3 Sep 2023
> In scalar case, x=x(:)=x{:}.
Are you sure this actually happens? (I assume by "=" you actual mean something like "isequal()" or "is the same as" in the broader sense; one-equal-sign "=" is the assignment operator, and two-equals "==" is the elementwise equality test.)
In the scalar case of an array x, then x and x(:) are the same thing. But the {...} dereferencing/pop-out operation produces something different. The x{...} operation "reaches in to" the contents of x subsetted by "...". I'm not aware of any case where x{...} is the same as x, unless you do some silly special-case subsref magic to make that happen. And I don't think any regular Matlab datatypes do that.
Andrew Janke
Andrew Janke on 3 Sep 2023
Also, note that "comma-separate lists" are – as far as I undersand it – not a Matlab datatype, but a special value-passing form or whateveryoucallit that only happens in the context of M-code syntactical and control flow constructs. CSLs can be captured in to cell arrays and vice versa, but they are not the same thing.
Andrew Janke
Andrew Janke on 3 Sep 2023
> {:} acts like CIA trying to turn Jason Bourne back to what he used to be [...]
Yeah well, what if the CIA pays for your Matlab licenses? Bc in my experience that's usually how it is: Matlab is commercial software, often paid for by the "business" intead of "tech" department, and the biz folks like things to just stay more or less like how they're used to.
> Suppose T is a table. [...] T{1,:} returns [...]
I think maybe there's another level of indirection going on here. If T is a table, then T{x,y} will "pop out" the contents of that table array's columns/variables, as opposed to T(x,y) subsetting the table and then returning another table. (And imho, for Matlab, "table array" means exactly the same thing as "table", because tables are arrays, just like everything else in Matlab.)
If you've got string arrays in table variables, then I think maybe T{x,y} should return a string array there, and then if you want to get at the "contents" of that string array in terms of char vectors, then you should hit that string array with an additional level of {...} indexing. Like, if T is a table array with a variable/column "mystr" that contains strings, maybe T{:,1} should pop out that one var and return a string array, and then T{:,1}{:} should then pop out the the string array's elements in to a list of charvecs, returned as a "comma-separated list" in this context.
My thesis here is that the string array type provides and additional layer of "indirection" or encapsulation that wraps charvecs in a higher-level type, and that table arrays are another level of composition on top of that, and you should expect one application of {...} indexing to only "pop out" one level's worth of encapsulation or composition.
IMHO, string arrays are kind of a special case here, because Matlab string arrays are kind of new thing, and the older ways of Matlab string handling were all kinda sloppy hacks layered on top of kinda-too-low-level representations. (http://matlab.wtf)
Stephen23
Stephen23 on 3 Sep 2023
@Simon: it would be quite handy having {:} also define a comma-separated list for tables, which would make that syntax meaning consistent** for all data types. It would also make a few kinds of operations much easier for tables (e.g. assigning a row of different data types to a table, a challenge I have seen several times on this forum). As far as I can tell, the main difference would be in case of multiple columns/variables, which would need to be replaced with horizontal concatenation, i.e. t{:} -> [t{:}].
Note that for comma-separated lists x(:) != x{:}, so your "singular case" example is inconsistent with all other comma-separated lists and is also inconsistent in and of itself: why should a comma-separated list of one array have a completely different behavior to a comma-separated list with any other number of arrays?. I would not expect or desire that, it would make comma-separated lists much harder to use (need to program special cases) with all of the resulting latent bugs etc.
" Even in scalar case, x = 2; x{:} returns 2."
No, it does not. Lets try that right now:
x = 2;
x{:}
Brace indexing is not supported for variables of this type.
x is numeric. It has no comma-separated list syntax because it is not a container. It makes no sense to attempt curly-brace indexing on something that is not a container.
**There are some subtleties/differences due to the need to refer to rows: unllike other container types, with tables it is useful to be able to refer to rows (which refer to the content not the container itself).
Simon
Simon on 3 Sep 2023
@Rik, thanks for the cellstr solution. I'll give it shot.
@Paul, your feedback led me to think more deeply about {:}.
x = "abc string";
x{:}
ans = 'abc string'
In that example, {:} acts like CIA trying to turn Jason Bourne back to what he used to be. Bad practice. I would like {:} to be like the toughest NKVD intogerator. Whatever container it touches up, the container will spew his or her contents.
Suppose T is a table.
T{1,:} returns the first row's contents as a comma-separated list. Even in scalar case, x = 2; x{:} returns 2. Under this semantic principle, {:} will behave as a nice symetric complement to (:).
T(1,:) returns a single-row table, wrapping the ocntent inside.
T{1,:} returns naked contents.
In scalar case, x=x(:)=x{:}. a singular case that doesn't break general rule, kind of fitting Matlab's birth purpose of serving mathematicians, isn't it?
Paul, the examples you give have my codes want to shout out MeToo. When I looked into built-in rowfun, splitapply, I found they also had the same MeToo moment. Those built-ins must have a carefully crafted local function to handle inconsistent semantic interpretation involving {:}, usually 'flatten' or 'expand' table rows, or other contructs to cell array. (But don't take my words 100% because I lost my patience during the code tracing.)
Steven Lord
Steven Lord on 1 Sep 2023
If you have feedback about a specific documentation page (something you expected to find on the page that's not present, a bug on the page, or a suggestion for an alternate way to phrase something on the page that may be clearer or more general) you can select a rating for "How useful was this information?" at the end of the page. Once you select a number of stars that will be replaced with a box asking "Why did you choose this rating?" where you can enter free-form text. I know for a fact that the documentation staff reviews this feedback.
If you have feedback about something that's missing entirely from the documentation, for that I'd recommend you contact Technical Support directly using this link. They can enter your feedback into the enhancement database for the documentation staff to review.
Bruno Luong
Bruno Luong on 1 Sep 2023
If only we could cascade brace indexing
y = [1 2 3]
num2cell(y){:} % won't work currently
Paul
Paul on 1 Sep 2023
My understanding is that you have two basic concerns:
a) TMW should have a tutorial on Comma Separated Lists. See Comma Separated Lists. Unfortunately, that doc page is lacking as it does NOT discuss how to generate a comma separated list from a string array, when doing so is a feature as you've pointed out. However, that doc page would not discuss comma separated lists as they relate to tables, because there is no way to generate a comma separated from a table (at least not according to the doc page I linked previously).
b) T{1,:} returns an array, not a comma separated list, and is therefore inconsistent with use of {} on classes like cell and string where {} does return a comma separated list. Do you think a comma separated list in this case would be more useful?
As an aside, I've sometimes wanted to be able to generate a comma separated list from a numeric array. Alas such is not possible and one as to resort to workarounds
y = 1:3
y = 1×3
1 2 3
try
y{:};
catch ME
ME.message
end
ans = 'Brace indexing is not supported for variables of this type.'
struct('y',num2cell(y)).y
ans = 1
ans = 2
ans = 3
Bruno Luong
Bruno Luong on 1 Sep 2023
@Steven Lord "...backwards compability with functions that accept cell arrays containing char vectors"
I see that thanks.
Strictly speaking I consider the backward compatibility is not broken even without the {} behavior on string, since every code written for char still works.
What you can "compatibility" is more like wanting the same functionality working for both string and char. However there are a bunch of other things that cannot work for both classes, such as char arithmetics, extract sub-char, numeric conversion, etc...
I remember we were working with a robot using a TCP-IP protocol with sending char-array/string. One of my intership changed char to string or using a function intended working for one and not for another, I can tell you that was the a very frustrating experience for us when the bug occurs because it is not working exactly the same...
Rik
Rik on 1 Sep 2023
I really like how string vectors have extremely similar bahavior to cellstr. You can pretty much rely on cellstr(data) to convert a string and your code should not require any changes. That especially helped me when the Name=Value syntax was introduced:
MyFun(Name='Value')
ans = "Name"
ans = 'Value'
function MyFun(varargin)
for n=1:nargin
varargin{n}
end
end
With varargin{:} forwarding the lot to your parser function, this new syntax is automagically supported.
Simon
Simon on 1 Sep 2023
@Steven Lord, I think back compatibility is the reason. When I began using Matlab, there was no string. That was good old days. Cell array was a wonderful, powerful thing. Life was much simpler. But it was a little too simple without string. Then there was string. Like any new useful invention, it requires users to be re-adjusted. I have saved Loren Shure's wonderful blog post for a quiet raniny day reading.
Paul
Paul on 1 Sep 2023
Frankly, I've never thought about it until I saw that use in this thread. Without thinking about it much more, I don't have any issue with curly brace indexing of a string array returning a comma separated list of char.
I did find this doc Access Characters Within Strings that at least shows how curly brace indexing works to convert one element of a string array to a char and relates that back to similarity of indexing into cell arrays of chars. In that sense, having x{:} return a CSL makes sense in that it mimics the behavior of the "old days" when x would be cell array.
x = {'a' , 'b'};
x{:}
ans = 'a'
ans = 'b'
Having Access Characters Wtihin Strings as a subordinate topic on a doc page for Create String Arrays is quite illogical IMO.
Steven Lord
Steven Lord on 1 Sep 2023
If I recall correctly, one of the reasons (perhaps the main reason) for curly brace indexing on a string array returning a comma-separated list of char vectors is for backwards compability with functions that accept cell arrays containing char vectors. See the third bullet point in the Looking to the Future section on this post from Loren Shure's blog about working with text in MATLAB.
If we'd made that operation error, I suspect our users would be grumbling something along the lines of "MathWorks, you know what I meant, just go ahead and do it instead of making me change my code to distinguish cellstr and string!" [Actually, you probably wouldn't have because internally MathWorks developers who would have had to make those same changes in our code base would have grumbled before the feature got released!]
Simon
Simon on 1 Sep 2023
@Paul, from the perspective of a pracctical user of Matlab, I don't mind what x{:} returns. An end-user-oriented tutorial would be good enough. Comma-separated list is a wonderful construct, and I have come gradually to embrace it. Great help came from @Stephen23, who has written an excellent tutorial: comma-separated lists. I hope Matlab staff could expand on that.
I remember I read somewhere, Hacker News maybe, that some experienced programmer in other languages, who wanted to get into Matlab, complained about similar things. The tutorial I suggest would lower Matlab's entrance barrier for, say, C++ programmers.
Bruno Luong
Bruno Luong on 1 Sep 2023
@Paul What would YOU like
x = ["a" , "b"];
x{:}
returns?
PS: "throw an error" is also a valid answer.
Paul
Paul on 1 Sep 2023
Does Access Data in Table cover all of the use cases for table indexing that you're looking for?
I, not surprisingly, couldn't find a doc page for x{:} where x is string array
x = ["a" , "b"];
x{:}
ans = 'a'
ans = 'b'
Setting aside concerns about inconsistent semantics for the moment, would T{1,:} returning a comma-separated-list of char be more useful than returning a string array?
Bruno Luong
Bruno Luong on 1 Sep 2023
@Simon "x{:} and T{1,:}, have two different semantic meaning."
Agree.
It seems to me table overloads heavily subasgn and subsref especially for {} and it's done internally.
I tried long ago do overload {} with my own class but it won't be able to make it works.
Rik
Rik on 1 Sep 2023
It sounds like we agree. This thread is for changes that would break compatibility. What you're suggesting is keeping the technical behavior the same, but improving the documentation. The threads I linked are more suited for that. I would like to show support for your suggestion by giving you an up-vote, but I don't feel this thread is the most suitable location.
I know that Mathworks staff is monitoring these threads and do consider the comments and votes when deciding what to do with a suggestion. Posting in the correct thread helps giving your suggestion the correct exposure.
Simon
Simon on 1 Sep 2023
I don't mean that Matlab should change the meanings of x{:} and T{1,:}. Just a more comprehensive tutorial would lessn a greate degree of headache. Better documentation oriented toward beginners go quite well with 'What should be in next generation', I think. But it's all personal opinion.
Rik
Rik on 1 Sep 2023
How exactly would this break compatibility? These things sound like new features, but not really things that will prevent older versions from running the same code.
This sound more suited to a missing feature threads (#1 #2): features that you whish Matlab would have had.
Feel free to move your answer (by posting it there and deleting it here; moving answers between threads is work in progress).
Yevgeniy Gorbachev
Yevgeniy Gorbachev on 29 Aug 2023
  1. Being dynamically typed makes large programs irritating to develop and makes the language slower (JIT needs some time to do its thing); I think a compiled statically typed MATLAB would be amazing (yes, I know the arguments block is a thing, but that's still checked at runtime)
  2. In-editor vim emulation (IdeaVim is the ideal case)
Yevgeniy Gorbachev
Yevgeniy Gorbachev on 30 Aug 2023
Coder - MATLAB Coder isn't what I mean. I would like MATLAB to be statically typed while retaining much of the neat math syntax that makes it pleasing to use.
Static typing - Nothing I've used in C requires that level of specificity for mathematical operations, casting is fine, and even implicitly widening ints to floats, or singles to doubles, is totally ok by me. I am thinking mostly about the "MATLAB Compiler" inn the sense of checking that e.g. a class I'm making implements an interface, and making sure all the code is type-valid without needing to run (for example) most of an expensive simulation.
Walter Roberson
Walter Roberson on 29 Aug 2023
Static typing gets in the way of rapid software development, which is the purpose of MATLAB.
Consider for example,
function C = myplus(A, B)
C = A + B;
end
In MATLAB, this one function is compatible with any datatypes for which the plus() method is defined. In a statically typed language, you need separate
function single C = myplus_single_single(single A, single B)
C = A + B;
end
function double C = myplus_single_double(single A, double B)
C = double(A) + B;
end
function double C = myplus_double_single(double A, single B)
C = A + double(B);
end
function uint8 C = myplus_uint8_double(uint8 A, double B)
C = uint8( double(A) + B);
end
and so on -- every possible combination must be named and defined... unless you have a template system.
If you do have a template system, you need something like
function <$superiortype(<$type_A>,<$type_B>)> C = myplus(<?type_A> A, <?type_B> B)
C = cast(cast(A, `$superiortype(<$type_A>,<$type_B>`) + cast(B,`$superiortype(<$type_A>,<$type_B>`), `$inferiortype(<$type_A>,<$type_B>`);
end
with special syntax to grab the types of input arguments, and functions to be able to calculate which type should be prompted to or demoted to, and special syntax to convert computed type names to parameter so as to be able to pass to functions such as cast() . Unless, that is, you want to introduce a semantic type cast instead of a function type cast...
Walter Roberson
Walter Roberson on 29 Aug 2023
MATLAB Coder is compiled statically typed MATLAB.
Sulaymon Eshkabilov
Sulaymon Eshkabilov on 29 Aug 2023
I have a couple of wishlists:
# 1. Machine Learning applications should have a few features to extract/store the simulation results (numerical data) in the workspace: (1) Regression data (target vs. predicted values), R (correlation coefficient values), Mean Squared Error values (Training, Test, Validation and overall).
# 2. Chord diagram function (a 3rd party function posted on mathworks.com)
Sulaymon Eshkabilov
Sulaymon Eshkabilov on 29 Aug 2023
Neural Network App, I am talking about. Thank you - Steven.
Steven Lord
Steven Lord on 29 Aug 2023
Is there a specific Machine Learning app you have in mind? Looking at the list of Statistics and Machine Learning Toolbox apps, I haven't used them extensively but based on the pictures at least Classification Learner and Regression Learning have Export sections on their toolstrips.
Rik