Live data from Hacker News

John Carmack on mutable variables

twitter.com

531–540 of 663 posts

Re: John Carmack on mutable variables

#531
"State is the enemy".

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.

Re: John Carmack on mutable variables

#532

I completely agree with the assertion and the benefits that ensue, but my attention is always snagged by the nomenclature. 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?

In the cases we're interested in here the variable does vary, what it doesn't do is mutate. Suppose I have a function which sums up all the prices of products in a cart, the total so far will frequently mutate, that's fine. In Rust we need to mark this variable "mut" because it will be mutated as each product's price is added. After calculating this total, we also add $10 shipping charge. That's a constant, we're (fo…

> In Rust we'd use `const` for this but in C you need to use the C pre-processor language instead to make constants, which is kinda wild.

I get that you're not very familiar with C? Because in C we'd use const as well.

    const int x = 2;
    x = 3; // error: assignment of read-only variable 'x'

Re: John Carmack on mutable variables

#533
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…

That example is too simple for me to grasp it. How would you code a function that iterates over an array to compute its sum. No cheating with a built-in sum function. If you had to code each addition, how would that work? Curious to learn (I probably could google this or ask Claude to write me the code).

Re: John Carmack on mutable variables

#534
post #527
post #466

Earlier quoted context omitted.

But he didn't design the Doom game. He designed its graphics engine.

You understand how games work, do you? Please tell me you do. Else, what kind of argument is it?

The engine enables people with actual creativity to realize their vision. I believe Carmack was part of that creative process, but the condescending tone of your comment really isn't appropriate because in most games the engine is just a means to an end (nobody sane idolizes games because they're using unreal underneath, for example)..

Re: John Carmack on mutable variables

#535
post #188

Earlier quoted context omitted.

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…

That example is too simple for me to grasp it. How would you code a function that iterates over an array to compute its sum. No cheating with a built-in sum function. If you had to code each addition, how would that work? Curious to learn (I probably could google this or ask Claude to write me the code).

Carmack gives updating in a loop as the one exception:

> You should strive to never reassign or update a variable outside of true iterative calculations in loops.

If you want a completely immutable setup for this, you'd likely have to use a recursive function. This pattern is well supported and optimized in immutable languages like the ML family, but is not super practical in a standard imperative language. Something like

  def sum(l):
    if not l: return 0
    return l[0] + sum(l[1:])
Of course this is also mostly insensitive to ordering guarantees (the compiler would be fine with the last line being `return l[-1] + sum(l[:-1])`), but immutability can remain useful in cases like this to ensure no concurrent mutation of a given object, for instance.

Re: John Carmack on mutable variables

#536
post #188

Earlier quoted context omitted.

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…

That example is too simple for me to grasp it. How would you code a function that iterates over an array to compute its sum. No cheating with a built-in sum function. If you had to code each addition, how would that work? Curious to learn (I probably could google this or ask Claude to write me the code).

[deleted]

Re: John Carmack on mutable variables

#537

Earlier quoted context omitted.

In what way is that an issue?

Because this isn't immutability. The goal is to have a way to define an object that will never change after initialisation, and JS's const isn't it.

Clearly that isn't the goal.

Re: John Carmack on mutable variables

#538

"State is the enemy". 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.

Which is why functional programmers believe in the separation of Church and state. https://wiki.c2.com/?SeparationOfChurchAndState

Re: John Carmack on mutable variables

#539
post #354
post #96

Yeah I wish variables were immutable by default and everything was an expression Oh well continues day job as a Clojure programmer that is actively threatened by an obnoxious python take over

You are not a Clojure programmer. You use Clojure to solve problems in a professional context. I'm sorry that there's a political tribal war based on language going on at your workplace. But especially now that coding agents are radically enabling gains in developer productivity, you don't need to feel excluded by the artificial tribal boundaries. If you haven't, I recommend reading: https://www.kalzumeus.com/2011/10…

I remember that post and essentially agree with everything in it and your points too.

However there's a real-world factor that I don't think it covers, which is that having ten years of experience in the ecosystem for any language almost guarantees that you're going to be faster, more efficient, more idiomatic, and generally more comfortable through familiarity with that language and its ecosystem than with any other 'drop in replacement'. And you'll also probably be more aware of what doesn't work, which is just as useful. You can always tell when someone knows their tools well when they can immediately tell you what sucks about them, and possibly even the history of it and why it might happen to make sense, even if seems bad.

This isn't an argument for favouring speed or efficiency, just an ackowledgement of what is lost when you choose or are forced to move to a different environment.

Languages are a lot more than just syntax. Language-specific features, conventions and common idioms, language implementation details that end up being valuable to understand, familiarity with core library, familiarity with third party libaries (including the ones that are so well-known as to almost be considered core), package management, documentation standards, related tooling, foreign-function interfaces and related tools to make that workable, release concerns. The list goes on.

There's no tribal boundary here, just a belief that time spent with a given tool and all its idiosyncrancies (and programming languages are their idosyncracies, otherwise they wouldn't be different) is valuable and not something to pass up, even if I agree with the thesis of the article.

Can you bootstrap your way to a passable, possibly even idiomatic, solution with coding agents? Yes. Does that mean you've managed to short circuit the results of long-term experience? I'm not so sure. Does it matter? Depends on the person or environment, I guess.

I don't think the learning curve for a new tool is a straight line (I imagine more logarithmic), so it's not that you'd need the same amount of exposure in terms of time, but that does imply the cost of changing is up-front.

There's also a difference between choosing to investigate a new language out of your own interest and having the time to do it properly, versus having some top-down mandate that you must now use , meanwhile still having to meet the same deadlines as before.

Re: John Carmack on mutable variables

#540

Love Carmack, but hard disagree on this and a lot of similar functional programming dogma. I find this type of thing very helpful: 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.

Fennel (Lisp):

    (table.concat [:highlighted :primary (if discount :on-sale)] " ")
Post reply on HN