Live data from Hacker News

John Carmack on mutable variables

twitter.com

381–390 of 663 posts

Re: John Carmack on mutable variables

#381

One area that I like to have immutability is in function argument passing. In javascript (and many other languages), I find it weird that arguments in function act differently depending on if they are simple (strings, numbers) versus if they are complex (objects, arrays). 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…

> 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.

JavaScript doesn’t have references, it is clearer to only use “passed by reference” terminology when writing about code in a language which does have them, like C++ [0].

In JavaScript, if a mutable object is passed to a function, then the function can change the properties on the object, but it is always the same object. When an object is passed by reference, the function can replace the initial object with a completely different one, that isn’t possible in JS.

Better is to distinguish between immutable objects (ints, strings in JS) and mutable ones. A mutable object can be made immutable in JS using Object.freeze [1].

[0] https://en.wikipedia.org/wiki/Reference_(C%2B%2B)

[1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

Re: John Carmack on mutable variables

#382

Earlier quoted context omitted.

"Constant" implies a larger context. As in - it's not very "constant" if you keep re-making it in your loop, right? Whereas "immutable" throws away that extra context and means "whatever variable you have, for however long you have it, it's unchangeable."

> As in - it's not very "constant" if you keep re-making it in your loop, right? you cant change a constant though

He’s implying that the variable it’s being defined within the loop. So, constant, but repeatedly redefined.

Re: John Carmack on mutable variables

#383

> and it avoids problems where you move a block of code and it silently uses a version of the variable that wasn’t what it originally had. 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.

It helps with that, but it has other trade-offs: indirection isn't free for readability.

I'll go further than that and say that indirection significantly increases cognitive load and hurts readability.

Re: John Carmack on mutable variables

#384

I also default to const in javascript. Somehow a "let" variable feels so dirty, but I don't really know why. I guess at this point my experience forged an instinct but I can't even put a theory on it. But it's sometimes necessary and I use it of course.

JS's const doesn't go far enough since you can still mutate the object via its methods. In C++, you can only call const methods (which can't mutate the object) on const variables.

Re: John Carmack on mutable variables

#385
post #321

Earlier quoted context omitted.

> In the cases we're interested in here the variable does vary, what it doesn't do is mutate. Those are synonyms, and this amounts to a retcon. The computer science term "variable" comes directly from standard mathematical function notation, where a variable reflects a quantity being related by the function to other variables. It absolutely is expected to "change", if not across "time" than across the domain of the f…

> Those are synonyms, and this amounts to a retcon. The point is that it varies between calls to a function, rather than within a call. Consider, for example, a name for a value which is a pure function (in the mathematical sense) of the function's (in the CS sense) inputs.

Or between iterations of the loop scope in which it's defined, const/immutable definitions absolutely change during the execution of a function. I understand the nitpicky argument, I just think it's kinda dumb. It's a transparent attempt to justify jargon that we all know is needlessly confusing.

Re: John Carmack on mutable variables

#386
post #188

After 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 think the explanation is: When you mutate variables it implicitly creates an ordering dependency - later uses of the variable rely on previous mutations. However, this is an implicit dependency that isn't modeled by the language so reordering won't cause any errors. With a very basic concrete example: x = 7 x = x + 3 x = x / 2 Vs x = 7 x1 = x + 3 x2 = x1 / 2 Reordering the first will have no error, but you'll get t…

Yet even Rust allows you to shadow variables with another one with the same name. Yes, they are two different variables, but for a human reader they have the same name.

I think that Rust made this decision because the x1, x2, x3 style of code is really a pain in the ass to write.

Re: John Carmack on mutable variables

#387
post #185

Earlier quoted context omitted.

The way I like to think about is that with immutable data as default and pure functions, you get to treat the pure functions as black boxes. You don't need to know what's going on inside, and the function doesn't need to know what's going on in the outside world. The data shape becomes the contract. As such, localized context, everywhere, is perhaps the best way to explain it from the point of view of a mutable world…

Sure modularity, encapsulation etc are great tools for making components understandable and maintainable. However, don't you still need to understand the entire program as ultimately that's what you are trying to build. And if the state of the entire programme doesn't change - then nothing has happened. ie there still has to be mutable state somewhere - so where is it moved to?

> However, don't you still need to understand the entire program as ultimately that's what you are trying to build.

Of course not, that's impossible. Modern programs are way to large to keep in your head and reason about.

So you need to be able to isolate certain parts of the program and just reason about those pieces while you debug or modify the code.

Once you identify the part of the program that needs to change, you don't have to worry about all the other parts of the program while you're making that change as long as you keep the contracts of all the functions in place.

Re: John Carmack on mutable variables

#388
post #336

I try to keep deeper mutation to where it belongs, but I'll admit to shadowing variables pretty often. 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 fo…

result.process() That doesn’t make logical sense. You already have a result. It shouldn't need processing to be a result.

It also doesn't make sense for `process()` to be an attribute of `result`. Why would you instantiate a class and call it result‽

Re: John Carmack on mutable variables

#389
post #138
post #32

Earlier quoted context omitted.

Which one, Erlang, Lisp, or ML?

Lisp syntax is objectively superior because you can write a predicate like thus: ( Instead of having to do the awful ampersand dance.

In Python or Icon (or Unicon) that's

    lower_bound 
except that usually you want

    lower_bound 
which is also legal.

In Python this is a magical special case, but in Icon/Unicon it falls out somewhat naturally from the language semantics; comparisons don't return Boolean values, but rather fail (returning no value) or succeed (returning a usually unused value which is chosen to be, IIRC, the right-hand operand).

And in SQL you have

    `x-coordinate` between `lower-bound` - 1 and `upper-bound` + 1
which is obviously the best possible syntax.

Re: John Carmack on mutable variables

#390
post #83

Earlier quoted context omitted.

I use Swift for work. The compiler tell you this. If a mutable variable is never mutated it suggests making it non-mutable. And vice versa.

As will Typescript, at least using Biome to lint it does.

eslint has this too: https://eslint.org/docs/latest/rules/prefer-const
Post reply on HN