Const (probably revisited)

13 views (last 30 days)
Jasper van Casteren
Jasper van Casteren on 12 Apr 2019
Commented: Walter Roberson on 15 Apr 2019
In professional programming languages like C or C++, you can define constants NOT AS PARAMETERS, but as compiler directives. These constants work like "replace all occurrences of "PI" by 3.14 and then start the program". This means that you can define miriades of constants, making your code much more transparant and robust, without any consequences to the execution speed. During execution, there are no parameters created, no memory allocation, no parameters passed, no m-files parsed, but all constants have been replaced by values prior to execution.
That is what a programming language should look like. Using classes with constants is hopelessly complicated, affects your execution speed and requires memory allocation for constants during execution. That is plain silly.
MATLAB should implement constants in the professional sense. It can't be too hard to do: a const clause for primitives variables alone (double, unit32, char, etc.) would already be a great help to programming matlab. Calling an m-file with const would then not mean to create these variables, but to replace all "const variable" names by the const value during the parsing of the code. Why is this not available?
Personally I would not mind, to avoid collision with non-const variables, to state that const variable names should start with a "0" or a "#" or a "!". No non-const variable may have that, so no collisions.
  1 Comment
Stephen23
Stephen23 on 12 Apr 2019
"In professional programming languages..."
I work with MATLAB (and other languages) professionally. I know others who do too. Does that make MATLAB a "professional programming language", or are you using some special definition that conveniently excludes anyone who actually works professionally with MATLAB?
"...without any consequences to the execution speed"
Just pass parameters as variables.
I very much doubt that passing variables is a significant bottleneck in your MATLAB code.
"During execution, there are no parameters created, no memory allocation, no parameters passed, no m-files parsed,"
What you describe is a precompiled, statically-typed language with compile-time memory allocation. MATLAB is a dynamically-typed high-level interpreted language which uses JIT compilation (and it is not the only one around). You appear to be arguing that interpreted languages should not exist: lets burn them!
"Using classes with constants is hopelessly complicated,...That is plain silly."
I agree: simply define them once and pass the parameters in an array (numeric, cell, structure, etc): this is much simpler and does not cause any duplication of data in memory.

Sign in to comment.

Answers (3)

Walter Roberson
Walter Roberson on 12 Apr 2019
It has nothing to do with "professional". What you are talking about is compile time constants, but MATLAB is not a compiler.
It is not known that MATLAB uses memoryless constants even for literals. F(x)+1 is defined as plus(F(x), 1) with the correct version of plus to call not known until type resolution is done on the return result of F(x). It could be a user defined function; it could be mex call; it could be a built-in; it could be Mathworks .m or .p or .slx. For user functions and mex calls and m and p files, literals need to be assigned memory. For slx a literal might hypothetically not need memory but that would depend on the exact blocks needed. So much analysis and predictions would be needed with regard to slx that it would be much more efficient to just always allocate memory for the literal at the boundary.
Meanwhile in order for built-in to be able to avoid allocating memory for literals, there would have to be 2^N version implemented, where N is the number of parameters....

Jasper van Casteren
Jasper van Casteren on 12 Apr 2019
You talk about the run type versions of methods, or run time descisions on resulo variable types. But I think that that is not the problem, and I do not think you need to go into "2^N" to solve this.
Let me explain my problem. I am working with models that have many variables, stored in arrays for speed (and, I must amit, for historical reasons). I need dozens of constants to know what is in which column. I can't use structs, as I cannot take out a multi-column part of a struct or do multu-column maths. I am turning to tables, by that will take some time (if ever), and tables seem to be slower than arrays. Not all math is as easy with tables as with arrays.
So, I actually like arrays in some cases, and I have a lot of multi-dimensional arrays. When I start using literal column and row indices, I will crash my project in a few weeks, and be a shamefull unemployed quickly thereafter. I need to use constants to adress specific rows and columns.
So, what I do now is to create flat m-files (not functions), and include the right ones in any m-file that needs these constants. That mensa opening m-files time after time (well, it is a few hundred thousand times actually), and I am suspecting that that is eating run-time. I could use a class with constants, but I do not care that my constants are not constant. I am wise enough not to change them (although it would be nice if they were protected).
I do not want to solve run-time typing, I simply want a method that replaces "MyArray(SPEED, COLOR, :) = X" by "MyArray(53,16,:) = X", without me knowing it, and without the need to allocate or pass "SPEED = 53; COLOR=16;".
I do not see any worries about 2^N there. It seems a simple parser feature. And that can also be done with a interpreter.
Any suggestions?
  2 Comments
