Live data from Hacker News

John Carmack on mutable variables

twitter.com

611–620 of 663 posts

Re: John Carmack on mutable variables

#611
post #219

Earlier quoted context omitted.

Immutable and constant are the same. rendaw didn't use the word mutable. One reason someone might use the word "mutable" is that it's a succinct way of expressing an idea. Alternative ways of expressing the same idea are longer words (changeable, non-constant).

They aren't the same for object references. The reference can't be changed, but the properties can.

Depends on the language. In C++

  const std::vector& foo = bar.GetVector();
foo is a constant object reference cannot have its properties changed (and also cannot be changed to refer to a new object).

  std::vector& foo = bar.GetVector();
Is an object reference that can have its properties changed (but cannot be changed to refer to a new object).

Re: John Carmack on mutable variables

#612
post #237

Earlier quoted context omitted.

Clojure also makes it very easy, it'd require too much discipline to do such a thing in Python. Even Carmack, who I think still does python mostly by himself instead of a team, is having issues there.

> it'd require too much discipline to do such a thing in Python Is Python that different from JavaScript? Because it's easy in JavaScript. Just stop typing var and let, and start typing const. When that causes a problem, figure out how to deal with it. If all else fails: "Dear AI, how can I do this thing while continuing to use const? I can't figure it out."

Javascript only enforces reassignments to const. So this,

  const arr = []
  arr.push(“grape nuts”]
is just peachy in JS and requires the programmer to avoid using it.

More importantly, because working immutably in JS is not enforced, trying to use it consistently either limits which libraries you can use and/or requires you to wrap them to isolate their side effects. ImmerJS can help a lot here, since immutability is its whole jam. I’d rather work in a language where I get these basic benefits by default, though.

Re: John Carmack on mutable variables

#613

Earlier quoted context omitted.

>developer ergonomics are much more important than freeing memory a little earlier Preach to the python choir bro, but it should be telling when a python bro considers it's too ergonomic and wasteful. At some point being clean and efficient about the code is actually ergonomic, no one wants to write sloppy code that overallocates, doesn't free, and does useless work. To quote Steve Jobs, even if no one sees the insid…

In this case, overuse of re-assigning is the sloppy thing to do, and immutability by default is the craftsman's move. Reducing your program's memory footprint by re-assigning variables all the time is a false economy.

So if you are preparing a 50Kb webpage, and you do 10 steps of processing, you would have a 500KB memory footprint that might be held during the life of the connection? All the while the footprint and thus capacity of your server could have been 100Kb? Nice craftmanship dude!

We are not even talking about in-place algorithms, just 10 functions that process an html into a new array, maybe:

html = load_template(route) html = formatstring(html,variables) html= localize_paths(html) ...

And you would rather have it:

template = load_template(route) formatted_html = formatstring(template,variables) html_with_localized_paths = localize_paths(html)

And you would rather have the latter? For what gain? I think you wouldn't.

"Only a sith deals in absolutes", you have to recognize that both are valid under different contexts. And I'm merely explaining why inmutable is the default in python, 1: python doesn't do programmer self restrictions like const and private; 2: memory is automatic, so there's no explicit allocation and freeing like in C++, so using a new variable for each thing isn't a zero overhead abstraction.

Even for smaller cases, (not 50kb arrays), it's still the proper thing to do, although you have freedom to choose, it's easier to just follow one style guide and protocol about how to do things, if it's pythonic to reuse the variable name, just reuse the variable name. Don't fall for the meme of coming from another language and writing C++ in python or Java in python, you are not a cute visionary that is going to import greatness into the new language, it's much better to actually learn the language rather than be stubborn.

There's places where you can be super explicit and name things, if it's just an integer then it's a very cheap comment that's paid in runtime memory instead of in LOC. But this is why the default in python is not const, because variable name reuse is a core python tactic, and you are not our saviour if you don't get that, you are just super green into the language.

Re: John Carmack on mutable variables

#614

Earlier quoted context omitted.

Why not? Which language?

Well, the stuff I'm writing is in C, but in general it would make no sense for anything to attempt to add items to a fixed-sized buffer. If you have something so fundamentally broken as to attempt that, you'd probably want to look at mutexes. Why one earth would you have something attempt to expand a fixed-sized buffer while something else is working on it?

There’s a mismatch between your assumptions coming from C and GP’s assumptions coming from a language where arrays are not fixed-length. Having a garbage collector manage memory for you is pretty fundamental to immutable-first languages.

Rich Hickey asked once in a talk, “who here misses working with mutable strings?” If you would answer “I do,” or if you haven’t worked much in languages where strings are always immutable and treated as values, it makes describing the benefits of immutability more challenging.

