www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How often I should be using const? Is it useless/overrated?

reply thebluepandabear <therealbluepandabear protonmail.com> writes:
A question I have been thinking about whilst using D is how often 
I should be using const.

Many people claim that all variables should be const by default, 
but whether or not it is really needed is debatable and 
oftentimes making everything const could cause readability issues 
and make the code more complex.

I also wonder how important const really is, like 99% of the time 
you will know when your variable will be changed, and even when a 
variable changes it's not like it is the end of the world.

Also, there is no real end to how much variables can be const. 
Oftentimes -- interestingly -- in popular repos I don't even see 
const being used, this is what confuses me.

As a newcomer, I'd be interested in hearing everyones thoughts.
Nov 18 2022
next sibling parent thebluepandabear <therealbluepandabear protonmail.com> writes:
On Friday, 18 November 2022 at 11:51:42 UTC, thebluepandabear 
wrote:
 A question I have been thinking about whilst using D is how 
 often I should be using const.

 Many people claim that all variables should be const by 
 default, but whether or not it is really needed is debatable 
 and oftentimes making everything const could cause readability 
 issues and make the code more complex.

 I also wonder how important const really is, like 99% of the 
 time you will know when your variable will be changed, and even 
 when a variable changes it's not like it is the end of the 
 world.

 Also, there is no real end to how much variables can be const. 
 Oftentimes -- interestingly -- in popular repos I don't even 
 see const being used, this is what confuses me.

 As a newcomer, I'd be interested in hearing everyones thoughts.
Some languages like Kotlin and Rust are const by default, but for languages that are not like D I have always wondered how often you should use const.
Nov 18 2022
prev sibling next sibling parent Dennis <dkorpel gmail.com> writes:
On Friday, 18 November 2022 at 11:51:42 UTC, thebluepandabear 
wrote:
 A question I have been thinking about whilst using D is how 
 often I should be using const.
