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
Rik on 29 Aug 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.
dim-ask
dim-ask on 28 Aug 2023
Using arrays of string by default to anything that right now is cellstr by default. For example, string columns with readtable, some_table.Properties.VariableNames, etc. Apart from it saving me a lot of time having to adjust things myself every time, it would help novice matlab users who may not know stuff like how bad long cellstr's are (huuuuge overhead), and have to learn this the hard way (like I had). Even put one of these "not recomended" warnings if somebody uses readtable opting for cellstr as default for character columns. It would require adjusting older code accordingly, but it would save a lot more. Maybe put a warning in general whenever somebody defines or uses a 1-d cellstr that is above some length.
Simon
Simon on 1 Sep 2023
I had the same headache and am still having it. I recently modify my readtable opts to set all variables as "string" in data-extraction step. This seems to reduce error-pronenss in this step and to speed up looping algorithm. However, when I want to store the extracted tables, I would change group variables to 'categorical' to reduce storage size. String data would occupy much larger space in the hard drive.
I also very much like Matlab to default some_table.Properties.VariableNames to be of string array. Somehow, Matlab is inconsistent in defaulting things as cell array or string array. That kind of inconstency is the biggest slow-down for me.
Simon
Simon on 28 Aug 2023
Better folder path utility. Python's pathlib is powerful and very intuitive to use. Matlab's dir is cumbersome. To be the problem lies in dir use structure and comma separated list, which I don't feel at home with.
Rik
Rik on 29 Aug 2023
The point of my comment was also that someone could write a function pathlib that would replicate the Python behavior, without impacting currently existing code.
Walter Roberson
Walter Roberson on 28 Aug 2023
There is a fundamental difference between the MATLAB dir() approach and the python pathlib approach.
The MATLAB dir() approach immediately returns information about all of the matching files. The python pathlib approach instead gives you an object that you have to iterate over, asking each time for the details you want.
As indexing is relatively efficient but making repeated system calls is less efficient, the MATLAB approach is faster, requiring fewer system resources.
Once it is understood that MATLAB is returning all of the information at the same time, then there are only a small number of representations available for the information:
  • dir() can return a struct array, like it does now
  • dir() could hypothetically return a 2D cell array in which you "just had to know" which offset corresponded to which information. This would use more memory than a struct array and would be notably less user-friendly
  • dir() could hypothetically return a table() of information. From a user experience perspective this might not have been a bad choice. But in practice, table() operations are slower than struct array operations. And in practice tables() were not introduced until R2013b, long after dir() had been designed
  • dir() could hypothetically return an object array with a bunch of properties and methods. Comma seperated lists would probably end up being used internally, but I suppose could have been hidden from the user. In practice though, object operations are slower than struct operations.
