I wish the IDE would simply provide a small clue, visible but graphically unobtrusive, that it was mutated.
In fact, I end up wishing this about almost every language feature that passes my mind. For example, I don't need to choose whether I can or can't append to a list; just make it unappendable if you can prove I don't append. I don't care if it's a map, list, set, listOf, array, vector, arrayOf, Array.of(), etc unless it's going to get in my way because I have ten CPU cores and I'll optimize the loop when I need to.
Although I do agree with the sentiment of choosing a construct and having it optimize if it can. Reminds me of a Rich Hickey talk about sets being unordered and lists being ordered, where if you want to specify a bag of non-duplicate unordered items you should always use a set to convey the meaning.
It's interesting that small hash sets are slower than small arrays, so it would be cool if the compiler could notice size or access patterns and optimize in those scenarios.
It made the code easier to read because it was easier to track down what could change and what couldn't. I'm now a huge fan of the concept.
I want to be able to write `x := y` and be sure I don't have mutable slices and pointer types being copied unsafely.
A lot of code needs to assemble a result set based on if/then or switch statements. Maybe you could add those in each step of a chain of inline functions, but what if you need to skip some of that logic in certain cases? It's often much more readable to start off with a null result and put your (relatively functional) code inside if/then blocks to clearly show different logic for different cases.
  if cond:
      X = “yes”
  else:
      X = “no”
  let X = if cond { “yes” } else { “no” };
    let x: Int
    if cond {
        x = 1
    } else { 
        x = 2
    }
    // read x hereJohn Carmack on Forks