Walter Roberson
Walter Roberson on 12 Apr 2019
Edited: Walter Roberson on 12 Apr 2019
Your posts require that memory not be allocated for the constants. Consider the expression A+SPEED where SPEED is one of the constants. In a setup where memory is allocated for literals and constants then this is implemented by one built-in method per fundamental type, such as @uint8/plus, that accepts two arguments as allocated memory and adds them. But in your proposal it would not be permitted to allocate memory for SPEED so there would need to be four methods instead: @uint8/plus(memory, memory), @uint8/plus(memory, constant), @uint8/plus(constant, memory), @uint8/plus(constant, constant).
Remember that in MATLAB, indexing is a function call, subsref() or subsasgn(). Those functions are passed cell arrays of indices because even for numeric arrays the bare colon operator is passed as ':' (and logicals and characters are valid indices). The No Memory requirement would require a fundamental change to indexing because currently all of the indices have allocated memory but suddenly now that would not be permitted for the "professional" constants.
MyArray(53) is currently handled by allocating memory for an unnamed numeric variable withddescriptor "type double sized 1, 1, local, not complex" and passing that location into the appropriate place in a cell in subsref. The *only* difference compared to a named variable SPEED=53; MyArray(SPEED) is lack of a symbol table entry "SPEED" -> descriptor. MyArray(literal) is not processed differently than MyArray(variable) other than there being a name associated with the descriptor. Your proposal would require treating your professional constants differently, not being permitted to construct the memory with descriptor node for them.
You might be thinking "Okay, when the professional constant is used then the value associated with the constant can be inserted into an appropriate descriptor and passed just as if a literal had been written." But then you have allocated memory to hold it, and if you ever refer to that constant twice then it would be more memory efficient to allocate memory only once and put it in the symbol table... as is done right now.
I can hear the "Oh, but optimization!" in the background. And... It turns out that MATLAB has a built in optimization layer called JIT that keeps track of locations and knows not to bother searching in the symbol table again provided that the variable was not cleared...
Stephen23
Stephen23 on 12 Apr 2019
Edited: Stephen23 on 12 Apr 2019
"And that can also be done with a interpreter."
Sure, and MATLAB does just that: simply pass your parameters as variable/s and MATLAB's JIT engine does not make copies of them (as long as you do not change them inside other workspaces). The simple MATLAB solution would be to use one single structure and pass that:
"Any suggestions?"
Stop trying to write MATLAB code as if it was C++.

Sign in to comment.


Jasper van Casteren
Jasper van Casteren on 15 Apr 2019
OK, I apologize for the "professional". I have been programming C++ for 10 years, professionally, but I am using Matlab now for 5 years, also professionally.
I like my code clean and tidy. Our project is about 5 MB of code, about 500 m-files, don't know how many lines. We compile various applications from this library. Finding a good solution for manageing constants is instrumental for code quality.
I understand that the best practice here is by creating a class with constants, programming everything related to them (units, descriptions, reporting, etc.) in the class. Then I need to instantiate all classes that my subscripts might need in the main script/app, and pass the objects to every script that either needs the constants itself, or that has sub- (sub-, sub-) scripts that might need them, because I need to pass down the const-objects down the hierarchical chain so that also the "leaf" scripts can access the constants. If I change/create a script that needs constants that I do not pass yet, then I need to work myself up the chain to make sure that alle upper scripts will pass the right const classes, unless I use a single class for all possible consts. I need to adapt to a way of working that always includes the const classes to all my scripts. That could work.
Ok, I will test this and see how it holds up. Seems a better method than to "include" const scripts. But I cannot shake the feeling that this is less "clean" than I would prefer. It feels like working around a missing feature. No problem, can do, but would it not be an idea for matlab to have a feature that automatically passes such a const class, like object methods get automatically passed the object that they work on? Declare the const class at the main script, and have it automatically in all called scripts?
Thank you for your help, and I again apologize for a bit of frustration in my first message. Not profesional . . . .
  1 Comment
Walter Roberson
Walter Roberson on 15 Apr 2019
Perhaps I have missed something but it looks to me as if you are reinventing databases, or tables, or object methods. that is, you can have a method named SPEED that returns a particular column of the stored object. Or just a general function named SPEED that returns a particular column of its input under the assumption that all inputs have the same layout.

Sign in to comment.

Categories

Find more on Platform and License in Help Center and File Exchange

Tags

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!