The python operations available for pathlib look over-engineered to me -- a lot of operations that should probably have been string operations.
Rik
Rik on 28 Aug 2023
How exactly would this break compatibilty with the current code base? At first glance I don't see much difference beyond the syntactic differences between Python and Matlab.
Jason
Jason on 6 Jul 2023
I'm not deep into how code "should" be written, but more of a user who realizes theoretical papers in matlab and python. So just want to frame my comments in that light. I also want to give kuddos to mathworks as I can't get away from MATLAB. The tool is extremely well done and well supported.
I would like to see the following:
- lose the brackets when assigning output arguments and make carrage returns end lines.
Example:
x, y = myFunc(temp, temp2)
- Add a way to do bulk comments
%* these are comments
still commenting *%
- add functionality to take highlighted code and immediately turn it into a function
- make it simpler to make code with variable arguements. For example, we have several ways right now to do name-value pairs. One of which cannot do autofill and one that can. Having the default values within the function definition is nice in python and somehow that one does auto filling without any extra code like is required by matlab. When I say autofill, I mean you hit tab in the argument spot and it gives you a list of options.
-native arduino or generic microcontroller support
-native AI code writing support like co-pilot
-improve the symbolic toolbox. Mathmatica kills you guys here.
Jason
Jason on 7 Jul 2023
Thank you for your attention to my comments and bringing some MATLAB features to my attention.
When I said "Native Arduino Support" my intent was to be able to code arduino in C in one file of the MATLAB IDE and be able to do the register read/writes in another file in the matlab IDE while executing some scripts on the data. After reading the Arduino documentation, it seems MATLAB already has or nearly has what I was asking for!
For the brackets, it was a comment on the features of python that I preferred over MATLAB. I liked not neededing to end every line with a semicolon, not needing to add brackets in the outputs, and not needing end statements for loops. For me, it would simply be a quality of life improvement.
Rik
Rik on 7 Jul 2023
In summary, only your suggestion of leaving out the brackets would actually break compatibility. Can you explain why you would like to see this change?
Walter Roberson
Walter Roberson on 6 Jul 2023
improve the symbolic toolbox
Mathworks has been working for several years to remove internal functions that it inherited with MuPAD, trying to get further and further away from user access to MuPAD, and meanwhile adding a few MATLAB-level functions that replace some of the key pieces.
Now, the more details of the symbolic engine that Mathworks hides, then the more potential there is for doing wholesale replacement or rewriting of the symbolic engine, as long as the replacement can satisfy what is left of the defined MATLAB-level functions. You should not expect a future of Mathworks providing MATLAB-level functions to do tasks such as setting the DOMAIN slots of overloaded symbolic functions --- but enhanced pattern matching in mapSymType is not out of the question.
Whether Mathworks will ever do the work to make the Symbolic Engine thread-safe (to improve performance by operating on multiple cores) is a big unknown to me. I'm not hearing anything about that possibility, but also not hearing a "No" on that possibility. My gut feeling is that at this point a more-or-less replacement of the internals of the symbolic engine is more likely than a tune-up, but I really don't know.
Walter Roberson
Walter Roberson on 6 Jul 2023
native arduino or generic microcontroller support
Could you expand on that?
aurdino() is already supported by installing a (free) add-on package.
There is absolutely no chance that MATLAB or compiled MATLAB executables itself will ever execute on arduino: the memory limitations for arduino are so severe that it is Not Going To Happen. (Raspberry Pi has a non-zero chance at some future point.)
Simulink can already target Arduino if the appropriate (free) add-on package is installed.
What is currently "missing" is that MATLAB Coder does not have a native target of "Arduino" if I recall correctly -- just of whatever ARM (or as appropriate) chip. (MATLAB Coder does have native support for Raspberry Pi)
Walter Roberson
Walter Roberson on 6 Jul 2023
There are some minor exceptions to the block comments having to appear alone on a line; see https://www.mathworks.com/matlabcentral/answers/92498-can-i-comment-a-block-of-lines-in-an-matlab-file-using-as-i-can-in-c#comment_1451187
Steven Lord
Steven Lord on 6 Jul 2023
lose the brackets when assigning output arguments and make carrage returns end lines.
That would be ambiguous if a variable named x is present in the workspace or there's a function named x that can be called with no output arguments. Should that line call myFunc with two output arguments and assign those to the variables x and y? Or should it display the value of the variable x / the value returned by the x function when called with no outputs then call myFunc with one output and assign that output to the variable y?
- Add a way to do bulk comments
This is possible and has been for several years. Use the block comment operators %{ and %}. These do need to appear alone on a line, though. See this documentation page for more information.
add functionality to take highlighted code and immediately turn it into a function
From the Editor (see the Refactor Code section) or from the Command History? Okay, the latter doesn't technically satisfy your request since it creates a script rather than a function. But all you have to add is the function declaration line.
improve the symbolic toolbox. Mathmatica kills you guys here.
If you have specific suggestions for what Mathematica does better than the Symbolic Math Toolbox, please send them to Technical Support as enhancement requests.
Walter Roberson
Walter Roberson on 6 Jul 2023
Bulk comments: %{ at the beginning of a line, an %} at the beginning of a line to terminate
Andrew Janke
Andrew Janke on 30 Sep 2022
Cool, thanks!
Rik
Rik on 30 Sep 2022
I just added this thread to the list of 'where to post' discussion threads. At 41 answers as of today it is getting pretty large already, so I think a second thread will soon be a good idea.
men8th
men8th on 30 Sep 2022
My goodness, the IDE can be annoying sometimes. What's missing...
  1. I use the editor undocked. Please can we have the capability to display a watchlist of variables in a panel in the editor. Also, you should be able to right click on a watched variable and set a breakpoint to halt when the value changes or some user specified conditional relating to that variable is satisfied. Basically, please can we have the MS Visual Studio watchlist.
  2. The call stack display in the editor is absolutely useless if the call stack is deep, which it often is with OOP. Can't we have this as a proper list? Having to open and re-open a tiny dropdown menu is hopeless. The horizontal list that you get with the live editor is also useless if the stack is deep. It needs to be a list which you can pin open, and where you click on it to move the stack frame. I routinely resort to using dbstack at the command line to get round this, but then clicking the output from dbstack doesn't move the stack frame so it is only half useful. Also, because the output from dbstack moves off the screen when you enter other commands and has to be regenerated to stay up-to-date, it's hard to mentally "keep your finger in the pages of the book where you want to go back to" when you are concentrating hard.
  3. Finally, and this is a big ask I'm sure, can we have the capability to drag the instruction pointer during debugging and also modify code on the fly when debugging.
