by azhenley on 10/31/25, 2:34 AM with 607 comments
by EastLondonCoder on 10/31/25, 9:30 AM
I think it may be one of those things you have to see in order to understand.
by hyperhello on 10/31/25, 3:00 AM
I wish the IDE would simply provide a small clue, visible but graphically unobtrusive, that it was mutated.
In fact, I end up wishing this about almost every language feature that passes my mind. For example, I don't need to choose whether I can or can't append to a list; just make it unappendable if you can prove I don't append. I don't care if it's a map, list, set, listOf, array, vector, arrayOf, Array.of(), etc unless it's going to get in my way because I have ten CPU cores and I'll optimize the loop when I need to.
by slifin on 10/31/25, 8:12 AM
Oh well continues day job as a Clojure programmer that is actively threatened by an obnoxious python take over
by gwbas1c on 10/31/25, 3:02 AM
It made the code easier to read because it was easier to track down what could change and what couldn't. I'm now a huge fan of the concept.
by nixpulvis on 10/31/25, 1:49 PM
If I have a `result` and I need to post-process it. I'm generally much happier doing `result = result.process()` rather than having something like `preresult`. Works nicely in cases where you end up moving it into a condition, or commenting it out to test an assumption while developing. If there's an obvious name for the intermediate result, I'll give it that, but I'm not over here naming things `result_without_processing`. You can read the code.
by anymouse123456 on 10/31/25, 1:50 PM
I know there are alternate names available to us, but even in the context of this very conversation (and headline), the thing is being called a "variable."
What is a "variable" if not something that varies?
by lopatin on 10/31/25, 3:07 AM
by agentultra on 10/31/25, 12:05 PM
const isn’t really it though. It could go further.
by DashAnimal on 10/31/25, 3:39 AM
by sunrunner on 10/31/25, 10:22 AM
# Immutable by default
x = 2
items = [1,2,3]
with mutable(x, items):
x = 3
items.append(4)
# And now back to being immutable, these would error
x = 5
items.append(6)
I have put almost zero thought into the practicality of this for implementation, the ergonomics for developers, and whether it would be different enough and useful enough to be worth having.by bitbasher on 10/31/25, 2:37 PM
Rust mentioned!
by y0ned4 on 10/31/25, 9:22 AM
Then, suddenly, the enlightenment
by or_am_i on 10/31/25, 9:45 AM
- this makes them really stand out, much easier to track the mutation visually,
- the underscore effect is intrusive just-enough to nudge you to think twice when adding a new `var`.
Nothing like diving into a >3k lines PR peppered with underscores.
by omnicognate on 10/31/25, 9:03 AM
I know it's irrelevant to his point, and it's not true of C, and it doesn't have the meaning he wants, but the pedant in me is screaming and I'm surprised it hasn't been said in the comments:
In C++ mutable is a keyword.
by munchler on 10/31/25, 2:54 AM
It's funny how functional programming is slowly becoming the best practice for modern code (pure functions, no side-effects), yet functional programming languages are still considered fringe tech for some reason.
If you want a language where const is the default and mutable is a keyword, try F# for starters. I switched and never looked back.
by swiftcoder on 10/31/25, 8:03 AM
by ronnier on 10/31/25, 3:04 AM
by TheRoque on 10/31/25, 2:07 PM
by duxup on 10/31/25, 1:09 PM
I don't mind the idea here, seems good. But I also don't move a block of code often and discover variable assignment related issues.
Is the bad outcome more often seen in C/C++ or specific use cases?
Granted my coding style doesn't tend to involve a lot of variables being reassigned or used across vast swaths of code either so maybe I'm just doing this thing and so that's why I don't run into it.
by vezcha on 11/2/25, 7:53 PM
by markstos on 10/31/25, 8:30 PM
Every new state is an additional condition to check. A mutated variable implies an additional state to test.
One boolean means two states to test. Four booleans that interact is 2^4 (16) states to test.
by acdbddh on 10/31/25, 2:03 PM
df = pd.concat(df,other_df)
df = df.select(...)
...
My eyes hurts, when I see it. It makes me avoid python.
I bet the reason for this mutable code is a missing simple pipes syntax.
I love pipes. In R can do: df |>
rbind(other_df) |>
select(...)
It feels much better.by shermantanktop on 10/31/25, 2:55 PM
by shmerl on 10/31/25, 3:29 AM
by storus on 10/31/25, 2:00 PM
by garrison on 11/2/25, 3:13 AM
by waffletower on 10/31/25, 6:44 PM
by loeg on 10/31/25, 3:36 AM
by DonHopkins on 10/31/25, 10:32 AM
by Razengan on 10/31/25, 10:03 AM
`let` is so 2020. `const` is too long. `static` makes me fall asleep at the keyboard. `con` sounds bad. How about
`law`?
law pi = 3.142 (heh typing on Mac autocompleted this)
law c = 29979245
law law = "Dredd"
or `set` or `once` or `make`?by Const-me on 10/31/25, 1:05 PM
by nyrp on 10/31/25, 1:43 PM
by thefaux on 10/31/25, 4:25 PM
by rezonant on 10/31/25, 5:56 PM
by QuadrupleA on 10/31/25, 3:17 PM
classList = ['highlighted', 'primary']
if discount:
classList.append('on-sale')
classList = ' '.join(classList)
And not having to think about e.g. `const` vs `let` frees up needless cognitive load, which is why I think python (rightly) chose to not make it an option.by warmwaffles on 10/31/25, 2:02 PM
by considerdevs on 10/31/25, 10:17 AM
Wouldn't this be an easy task for SCA tool e.g. Pylint? It has atleast warning against variable redefinition: https://pylint.pycqa.org/en/latest/user_guide/messages/refac...
by koolba on 10/31/25, 10:42 AM
The value (pun intended) of the latter is that once you’ve arrived at a concrete result, you do not have to think about it again.
You’re not defining a “variable”, you’re naming an intermediate result.
by noduerme on 10/31/25, 3:09 AM
A lot of code needs to assemble a result set based on if/then or switch statements. Maybe you could add those in each step of a chain of inline functions, but what if you need to skip some of that logic in certain cases? It's often much more readable to start off with a null result and put your (relatively functional) code inside if/then blocks to clearly show different logic for different cases.
by zahlman on 10/31/25, 3:22 PM
I find that keeping functions short also helps a ton with that.
No, shorter than that. Short enough that the only meaningful place to "move a block of code" is into another function. Often, by itself.
by sgarland on 10/31/25, 10:47 AM
by AaronAPU on 10/31/25, 1:39 PM
by AtNightWeCode on 10/31/25, 9:39 PM
by carabiner on 10/31/25, 7:07 PM
df = pd.read_excel()
df = df.drop_duplicates.blahblah_other_chained_functions()
[20 cells later]
df = df.even_more_fns()by stevage on 10/31/25, 3:51 AM
- if (x) { const y = true } else { const y = false } // y doesn't exist after the block - try { const x = foo } catch (e) { } // x doesn't exist after the try block
by mcv on 10/31/25, 1:31 PM
by wodenokoto on 10/31/25, 1:51 PM
When I was first learning I thought all methods would mutate. It has a certain logic to it
by Havoc on 10/31/25, 9:36 AM
by jdthedisciple on 10/31/25, 9:26 AM
For example in Dart you make everything `final` by default.
by WalterBright on 10/31/25, 6:08 PM
int x = 3;
x = 4; // error!
int* p = &x;
*p = 4; // is that an error?by mr_mitm on 10/31/25, 8:36 AM
by halo on 10/31/25, 8:56 AM
The principle of reducing state changes and side-effects feels a good one.
by MrNet32823 on 10/31/25, 10:19 AM
by groby_b on 10/31/25, 5:39 PM
Hindsight's 20/20, of course. But still.
by bmitc on 10/31/25, 1:40 PM
Well yea, that's what sane languages that aren't Python, C, and C++ do. See F# and Rust.
by avadodin on 10/31/25, 6:05 PM
by xd1936 on 10/31/25, 1:06 PM
by jodleif on 10/31/25, 10:50 AM
by ardit33 on 10/31/25, 9:41 AM
But, there is practicality in the ability of being able to change a var, and not having to create a new object every time you change one of its members.
It models real nature/physics better.
It looks like He is asking that 'const' be the default, and 'var' should be explicit, which makes sense.
by mavhc on 10/31/25, 11:47 AM
by kybernetyk on 10/31/25, 10:51 AM
by dinkblam on 10/31/25, 4:00 PM
#define var __auto_type
#define let const __auto_type
by theodorethomas on 10/31/25, 12:24 PM
by textlapse on 10/31/25, 3:14 PM
Don't be silly and assume if I assign it multiple times in an if condition it's mutable - it's constructing the object as we speak, so it's still const!!!
C# gets this right among many other things (readonly vs const, init properties, records to allow immutability by default).
And the funny thing is the X thread has lots of genuine comments like 'yeah, just wrap a lambda to ensure const correctness' like that's the okay option here? The language is bad to a point it forces good sane people into seeing weird "clever" patterns all the time in some sort of an highest ELO rating for the cleverest evilest C++ "solution".
I was hoping Carbon was the hail mary for saving C++ from itself. But alas, looks like it might be googlified and reorged to oblivion?
Having said that, I still like C++ as a "constrained C++" language (avoid clever stuff) as it's still pretty good and close to metal.
by armaoin on 10/31/25, 7:24 PM
by mtlmtlmtlmtl on 10/31/25, 4:50 PM
by askmrsinh on 10/31/25, 5:07 AM
It can be perfectly fine to use mutable variables within a block, like a function when absolutely needed - for example, in JavaScript's try catch and switch statements that need to set a variable for later use. As long as these assignments are local to that block, the larger code remains side-effect free and still easy to reason about, refactor and mantain.
https://rockthejvm.com/articles/what-is-referential-transpar...
by gethly on 10/31/25, 8:53 AM
Constant is by definition immutable.
Why can't people get it through their heads in 2025? (I'm looking at you, Rust)
by cfontes on 10/31/25, 11:32 AM
by reverseblade2 on 10/31/25, 1:25 PM
by moi2388 on 11/1/25, 6:04 PM
Makes everything so much easier to reason about.
by KaiserPro on 10/31/25, 10:54 AM
I mean there is good reason to keep variables well scoped, and the various linters do a reasonable job about scope.
But I've only really know C++[1] people to want everything as a const.
[1] Yes, you functional people also, but, lets not get into that.
by GTP on 10/31/25, 5:13 PM
by andsoitis on 10/31/25, 2:04 PM
by oulipo2 on 10/31/25, 1:32 PM
by GPerson on 10/31/25, 3:34 AM
by smallstepforman on 10/31/25, 10:46 AM
by hackthemack on 10/31/25, 1:32 PM
I want everything that passes through a function to be a copy unless I put in a symbol or keyword that it suppose to be passed by reference.
I made a little function to do deep copies but am still experimenting with it.
function deepCopy(value) {
if (typeof structuredClone === 'function') {
try { return structuredClone(value); } catch (_) {}
}
try {
return JSON.parse(JSON.stringify(value));
} catch (_) {
// Last fallback: return original (shallow)
return value;
}
}