Live data from Hacker News

John Carmack on mutable variables

twitter.com

651–660 of 663 posts

Re: John Carmack on mutable variables

#651
post #500

Earlier quoted context omitted.

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

> Why would you instantiate a class and call it result‽ Are you suggesting that the results of calculations should always be some sort of primitive value? It's not clear what you're getting hung up on here.

No, the result of a calculation could be a key value or list or other compound value - whatever the result is. I am getting hung up on deceptive naming. If you have a 'result', the calculation is done. You have a result.

Re: John Carmack on mutable variables

#652

https://nitter.net/id_aa_carmack/status/1983593511703474196

I wish this was one of HN's auto formatting rules, automatically replace the link with one of these frontends

Tbh I think it's ok - as much as I also want to avoid Twitter I do encourage original sourcing, especially since these nitter services can also have downtime fairly often. As long as someone jumps in and shares a link

Re: John Carmack on mutable variables

#653

Earlier quoted context omitted.

> If you need new values you just make new things. > If you want to do an operation on fooA, you don't mutate fooA. You call fooB = MyFunc(fooA) and use fooB. The beautiful thing about this is you can stop naming things generically, and can start naming them specifically what they are. Comprehension goes through the roof.

Yes, but you can do that without having loads of stale copies of incorrect data lying around, presumably.

With techniques like method chaining you can avoid using a constant or a variable and just pass return values around.

Re: John Carmack on mutable variables

#654
post #626
post #487

Earlier quoted context omitted.

Depends on how clear it is. I usually write code to help local debug-ability (which seems rare). For example, this allows one to trivially set a conditional breakpoint and look into the full response: response = get_response() response = response.json() The fact that the first response is immediately overwritten proves to the reader it's not important/never used, so they can forget about it, where a temp variable wou…

get_response().json() is ideal, and I'm assuming yoiu're writing an HTTP wrapper since decoding JSON is a sensible default. If you need to add an intermediary variable, name it as clearly as possible: raw_response = get_response() response = raw_response.json()

> The fact that the first response is immediately overwritten proves to the reader it's not important/never used, so they can forget about it, where a temp variable would add cognitive load since it might be used later.

I strive to write code that reduces cognitive load. To me, putting it in a temp variable is more of habit of old languages, mixed with a bit of cargo cult.

Re: John Carmack on mutable variables

#655
post #107

Earlier quoted context omitted.

In Java you can use final[1]. And yes, if final points to an ArrayList you can change it, but you can also use final together with immutable data structures[2]. [1]: https://www.baeldung.com/java-final [2]: https://www.baeldung.com/java-immutable-list

Did you know that "final" does not actually mean final in Java (as in: the variable can be constant folded)? Reasons include reflection and serialization (the feature that nowadays nobody uses, but due to backwards compatibility the Java language developers always have to worry about?). There was an excellent talk about this recently, I think triggered by a new JEP "stable values": https://youtu.be/FLXaRJaWlu4

That is interesting, but I am already aware of it.

For anyone who wonder about why, it is meant to help us as programmers avoid shooting ourselves in the feet, not as some kind of unbreakable enforcement.

Re: John Carmack on mutable variables

#656
post #571

Earlier quoted context omitted.

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?

You are very right in that things need to change. If they don't, nothing interesting happens and we as programmers don't get paid :p. State changes are typically moved to the edges of a program. Functional Core, Imperative Shell is the name for that particular architecture style. FCIS can be summed up as: R->L->W where R are all your reads, L is where all the logic happens and is done in the FP paradigm, and W are al…

I'm trying to work out in my head if it helps the true challenge of programming - not writing the program in the first place, but maintaining it as requirements evolve.

The examples for functional programming benefits always seem to boil down to composable functions operating on lists of stuff where the shape has to be the same or you convert between shapes as you go.

It's very useful, but it's not a whole programme - unless you have some simple server side data processing pipeline - and I'd argue those aren't difficult program.

Programming get's difficult when you have to manage state - so I accept that parts that don't have to do that are therefore much simplier, however you have just moved the problem, not solved it.