Turlough Hughes
Turlough Hughes on 23 Aug 2022
When using the debugger, I would love to have a button to Step (run the next line) and display output regardless of the ; being there or not.
Image Analyst
Image Analyst on 23 Aug 2022
What I do in cases like that is to highlight the line up to the semicolon and then hit F9 to execute it.
Gregory Warnes
Gregory Warnes on 21 Jun 2022
Allow (prefer?) use of square brackets for indexing into arrays:
A[1:10,1:10]
dim-ask
dim-ask on 28 Aug 2023
Second this. I have tried Julia that uses brackets, and it makes soooo much more sense and code is soooooo much more clearer, just because of this. Taking a mental step (which may not be trivial actually) to mentally parse if a certain line is about a function call or an array is unnecessary, and makes things more obscure.
I think saying that "indexing an array is a function call" is a bit of an overstretch in this situation. Even if it makes sense to see it like this, then it would make sense to write array.index(n) rather than array(n) , because the latter would imply that array is a function itself, not a method over array .
This would also make stuff like function_that_outputs_an_array(10)[4] possible, while now we often have to take detours for that.
Andrew Janke
Andrew Janke on 22 Jun 2022
> I can't vistually tell if someObjectName(1,3) is a function call or index into an array.
This is an intentional part of the design of the Matlab language. Not only can't you tell visually, you can't tell by parsing or analyzing the code either: it's actually indeterminate until run time, and depends on whether someObjectName refers to a regular value or is the name of a function or is a callable object like a function handle or an object that implements subsref in your execution environment. It's called the "uniform access principle", though I don't see that term used much. The idea is that you can write some client code that indexes into someObjectName, and then the code defining someObjectName can supply it as either a function or a value array, without close coupling to which it is. It's a sort of duck typing. Mathematically speaking, an array basically is a function which maps integer-valued inputs to the values in those elements of the array.
I almost never see this flexibility used in practice, though, so I don't know how useful it is.
Similary, and this one I actually see used, you might have a class Foo that defines a property blah, which exposes an array into which callers acces. At some point you might want to generate that value dynamically or through a more complex process. You can change blah from a property to a method, or vice versa, and existing client code will continue to work without change (if you do it right). If array indexing and function calls had different syntax, this would be a breaking change and all your clients would have to change their code (or you would have to just iimplement it as a method wrapping the array in the first place, for future-proofing).
If you switch, there is a minor issue with array concatenation syntax: given [x [1]], does that concatenate x with a numeric array, or index in to x? Seems like a degenerate case that could be resolved by making the space between the identifier and brackets significant, or requiring you to use "," or ";" in the concatenation to resolve the ambiguity.
I have no opinion on which way is actually better. I might prefer the "[ ]" version, because you don't have to hold down shift to produce "[ ]" but you do for "( )", and I am a lazy typist: that's mostly why I use single-quoted char literals instead of double-quoted string literals in most places.
Walter Roberson
Walter Roberson on 22 Jun 2022
I note that R and Python are newer languages than MATLAB, so it could be argued that they should change.
Walter Roberson
Walter Roberson on 21 Jun 2022
() and [] and . (dot) all invoke methods of their class. Indexing of an array is a function call.
As an implementation optimization, when the class is one of the built-in numeric-like classes, the execution engine can take shortcuts instead of a full method call. But that is an optimization.
Gregory Warnes
Gregory Warnes on 21 Jun 2022
Yes, in fact R does this now.
My primary interest is to reduce the challenge of switching between languages. I regularly use Python, R and Matlab and the thing that bites me most often is that Matlab uses () for both indexing and function calls, for two reasons:
  1. Confusion: I can't vistually tell if someObjectName(1,3) is a function call or index into an array.
  2. Muscle memory: In the other languates, indexing always uses [ ] , so I end frequently up typing the square brackets and creating syntax errors.
