Join the discussion

Write your take first — we'll ask for email only when you're ready to publish.

  • Hacker News
  • > ... making almost every variable const at initialization is good practice. I wish it was the default, and mutable was a keyword.

    Rust mentioned!

  • And Zig :)
  • When I started programming in Haskell, where all variables are immutable, I felt like I was in a straitjacket

    Then, suddenly, the enlightenment

  • The lovely thing with Haskell is you have the ST monad that lets you have as many mutable variables as you want, as long as they stay within ST.
  • How does Haskell deal with things like memory-mapped I/O or signal handlers where the value of a variable can be changed by factors outside of the programmer's control?
  • I've had this experience with going from PHP and JS to typed languages. Many years ago I was a type sceptic, but after being forced to use them, I now can't stand not having strict typing.

    I'm sure others have written about this, but these days I think good code is code which has a very small area of variability. E.g code which returns a value in a single place as a single type, has a very limited number of params (also of single type), and has no mutable variables. If you can break code into chunks of highly predictable logic like this it's so so much easier to reason about your code and prevent bugs.

    Whenever I see methods with 5+ params and several return statements I can almost guarantee there will be subtle bugs.

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

    by blub
  • I like the idea of immutable-by-default, and in my own musings on this I've imagined a similar thing except that instead of a mutable keyword you'd have something more akin to Python's with blocks, something like:

        # Immutable by default
        x = 2
        items = [1,2,3]
    
        with mutable(x, items):
            x = 3
            items.append(4)
    
        # And now back to being immutable, these would error
        x = 5
        items.append(6)  
    
    I have put almost zero thought into the practicality of this for implementation, the ergonomics for developers, and whether it would be different enough and useful enough to be worth having.
  • Without a borrowck, inside your mutable block, another variable can reference to the mutable version of your x or items, and be mutated outside of that block.
  • This is in essence a mutable borrow - by looking at Rust's borrow checker, one can see the complexities of the concept.
  • 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.

  • Are Rust's defaults far enough?
  • Well in C actually you can not mutate something, you can only reassign, as it is always pass-by-value. You need to work around that, by passing a pointer to the object instead. In that sense mutability is kind of a language keyword: '&'. When you want to just get the object, you pass object it, if you need to modify it, you need to pass &object. This is something I hate in C++, that random function invocations can mutate arguments without it being obvious in the call syntax.
  • I wish this was one of HN's auto formatting rules, automatically replace the link with one of these frontends
  • 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?

  • Some languages like Kotlin have var and val introducing the distinction between variables (that are expected to get reassigned, to vary over time, and values, which are just that, a value that has been given a name. I like these small improvements.

    (unfortunately, Kotlin then goes on and introduces "val get()" in interfaces, overloading the val term with the semantics of "read only, but may very well change between reads, perhaps you could even change it yourself through some channel other than simple assignment which is a definite no")

  • The term 'variable' is from mathematics. As others have said, the values of variables do vary but they do not mutate.
  • A common naming is value. You can call them immutable values and mutable variables.

    Another way to look at it is a variables are separate from compile time constants whether you mutate them or not.

  • Right, yeah, it’s a funny piece of terminology! The sense in which a ‘variable’ ‘varies’ isn’t that its value changes in time, but that its value is context-dependent. This is the same sense of the word as used in math!
  • It's a variable simply because it doesn't refer to a specific object, but any object assigned to it as either function argument or by result of a computation.

    It's in fact us programmers who are the odd ones out compared to how the word variable has been used by mathematics and logicians for a long time

  • Variables are called variables because their values can vary between one execution of the code and the next. This is no different for immutable variables. A non-variable, aka a constant, would be something that has the same value in all executions.

    Example:

      function circumference(radius)
          return 2 * PI * radius
    
    Here PI is a constant, while radius is a variable. This is independent of whether radius is immutable or not.

    It doesn’t have to be a function parameter. If you read external input into a variable, or assign to it the result of calling a non-pure function, or of calling even a pure function but passing non-constant expressions as arguments to it, then the resulting value will in general also vary between executions of that code.

    Note how the term “variable” is used for placeholders in mathematical formulas, despite no mutability going on there. Computer science adopted that term from math.

    https://en.wikipedia.org/wiki/Variable_(mathematics)

  • > What is a "variable" if not something that varies?

    If I define `function f(x) { ... }`, even if I don't reassign x within the function, the function can get called with different argument values. So from the function's perspective, x takes on different values across different calls/invocations/instances.

  • 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 (for this piece of code) always saying $10. That's not a variable it's a constant. 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.

    However for each time this function runs we do also need to get the customer ID. The customer ID will vary each time this function runs, as different customers check out their purchases, but it does not mutate during function execution like that total earlier, in Rust these variables don't need an annotation, this is the default. In C you'd ideally want to label these "const" which is the confusing name C gives to immutable variables.

  • How fast this got to the top, you would think John Carmack just invented nuclear fusion.
  • People worship this guy, but other than being a good C++ graphics programmer, it isn't clear what he's actually done.
  • Sometimes it's nice to be reminded of some basic good ideas. Even if you already know. Also https://xkcd.com/1053/
  • Just like AGI he was supposedly brought on board for but…..checks notes. Nothing.
  • Right? This isn't even a hot take - it's just standard software engineering advice we all learn in school or on the job.