And you say you've moved it to the edge of the program - that's fine with a simple in->function-> out, but in the case of a GUI isn't state is at the core of the program?

In that case isn't something with a central model that receives and emits events, easier to reason over and mutate?

Re: John Carmack on mutable variables

#657
post #654
post #626

Earlier quoted context omitted.

get_response().json() is ideal, and I'm assuming yoiu're writing an HTTP wrapper since decoding JSON is a sensible default. If you need to add an intermediary variable, name it as clearly as possible: raw_response = get_response() response = raw_response.json()

> The fact that the first response is immediately overwritten proves to the reader it's not important/never used, so they can forget about it, where a temp variable would add cognitive load since it might be used later. I strive to write code that reduces cognitive load. To me, putting it in a temp variable is more of habit of old languages, mixed with a bit of cargo cult.

> To me, putting it in a temp variable is more of habit of old languages

If you do want an intermediate variable, naming it non-deceptively will reduce cognitive load. If you don't want one, that's fine too. There's no deception with a name that doesn't exist.

Re: John Carmack on mutable variables

#658
post #571

Earlier quoted context omitted.

You are very right in that things need to change. If they don't, nothing interesting happens and we as programmers don't get paid :p. State changes are typically moved to the edges of a program. Functional Core, Imperative Shell is the name for that particular architecture style. FCIS can be summed up as: R->L->W where R are all your reads, L is where all the logic happens and is done in the FP paradigm, and W are al…

I'm trying to work out in my head if it helps the true challenge of programming - not writing the program in the first place, but maintaining it as requirements evolve. The examples for functional programming benefits always seem to boil down to composable functions operating on lists of stuff where the shape has to be the same or you convert between shapes as you go. It's very useful, but it's not a whole programme…

Even the GUI can follow the FCIS architecture. It helps immensely with testing and moving things around.

For a bigger program that handles lots of things, you can still build it around the FCIS architecture, you just end up with more in->chains of functions->out. The things at the edges might grow, but at a much slower pace than the core.

My experience with both sides is what's driven me to FP+immutability.

For your last question: I believe it's a false belief. I believed the same when I started with FP+immutability. I just did not understand where I should put my changes, because I was so used to mutating a variable. Turned out that I only really need to mutate it when I store in a db of some sort (frontend or backend), send it over the wire (socket, websocket, http response, gRPC, pub/sub, etc) or act as an object hiding inherit complexity (hardware state like push button, mouse, keyboard, etc). Graphics would also qualify, but that's one area where I think FP+immutability is ill suited.

Hit me up if you have any more questions :).

Re: John Carmack on mutable variables

#659

Earlier quoted context omitted.

How? I think the same argument applies: If it's changing from loop to loop, seems mutable to me.

I can give a specific example. for (0..5) |i| { i = i + 1; std.debug.print("foo {}\n", .{i}); } In this loop in Zig, the reassignment to i fails, because i is a constant. However, i is a new constant bound to a different value each iteration. To potentially make it clearer that this is not mutation of a constant between iterations, technically &i could change between iterations, and the program would still be correct…

I argue in your example there are 6 constants, not 1 constant with 6 different values, though this could be semantics ie we could both be right in some way

Re: John Carmack on mutable variables

#660
post #263

Earlier quoted context omitted.

In my IntelliJ (a recent version), if I write a small Java function like this: private static void blah() { final int abc = 3; for (int def = 7; def The variable 'def' is underlined. Mouse-over hint shows: 'Reassigned local variable'. To be clear, 'abc' is not underlined. When I write Java, I try to use the smallest variable scopes possible with as much final (keyword) as possible. It helps me to write more maintaina…

1st) you use ++def in a loop, don't be weird; 2nd) if 'abc' is to be used in the loop body, define in the loop, e.g. for (int def = 7, abc =3; ...); 3rd) this is an IntelliJ bug - both 'def' and 'abc' in the sample are always defined.

    > you use ++def in a loop, don't be weird
I come from a C++ background where it is always advised to use ++i instead of i++. It's just a habit. Does it stress you to read ++i over i++?
Post reply on HN