John Carmack on Coca Cola
Sorry, but this isn't even news. John Carmack's opinion doesn't validate anything. The fact it took him this long to be exposed to "mutability bad" is a bit concerning and should be part of the reasoning why you don't just absorb opinions from well known people!
Just because someone is expressing a thought after you or others have already thought about it, doesn't mean they're trying to push it as something new and exciting, it's just another perspective.
https://github.com/hsutter/cppfront/wiki/Design-note%3A-cons...
> No, he's a competent programmer.
I don't think these are mutually exclusive
If it was just his ownership that would be one thing but his aggressive support for turning the site into /pol/ has ruined it.
- if (x) { const y = true } else { const y = false } // y doesn't exist after the block - try { const x = foo } catch (e) { } // x doesn't exist after the try block
  const y = (() => {
    if (x) {
      return true;
    } else {
      return false;
  })();    const y = (x === true) ? true : false;
    Composite.prototype.SetPosition(x, y, z) {
        x = (isNumber(x) && x >= 0 && x <= 1337) ? x : null;
        y = (isNumber(y) && y >= 0 && y <= 1337) ? y : null;
        z = isNumber(z) ? z : null;
        if x !== null && y !== null && z !== null {
            // use clamped values
        }
    }  function SetPosition(x, y, z) {
    if (!(isNumber(x) && isNumber(y) && isNumber(z))) {
      // Default vals
      return;
    }
    x = clamp(x, 0, 1337);
    y = clamp(y, 0, 1337);
    z = z;
  }In JS, errors are pretty painful due to try/catch, that's why I would probably these days recommend to use Effect [1] or similar libraries to have a failsafe workflow with error cases.
Errors in general are pretty painful in all languages in my opinion. The only language where I thought "oh this might be nice" was Koka, where it's designed around Effect Types and Handlers [2]
const y = x ? true : false;
val result = if (condition) { val x = foo() y = bar(x) y + k // return of last expression is return value of block } else { baz() }
Or:
val q = try { a / b } catch (e: ArithmeticException) { println("Division by zero!") 0 // Returns 0 if an exception occurs }
Edit: ugh, can't get the formatting to work /facepalm.
It can be perfectly fine to use mutable variables within a block, like a function when absolutely needed - for example, in JavaScript's try catch and switch statements that need to set a variable for later use. As long as these assignments are local to that block, the larger code remains side-effect free and still easy to reason about, refactor and mantain.
https://rockthejvm.com/articles/what-is-referential-transpar...
Oh well continues day job as a Clojure programmer that is actively threatened by an obnoxious python take over
munchler•5h ago
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 F# for starters. I switched and never looked back.
Terr_•5h ago
This creates friction between casual stakeholder models of a mutable world, versus the the assumptions an immutable/mostly-pure language imposes. When the customer describes what they need, that might be pretty close to a plain loop with a variable that increments sometimes and which can terminate early. In contrast, it maps less-cleanly to a pure-functional world, if I'm lucky there will at least be a reduce-while utility function, so I don't need to make all my own recursive plumbing.
So immutability and pure-functions are like locking down a design or optimizing--it's not great if you're doing it prematurely. I think that's why starting with mutable stuff and then selectively immutable'ing things is popular.
Come to think of it, something similar can be said about weak/strong typing. However the impact of having too-strong typing seems easier to handle with refactoring tools, versus the problem of being too-functional.
Freedom2•5h ago
jeffreygoesto•25m ago
But [0] is never possible.
josephg•5h ago
Rust is also like this (let x = 5; / let mut x = 5;).
Or you can also use javascript, typescript and zig like this. Just default to declaring variables with const instead of let / var.
Or swift, which has let (const) vs var (mutable).
FP got there first, but you don't need to use F# to have variables default to constants. Just use almost any language newer than C++.
bathtub365•3h ago
orlp•8m ago
snalty•4m ago
umanwizard•5m ago
Fire-Dragon-DoL•1h ago
eitland•7m ago
[1]: https://www.baeldung.com/java-final
[2]: https://www.baeldung.com/java-immutable-list
ehsankia•5h ago
Python has a lot of functional-like patterns and constructs, but it's not a pure functional language. Similarly, Python these days allow you to adds as much type information as you want which can provide you a ton of static checks, but it's not forced you like other typed languages. If some random private function is too messy to annotate and not worth it, you can just skip it.
I like the flexibility, since it leads to velocity and also just straight up more enjoyable.
tasn•5h ago
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), so a pure first approach ends up being weird for many people.
At least based on my experience.
rapind•4h ago
Maybe they're right about the syntax too though? :)
kragen•4h ago
nickpeterson•2h ago
kragen•4h ago
tayo42•4h ago
kragen•3h ago
rao-v•45m ago
C# is not that far I suppose from what I want
the__alchemist•5h ago
In particular: My brain, my computing hardware, and my problems I solve with computers all feel like a better match for time-domain-focused programming.
cogman10•4h ago
Haskell is a great example here. Last time I tried to learn it, going on the IRC channel or looking up books it was nothing but a flood of "Oh, don't do that, that's not a good way to do things." It seemed like nothing was really settled and everything was just a little broken.
I mean, Haskell has like what, 2, 3, 4? Major build systems and package repositories? It's a quagmire.
Lisp is also a huge train wreck that way. One does not simply "learn lisp" There's like 20+ different lisp like languages.
The one other thing I'd say is a problem that, especially for typed functional languages, they simply have too many capabilities and features which makes it hard to understand the whole language or how to fit it together. That isn't helped by the fact that some programmers love programming the type system rather than the language itself. Like, cool, my `SuperType` type alias can augment an integer or a record and knows how to add the string `two` to `one` to produce `three` but it's also an impossible to grok program crammed into 800 characters on one line.
v9v•42m ago
Lisp is not a language, but a descriptor for a family of languages. Most Lisps are not functional in the modern sense either.
Similarly, there are functional C-like languages, but not all C-likes are functional, and "learn c-likes" is vague the same way "learn lisp" is.
umanwizard•2m ago
jandrewrogers•5h ago
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 purity of their functional-ness than imperative languages were about their imperative-ness.
jancsika•3h ago
For some reason, this makes me think of SVG's foreignObject tag that gives a well-defined way to add elements into an SVG document from an arbitrary XML namespace. Display a customer invoice in there, or maybe a Wayland protocol. The sky's the limit!
On the other hand, HTML had so many loose SVG tags scattered around the web that browsers made a special case in the parser to cover them without needing a namespace.
And we all know how that played out.
Posted from an xhtml foreignObject on my SVGphone
Fire-Dragon-DoL•1h ago
black_knight•35m ago
Also, the STM monad is the most carefree way of dealing with concurrency I have found.
christophilus•35m ago
keeda•5h ago
My bet is functional programming will become more and more prevalent as people figure out how to get AI-assisted coding to work reliably. For the very reasons you stated, functional principles make the code modular and easy to reason about, which works very well for LLMs.
However, precisely because functional programming languages are less popular and hence under-represented in the training data, AI might not work well with them and they will probably continue to remain fringe.
charcircuit•4h ago
umanwizard•4h ago
brrrrrm•4h ago
dropping down into the familiar or the simple or the dumb is so innately necessary in the building process. many things meant to be "pure" tend to also be restrictive in that regard.
runevault•4h ago
johncolanduoni•4h ago
Also, category theorists think how excited people get about using the word monad but then most don’t learn any other similar patterns (except maybe functors) is super cringe. And I agree.