Walter Roberson
Walter Roberson on 21 Jun 2022
If this were done, then hypothetically Mathworks could declare that in the case where a value were assigned to a name that is a function, then if [] were used that the reference would be to the variable, but if () were used then the function would be invoked.
This would reduce the problem of people assigning a value to variable named "sum"
Rik
Rik on 21 Jun 2022
Why exactly? I'm just curious. This seems simply a matter of taste. What would be the benefit?
Gregory Warnes
Gregory Warnes on 21 Jun 2022
Documentation on how to change the default size of figures in Live Scripts.
Gregory Warnes
Gregory Warnes on 12 May 2022
Extend Find/Replace regular expression support to include substitution of matched elements from 'find' into 'replace', so that one can do things like:
Find: (call\(\w+ *, \w+, *)(\w+ *))
Repace: \1uint16(\2))
and accomplish the transformation
call(a, b, c)
call(d, e, f)
to
call(a, b, uint16(c))
call(d, e, uint16(f))
Walter Roberson
Walter Roberson on 30 Sep 2022
@Gregory Warnes I am not clear as to what your desired output is?
S = string('%#codegen') + newline + ...
'coder.extrinsic("disp");' + newline + ...
'coder.extrinsic("warning");'
S =
"%#codegen coder.extrinsic("disp"); coder.extrinsic("warning");"
regexprep(S, 'extrinsic\("(\w+)")', 'extrinsic($1)')
ans =
"%#codegen coder.extrinsic(disp); coder.extrinsic(warning);"
Walter Roberson
Walter Roberson on 30 Sep 2022
S = 'disp("hello"); call(a, b, c); disp("bye");'
S = 'disp("hello"); call(a, b, c); disp("bye");'
regexprep(S, '(call\(\w+ *, \w+, *)(\w+ *)', '$1uint16($2)')
ans = 'disp("hello"); call(a, b, uint16(c)); disp("bye");'
Gregory Warnes
Gregory Warnes on 12 May 2022
Not in Matlab Online 2021a.
For example, with the original code:
function obj = bladeRF_new()
%#codegen
coder.extrinsic("disp");
coder.extrinsic("warning");
obj = bladeRF();
end % function
and using
Find: extrinsic\(("\w+")\)
Replace: extrinsict\( $1 \)
yields:
function obj = foo_new()
%#codegen
coder.extrinsict\( $1 \);
coder.extrinsict\( $1 \);
obj = foo();
end % function
(I also tried \1 and \$1).
Walter Roberson
Walter Roberson on 12 May 2022
This is already supported using $N instead of \N for numeric N
Gregory Warnes
Gregory Warnes on 11 May 2022
Please unify/combine the Matlab coder (`ceval` and friends) and C API (`calllib` and friends) to remove the need to double-code all C calls in code that needs to be run by the interpeter and processed by coder.
For example, I currently have a device driver where every c library call looks like:
if coder.target("MATLAB")
[status, ~, val] = calllib( ...
'libFoo', ...
'foo_get_correction', ...
obj.foo.device, ...
foo.str2ch(obj.module), ...
'FOO_ENUM_STRING', ...
val ...
);
else
status = int32(0);
val = int16(0);
enum_val = foo_enuminfo('foo_correction').FOO_CORR_GAIN;
status = coder.ceval( ...
'foo_get_correction', ...
obj.foo.device, ...
foo.str2ch(obj.module), ...
enum_val, ...
val ...
);
end;
Unable to resolve the name 'obj.foo.device'.
Even bettter, would be a tool that automatically generates a wrapper from a (well formed) C/C++ header file, that can be customized by the user, and that is compatible with both interpreded use (coder.target("MATLAB")) and compiled/embedded use (~coder.target("MATLAB")).
James Strieter
James Strieter on 25 Mar 2022
One thing that I love about the way MATLAB has evolved over the 20+ years I've been using it is the way you keep adding modern features while keeping the fast matrix operations. Beautiful plotting built in helps a lot too. Like a lot of other people, I've said, "I'll use Numpy because it's free," and then 8 hours later I'm like this would take 5 minutes in MATLAB. And then I do it in MATLAB and it's done. I love that. Here are my favorite features from other languages that could be added, probably without breaking anything:
  • Haskell's guards and list comprehensions,
  • Lazy containers,
  • LISP keywords,
  • LISP style maps, in which the :keyword-with-hyphens is also a function that retrieves data from an object,
  • Python's convention of defining ```__str__(self)``` to mean "This is what happens when you cast to a string," ```__int___``` for "This is what happens when you cast to an int," etc. Optional methods that support every kind of cast you could want.
  • More modern kinds of loops. ```for i in <arbitrary_container>``` for example. Whether the loop is executed in any particular order depends on whether the container has any kind of order, etc.
  • An API for defining language extensions. This would allow the community to experiment with new language features, making it cheaper & easier for Mathworks to see which language features gain traction. Mathworks would always have the option to include the most popular language extensions in a future release.
