Live data from Hacker News

John Carmack on mutable variables

twitter.com

201–210 of 663 posts

Re: John Carmack on mutable variables

#201
post #2

> Making almost every variable const at initialization is good practice. I wish it was the default, and mutable was a keyword. 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…

Pure functional works great until it doesn't. For a lot of systems-y and performance-oriented code you need the escape hatches or you'll be in for a lot of pain and annoyance. As a practical observation, I think it was easier to close this gap by adding substantial functional capabilities to imperative languages than the other way around. Historically, functional language communities were much more precious about the…

"Pure functional works great until it doesn't. "

That's why F# is so great.

Functional is default, but mutable is quite easy to do with a few mutable typedefs.

The containers are immutable, but nobody stops you from using the vanilla mutable containers from .net

It's such a beautiful, pragmatic language.

Re: John Carmack on mutable variables

#202
post #187
post #124

When I started programming in Haskell, where all variables are immutable, I felt like I was in a straitjacket Then, suddenly, the enlightenment

How do you know it’s real? When one is in a straitjacket for a long time, the trauma might make the mind disassociate from the body, giving an illusion of freedom. The brain is essentially dreaming it’s escaped while the body is still programming in Java.

That made me laugh, thank you.

Re: John Carmack on mutable variables

#204
Agree. After working seriously on a large production Haskell codebase for several years I definitely took it for granted. Now that I’m writing stuff in C again I do think immutability should be the default.

const isn’t really it though. It could go further.

Re: John Carmack on mutable variables

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

whats the difference between immutable and constant, which has been in use far longer? why are you calling it mutable?

Re: John Carmack on mutable variables

#206
post #10
post #2

> Making almost every variable const at initialization is good practice. I wish it was the default, and mutable was a keyword. 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…

Functional programming languages (almost always?) come with the baggage of foreign looking syntax. Additionally, imperative is easier in some situations, so having that escape hatch is great. I think that's why we're seeing a lot of what you're describing. E.g. with Rust you end up writing mostly functional code with a bit of imperative mixed in. Additional, most software is not pure (human input, disk, network, etc)…

> Functional programming languages (almost always?) come with the baggage of foreign looking syntax.

At least for me, this was solved by Gleam. The syntax is pretty compact, and, from my experience, the language is easily readable for anyone used to C/C++/TypeScript and even Java.

The pure approach may be a bit off-putting at first, but the apprehensions usually disappear after a first big refactoring in the language. With the type system and Gleam's helpful compiler, any significant changes are mostly a breeze, and the code works as expected once it compiles.

There are escape hatches to TypeScript/JavaScript and Erlang when necessary. But yeah, this does not really solve the impure edges many people may cut themselves on.

Re: John Carmack on mutable variables

#207
post #2

> Making almost every variable const at initialization is good practice. I wish it was the default, and mutable was a keyword. 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…

> If you want a language where const is the default and mutable is a keyword

whats the difference between const and mutable?

Re: John Carmack on mutable variables

#208
post #121
post #115

Variable is by definition mutable. Constant is by definition immutable. Why can't people get it through their heads in 2025? (I'm looking at you, Rust)

That depends on your definition. Programming languages often deviate from mathematics when it comes to definition of variables, functions etc. That is by choice, Haskell tried to be as close to mathematical definition as possible.

You don’t need to make a mathematical argument, “variable” and “constant” have clear meanings in colloquial use which match the definitions of your parent comment.

Re: John Carmack on mutable variables

#209

Earlier quoted context omitted.

There is a huge amount of syntactic sugar that has been added over the years that doesn't do whole lot IMO. It is often imported from other languages (usually JavaScript and/or Python). e.g. Just a very simple example to illustrate the point if (customer != null) { customer.Order = GetCurrentOrder(); } vs if (customer is not null) { customer.Order = GetCurrentOrder(); } Is there really any benefit in adding "is/is no…

In your sample there really is no benefit to using the "is" operator over just checking for null (assuming you haven't overloaded the "!=" operator). However, the "is" operator is a lot more powerful, you can match an expression against a pattern with it. Would you say that these samples show no benefit to using the "is" operator? if (obj is string s) { ... } if (date is { Month: 10, Day: https://learn.microsoft.com/…

The issue is that I dislike the overall mentality of just adding a bunch of language features. Things just seem to be dumped in each release and I think to myself "When I am going to use that?".

> Would you say that these samples show no benefit to using the "is" operator?

I didn't say no benefit. I said dubious benefit.

I didn't really want to get into discussing specific operators, but lets just use your date example:

   if (date is { Month: 10, Day: 
This following would do the same thing before the is operator:

    static bool IsFirstFridayOfOctober(DateTime date)
    {
        return date.Month == 10
            && date.Day 
And then:

    if IsFirstFridayOfOctober(date) {
       ...
    }
I understand it is more verbose. But do we really need a new operator for this? I was getting on fine without it.

Each release there seems to be more of these language features and half the time I have a hard time remembering that they even exist.

Each time I meet with other .NET developers either virtually or in Person they all seem to be salivating over this stuff and I feel like I've walked in on some sort of cult meeting.

Re: John Carmack on mutable variables

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

The immutable approach doesn't conflate the concepts of place, time, and abstract identity, like in-place mutation does.

In mutating models, typically abstract (mathematical / conceptual) objects are modeled as memory locations. Which means that object identity implies pointer identity. But that's a problem when different versions of the same object need to be maintained.

It's much easier when we represent object identity by something other than pointer identity, such as (string) names or 32-bit integer keys. Such representation allows us to materialize us different versions (or even the same version) of an object in multiple places, at the same time. This allows us to concurrently read or write different versions of the same abstract object. It's also an enabler for serialization/deserialization. Not requiring an object to be materialized in one particular place allows saving objects to disk or sending them around.

Post reply on HN