Von Neumann famously thought Assembly and higher-level language compilers were a waste of time. How much that opinion was based on his facility with machine code I don’t know, but compilers certainly helped other programmers to write more closely to the problem they want to solve instead of tracking registers in their heads. Immutable state is a similar offloading-of-incidental-complexity to the machine.

Re: John Carmack on mutable variables

#615
post #544

Earlier quoted context omitted.

You don't have to use recursion, that is, you don't need language support for it. Having first class (named) functions is enough. For example you can modify sum such that it doesn't depend on itself, but it depends on a function , which it will receive as argument (and it will be itself). Something like: def sum_(f, l): if not l: return 0 return l[0] + f(f, l[1:]) def runreq(f, *args): return f(f, *args) print(runreq…

> You don't have to use recursion You're using recursion. `runreq()` calls `sum_()` which calls `sum()` in `return l[0] + f(f, l[1:])`, where `f` is `sum()`

> You're using recursion.

No, see GP.

> `runreq()` calls `sum_()` which calls `sum()` in `return l[0] + f(f, l[1:])`, where `f` is `sum()`

Also no, see GP.

Re: John Carmack on mutable variables

#616

Earlier quoted context omitted.

But there isn’t anything hilarious about that. It’s a clear-minded and deliberate approach to reconciling principle with pragmatic utility. We can debate whether it’s the best approach, but it isn’t like… logically inconsistent, surprising, or lacking in self awareness.

You don’t see what’s hilarious about recreating what you are pretending to remove only one abstraction level removed? Anyway, I have great hopes for effect system as a way to approach this in a principled way. I really like what Ocaml is currently doing with concurrency. It’s clear to me that there is great value to unlock here.

I don’t agree with your characterization that anyone is “pretending”. The whole point of abstraction is convenience of reasoning. No one is fooling themselves or anyone else, nor trying to. It’s a conscious choice, for clear purposes. That’s precisely as hilarious as using another abstraction you might favor more, such as an effect system.

Re: John Carmack on mutable variables

#617
post #577

Earlier quoted context omitted.

But there isn’t anything hilarious about that. It’s a clear-minded and deliberate approach to reconciling principle with pragmatic utility. We can debate whether it’s the best approach, but it isn’t like… logically inconsistent, surprising, or lacking in self awareness.

You might also think of it a bit like poetry: creativity emerging from the process of working within formal constraints. By asking how you can represent something familiar in a specially structured way, you can learn both about that structure and the thing you're trying to unite with it. Occasionally, you'll even create something beautiful or powerful, as well. Maybe in that sense there's an "artificial" challenge in…

This is a fantastic way to put it, thank you for adding it!

Re: John Carmack on mutable variables

#618
post #464

Earlier quoted context omitted.

I don't think so? I've been clear that there are three distinct kinds of thing here - constants, immutable variables, and mutable variables. In C the first needs us to step outside the language to the macro pre-processor, the second needs the keyword "const" and the third is the default In Rust the first is a const, the second we can make with let and the third we need let mut, as Carmack says immutable should be the…

There are surely more than three! References can support mutation or not, "constants" may be runtime or compile time. The point is that the word "variable" inherently reflects change. And choosing it (a-la your malapropism-that-we-all-agree-not-to-notice "immutable variables") to mean something that does (1) is confusing and (2) tends to force us into worse choices[1][2] elsewhere. A "variable" should reflect the ide…

The term variable is from math is 100s (probably) of years old. Variables in pure functional languages are used exactly the same way it’s used in math. The idea of mutating and non-mutating variable is pretty old too and used in math as well. Neither are going to change.

Re: John Carmack on mutable variables

#619
post #513

Earlier quoted context omitted.

As Carmack points out, naming the intermediate values aides in debugging. It also helps you write code as you can give a name to every mutation. But also keep in mind that correct and incorrect is not binary. You might want to pass a fooA to another class that does not want the fooB mutation. If you just have foo, you end up with situations where a copy should have happened but didn't and then you get unwanted change…

But that's just it, why would a copy ever happen? Why would you want a correct and an incorrect version of your variable hanging about?

Taking your point of view: you assigned a value1 to a name. Then you assigned a value2 to the same name.

You say that value2 is correct. It logically follows that value1 was incorrect. Why did you assign it then?

The names are free, you can just use a correct name every single time.

Re: John Carmack on mutable variables

#620
post #555

Earlier quoted context omitted.

Const annotations are worth it for methods and APIs, but not most local variables.

I'd argue that it is. Use const by default, so it's obvious to the reader if something is mutated or not. It's easier to read code when you don't have to worry about how values may change over time. This is why Rust made the right choice.

Yeah, I think it's a great default, and Rust got that right. It's just too noisy in C++ as the non-default.
Post reply on HN