Andrew Janke
Andrew Janke on 26 Mar 2022
Oh, I totally forgot: In Matlab, iteration over a table array already is defined! A Matlab for loop is defined as iterating over the columns in a 2-D array. (That's why your sequences used in for loops generally need to be row vectors.) A Matlab table array is defined to be a 2-D array, of rows x variables. So a for loop will iterate over the variables of a table array, producing a 1-variable table as the iterator/index variable each time.
For example, this works:
tbl = array2table(magic(3))
for it = tbl
it
end
Producing:
it =
3×1 table
Var1
____
8
3
4
it =
3×1 table
Var2
____
1
5
9
[...]
I don't think that's a very useful behavior, but it is defined. :)
Andrew Janke
Andrew Janke on 25 Mar 2022
> Python's convention of defining ```__str__(self)``` to mean "This is what happens when you cast to a string,"
This is basically a thing now! Matlab classes can define an overidden string() method to define what happens when you cast that object to a string (even implicitly, as happens when assigning into a string array). Overriding disp() controls how the object is displayed at the command window. And in the most recent Matlab releases, there are now additional things you can override to provide finer-grained control of how the object is displayed in other contexts, such as when it is contained in a field of a composite type like a struct or cell and a more compact representation is required. See: https://www.mathworks.com/help/matlab/group_analysisopt.html
If you want a simpler string-representation API that works more like Python's str() and repr() functions, you can also hack that together in userland Matlab code and it'll work in many places, though not in some built-in Matlab display contexts. Here's a little prototype example: https://dispstr.janklab.net/
You can also define overridden int32(), uint32(), double() and similar methods to define what happens when your user-defined object is cast to various other Matlab types, including numerics.
Andrew Janke
Andrew Janke on 25 Mar 2022
A thought on tables specifically: From a SQL/relational algebra standpoint, and how it's done in Python, a table/dataframe is a container that holds a list of tuples (records or rows), and iterating over a table iterates over records, which are presented as something that looks in Matlab terms like a scalar struct array. That operation is kind of opposed to the array-oriented, vectorized (or "column-store") nature of (fast, idiomatic) Matlab code for data structures like this. I'm not sure that encouraging interation-oriented programming though convenience functions or syntax is necessarily a good idea for Matlab "containers" like this. I think we might want to lean more towards APIs that encourage the use or creation of vectorized or array-oriented operations, and push interation requirements out to the user-defined code you want to apply to tables and similar containers.
Walter Roberson
Walter Roberson on 25 Mar 2022
LISP keywords,
Switching the editor to be emacs ??
CAR and CDR as alternative functions instead of indexing?
Or do you mean that you would like MATLAB to support, for example,
show_members :a p :b 'q :c 2
as an alternative syntax for
show_members( a=p, b='q', c=2 )
complete with it being the value of p that would be passed in to show_members, even though at present MATLAB's command-function equivalence would currently treat that call as
show_members(':a', 'p', ':b', '''q', ':c', '2')
in which all of the elements are treated as character vectors ?
... I think there would be conflicts with the existing use of : as the range operator, if you are going to start interpolating values from text...
Walter Roberson
Walter Roberson on 25 Mar 2022
Questions...
A table() is a container. What would it mean to for i in MyTable ?
A hggroup() is a container. What would it mean to for i in a hggroup ?
A scalar struct is a container. Would for i in the scalar struct mean to iterate over the fields? Giving you the content of the fields? Giving you a scalar struct that contains just the one field?
A nonscalar struct is a container. Would for i in the nonscalar struct mean to iterate over the array elements (giving you one full struct at a time), or would it mean to iterate over the fields? Giving you a nonscalar struct that contains just the one field? Giving you a cell array of the contents of the field?
Bjorn Gustavsson
Bjorn Gustavsson on 24 Mar 2022
Replace the pinv function with a function tikhonov that defaults to the Moore-Penrose generalized inverse without regularization-parameter, zeroth-order Tikhonov with a second scalar input for the regularization-parameter and a L-th-"order" Tikhonov-regularization with a third-order L-matrix.
The argument for this compatibility-break is that it would force users of pinv to think about what they've done and why, and let them consider the more general and preferable regularized solutions than the M-P inverse.
CFDesign
CFDesign on 18 Feb 2022
Clean inconsistencies, or counter-intuitive behaviours.
1.- [dr,dc] = size(data)
2.- dsize = size(data)
3.- [dr,dc] = dsize
1) works, but 2 and 3, wich is intuitively same, do not work.
Improve consistency in general.
Walter Roberson
Walter Roberson on 18 Feb 2022
For consistency with the first call, already said to work, [dr, dc] = dsize2 would have to mean dr = dsize2(1), dc = prod(dsize2(2:end))
Steven Lord
Steven Lord on 18 Feb 2022
To give a more concrete example of what Rik and Jan pointed out:
A = ones(2, 3, 4);
% Option 1
[dr, dc] = size(A) % Yes, dc being 12 is the correct and documented behavior
dr = 2
dc = 12
% Option 2
dsize = size(A)
dsize = 1×3
2 3 4
Given this dsize vector, what exactly would you expect dr and dc to be in the Option 3 case and what rules did you apply to decide on those expected values? What if dsize had been created not by a call to size but explicitly?
dsize2 = [4 8 15 16 23 42]
What would you expect dr and dc to be if the code [dr, dc] = dsize2 were executed?
Jan
Jan on 18 Feb 2022
This is the documented behaviour of the size() function. Many codes rely on this feature, which is implemented in the mex level also by mxGetN().
This is a useful feature, if the size of the first dimension matters and all following dimensions are treated as "slices". Therefore the special output of size with 2 output arguments was introduced on purpose and you cannot change it anymore.
As soon, as 1 output is replied by size, it contains all dimensions and there is no consistent way to solve "[dr,dc] = dsize".
If you want to get the sizes of the first 2 dimensions, size(X, [1,2]) is intuitive.
Rik
Rik on 18 Feb 2022
You mean 2 followed by 3? You can split a vector into 2 parts if you want.
What would be the expected behavior if dsize is not exactly 2 elements? Should one of the variables be empty?
Also can you explain what would make your suggested syntax more consistent? I don't really see why it is inconsistent. Maybe I'm set in my ways and don't see the quirk you see. Can you provide a bit more context about what this would solve?
Tobias Held
Tobias Held on 2 Feb 2022
A small but handy function that allows when in workspace to press a letter and automatically highlight the variable with this first letter.
Rik
Rik on 18 Feb 2022
This wouldn't break compatibility as far as I can see. Feel free to cross-post this here (and/or submit a feature request).