John Carmack on mutable variables
251–260 of 663 posts
Re: John Carmack on mutable variables
#252I'm going to maybe out myself as having limited experience here ... 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 th…
1) You get intermediate results visible in the debugger / accessible for logs, which I think is a benefit in any language.
2) You get an increased safety in case you move around some code. I do think that it applies to any language, maybe slightly more so in C due to its procedural nature.
See, the following pattern is rather common in C (not so much in C++):
- You allocate a structure S
- If S is used as input, you prefill it with some values. If it's used as output, you can keep it uninitialized or zfill.
- You call function f providing a pointer to that struct.
Lots of C APIs work that way: sockets addresses, time structures, filesystem entries, or even just stack allocated fixed size strings are common.
Re: John Carmack on mutable variables
#253Earlier quoted context omitted.
As a Python programmer at day job, that is Clojure-curious and sadly only gets to use it for personal projects, and is currently threatened by an obnoxious TypeScript take over, I feel this.
In the context of the original discussion, TypeScript (and ES6) has const and let.
Re: John Carmack on mutable variables
#254Re: John Carmack on mutable variables
#255I 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;
}
}Re: John Carmack on mutable variables
#256Re: John Carmack on mutable variables
#257Earlier quoted context omitted.
Because it has nothing to do with the content and it's the kind of comment that is only made for the sake of stirring up feelings people have about Twitter and its owner, a topic that has been done to death for years on HN, and about which there is nothing new or interesting to say. HN is a site that's specifically designed to focus on the new and interesting aspects of topics.
That Carmack still posts to Twitter (and QTs Curtis Yarvin) was news to me.
Please don't pick the most provocative thing in an article or post to complain about in the thread. Find something interesting to respond to instead.
This has been in the guidelines for many years and it’s long been routine moderation that we ask people to avoid that kind of thing.
Re: John Carmack on mutable variables
#258For performance critical code, you want to reuse L1D cache lines as much as possible. In many cases, allocation of a new immutable object boils down to malloc(). Newly allocated memory is unlikely to be found on L1D cache. OTOH, replacing data in recently accessed memory and reusing the memory is very likely to become L1D cache hit in runtime.
Similar to how "tail recursion can (usually) be lifted/lowered to a simple loop...", immutability from language statements can often be "collapsed" into mutating a single variable, and there may be one or two "dances" you need to do to either add helper functions, structure your code _slightly_ differently to get there, but it's similar to any kind of performance sensitive code.
Example foo(bar(baz(), bar_alt(baz_alt(), etc...))) [where function call nesting is "representing" an immutability graph] ...yeah, that'd have a lot of allocations and whatever.
But: foo().bar().bar_alt().baz().baz_alt().etc(...) you could imagine is always just stacking/mutating the same variable[s] "in place".
...don't get hung up on the syntax (it's wildly wrong), but imagine the concept. If all the functions "in the chain" are pure (no globals, no modifications), then they can be analyzed and reduced. Refer back to the "Why SSA?" article from a week or two ago: https://news.ycombinator.com/item?id=45674568 ...and you'll see how the logical lines of statements don't necessarily correspond to the physical movement of memory and registers.
Re: John Carmack on mutable variables
#259After a 2 year Clojure stint I find it very hard to explain the clarity that comes with immutability for programmers used to trigger effects with a mutation. I think it may be one of those things you have to see in order to understand.
I guess I'm not that good a programmer, because I don't really understand why variables that can't be varied are useful, or why you'd use that. How do you write code that actually works?
Re: John Carmack on mutable variables
#260Earlier quoted context omitted.
That's an aesthetically awkward and also bug-prone syntax: So just a difference of 1 single letter (that looks similar) to mean the completely opposite thing?? Nah you don't want that, and I don't either.
Kotlin uses var/val too[0] which is what Java is trying to copy. I have never written any kotlin code before, so I don't know if this would be a problem in practice. On the plus side, var and val both have the same length, so the variable declaractions are properly aligned. The names are also intuitive as far as I can tell.In theory, I'd probably be okay with it. [0] https://kotlinlang.org/docs/basic-syntax.html#vari…