This should be a good read for you: [Is there any real reason to use "const"?](https://forum.dlang.org/post/dkkxcibwdsndbckonhav forum.dlang.org)
Nov 18 2022
prev sibling next sibling parent reply H. S. Teoh <hsteoh qfbox.info> writes:
On Fri, Nov 18, 2022 at 11:51:42AM +0000, thebluepandabear via 
Digitalmars-d-learn wrote:
 A question I have been thinking about whilst using D is how 
 often I
 should be using const.
You should use it as often as you need to use it, and no more. If you don't need to use it, don't use it.
 Many people claim that all variables should be const by 
 default, but
 whether or not it is really needed is debatable and oftentimes 
 making
 everything const could cause readability issues and make the 
 code more
 complex.
You're looking at it the wrong way. The kind of issues having const would solve is like when your function takes parameters x, y, z, and somewhere deep in the function you see the expression `x + y*z`. If x, y, and z are const, then you immediately know what the value of this expression is. However, if they were not, then you'd have to trace through all of the preceding code to figure out whether their values have changed, and how they have changed. The former makes the code easier to understand, the latter adds complexity to understanding the code. Now if you have a variable that's expected to change a lot, like an accumulator of some complex calculation, then it makes no sense to make it const. Just modify it; you already have to understand most of the code to figure out how the value is derived anyway, so having fewer variables would actually make it easier to understand. In this case, using const is just counterproductive. IOW, if const makes your code easier to understand and maintain, then go for it. If you're finding that you have to jump through hoops in order to make your variables const, then probably it's *not* a suitable usage in that case.
 I also wonder how important const really is, like 99% of the 
 time you
 will know when your variable will be changed, and even when a 
 variable
 changes it's not like it is the end of the world.
It totally *can* be the end of the world, if your variable is controlling the launch of nuclear missiles, for example. :-P Having a variable change when you don't expect it to -- that's a frequent source of bugs and hard-to-understand code. Again I say, it depends on what it's being used for. If it's used to hold a logically fixed value (e.g., function argument passed from the caller that logically doesn't change) then you want to use const. But if you're using it to hold a temporary value that's expected to change, then what's the point of jumping through hoops just so you can brag "look, ma! my variables are all const!"?
 Also, there is no real end to how much variables can be const.
 Oftentimes -- interestingly -- in popular repos I don't even 
 see const
 being used, this is what confuses me.
[...] Because, honestly, const in D is a pain. The reason is that D's const, unlike const in C or C++, is transitive, meaning that if some object X is const, then everything X refers to is also automatically const. OT1H this is wonderful: this means the compiler can actually make guarantees about const and enforce it. You cannot just cast it away willy-nilly without invoking UB, so the compiler can make optimizations based on the assumption that some value never changes. OTOH the fact that it's transitive means that even if you have one tiny bit of data 10 hops down the line that you want to modify, you can't do it. This greatly narrows the applicability of const in D. It's physical const, and cannot be made logical const. IME, const in D is mostly applicable to what I call "leaf node" data structures: low-level structures where you're mostly dealing directly with the underlying data or maybe 1-2 levels of abstraction away from the physical data. Once you get past that to higher level code, const quickly becomes a giant pain to work with. You cannot, for example, lazy-initialize const data -- because that means you have to modify it after the reference is already initialized, which is UB. You cannot cache data -- because you need to initialize the data when it's referenced for the first time, and you need to set a flag to indicate that the data is cached so that you don't have to load it again. There are ways of working around this, but they are dirty and annoying to use. In my own code, I rarely bother with const, except for the lowest levels of code: modules that don't depend on anything else, so the scope is easier to control and the number of situations to support is limited enough that workarounds don't generate exponential amounts of boilerplate. In higher-level code I rarely bother with const. It often excludes things you often do with complex code -- like caching, lazy initialization, etc.. And errors with const in high-level code can sometimes be a pain to track down -- you declare something const and some leaf-node module 5 levels of abstraction down fails to compile. Why? You have to chase the code down 5 levels of abstraction to find out. It's just not worth the trouble. Having said all that, though, one place where const/immutable really shines in D is strings: because strings are defined to be immutable(char)[], that means taking substrings never has to copy. This saves a LOT of busywork copying bits of strings all over the place -- which you have to do in C/C++ because there char arrays are mutable, so to make sure your substring doesn't unexpectedly mutate from under you, you make a copy of it. This leads to far more allocations than are strictly necessary to perform some operation. In D, you can freely slice the strings as much as you want, and you're guaranteed that none of them will unexpectedly mutate from under you. None of them require an allocation, and so are more efficient in string-processing code. T -- Маленькие детки - маленькие бедки.
Nov 18 2022
parent Kagamin <spam here.lot> writes:
On Friday, 18 November 2022 at 17:57:25 UTC, H. S. Teoh wrote:
 You're looking at it the wrong way.  The kind of issues having 
 const
 would solve is like when your function takes parameters x, y, 
 z, and
 somewhere deep in the function you see the expression `x + 
 y*z`. If x,
 y, and z are const, then you immediately know what the value of 
 this
 expression is.  However, if they were not, then you'd have to 
 trace
 through all of the preceding code to figure out whether their 
 values
 have changed, and how they have changed.  The former makes the 
 code
 easier to understand, the latter adds complexity to 
 understanding the
 code.
AFAIK Rust allows shadowing (intentionally) to solve usability problems with immutable variables, so when deep in the function you see `x+y*z`, you can't immediately tell its value, because the variables could be previously shadowed and you have to trace through all of the preceding code to figure it out :)
Nov 22 2022
prev sibling next sibling parent XavierAP <n3minis-git yahoo.es> writes:
On Friday, 18 November 2022 at 11:51:42 UTC, thebluepandabear 
wrote:
 A question I have been thinking about whilst using D is how 
 often I should be using const.

 Many people claim that all variables should be const by 
 default, but whether or not it is really needed is debatable 
 and oftentimes making everything const could cause readability 
 issues and make the code more complex.

 I also wonder how important const really is, like 99% of the 
 time you will know when your variable will be changed, and even 
 when a variable changes it's not like it is the end of the 
 world.

 Also, there is no real end to how much variables can be const. 
 Oftentimes -- interestingly -- in popular repos I don't even 
 see const being used, this is what confuses me.

 As a newcomer, I'd be interested in hearing everyones thoughts.
IMHO and besides other insights in previous replies, in practice this depends on whether you're talking about private implementation code, or an external interface -- of a library, component/unit (under test), etc. In private implementation code, including your scripts, informal code for personal use etc. you should probably not bother more than needed. It's fine that other languages (functional or safety-paranoid) force const or immutable by default, it's fine that D doesn't. Go with the least verbose default for this kind of code. For external interfaces, be mindful that everything that should not be mutated across them, is annotated as const, since languages D or C++ provide this facility. Otherwise you'd have to rely and unsafely trust on naming conventions like Python.
Nov 22 2022
prev sibling parent reply []() {}() <SilentLambda gmail.com> writes:
On Friday, 18 November 2022 at 11:51:42 UTC, thebluepandabear 
wrote:
 As a newcomer, I'd be interested in hearing everyones thoughts.
Everyones thoughts? You sure about that ;-) anyho.... To Const or Not to Const? https://www.artima.com/articles/const-rtti-and-efficiency
Nov 22 2022
parent reply thebluepandabear <therealbluepandabear protonmail.com> writes:
On Tuesday, 22 November 2022 at 22:40:54 UTC, []() {}() wrote:
 On Friday, 18 November 2022 at 11:51:42 UTC, thebluepandabear 
 wrote:
 As a newcomer, I'd be interested in hearing everyones thoughts.
Everyones thoughts? You sure about that ;-) anyho.... To Const or Not to Const? https://www.artima.com/articles/const-rtti-and-efficiency
C++ const is different than D const, not sure how helpful that article is.
Nov 22 2022
parent reply []() {}() <SilentLambda gmail.com> writes:
On Tuesday, 22 November 2022 at 23:30:38 UTC, thebluepandabear 
wrote:
 On Tuesday, 22 November 2022 at 22:40:54 UTC, []() {}() wrote:
 On Friday, 18 November 2022 at 11:51:42 UTC, thebluepandabear 
 wrote:
 As a newcomer, I'd be interested in hearing everyones 
 thoughts.
Everyones thoughts? You sure about that ;-) anyho.... To Const or Not to Const? https://www.artima.com/articles/const-rtti-and-efficiency
C++ const is different than D const, not sure how helpful that article is.
Yes, that is true (about the differences). But Scott is very specific about it not being langauge specific. His guidelines are engineering guidelines. e.g. "You're saying in your experience, the cost of the policy to type const all those times just doesn't pay for itself. If that's been your experience, then that's fine." In other words, he is saying, the decision to use const or not, is a tradeoff. Software engineers make tradeoffs, all the time. It comes with package. So the answer to your question is, use it when it has a payoff - for you. That's the same answer I gave to you for getters/setters ;-)
Nov 22 2022
parent thebluepandabear <therealbluepandabear protonmail.com> writes:
 So the answer to your question is, use it when it has a payoff 
 - for you.
If that's the case, I've probably come to my own conclusion: that it's not worth it as it's not giving me any payoff for the extra code. Thanks.
Nov 22 2022