Hacker News new | ask | show | jobs
by maxeonyx 2053 days ago
I like to think of mutation as a performance optimisation. Correctness first, then optimisation.

Unless performance is a problem, don't ever mutate state.

1 comments

Mutation is not merely a performance optimization, but makes code more concise and expressive. Mutation makes things like `cfg.tabs[2].title = "Suspended"` possible to write in one line. Trying to achieve the same thing with only immutable data structures forces you to clone title, then clone cfg.tabs[2] with a new title, then clone cfg.tabs with a new [2], then clone cfg with a new tabs.
I suggest you check out efficient mutable data-structures which are safe by default. Clojure and ClojureScript come to mind.
They are still less efficient. Compare even modern stuff like HAMTs to ordinary sets. Close, but no cigar.
You don't lose conciseness with mutable state. What you seem to think is lost can be regained through abstraction.

Just think about the complexity behind the assignment operator, all the way to the logic gates in RAM.

You don't need mutation to write that expressively; you can achieve the same thing with lenses. With the advantage that if you ever get confused about what's happening you can break the lens down into what it's "really" doing and reason about that, in a way that you just can't with language-level mutation.

Syntax shortcuts are good when they're built on a rigorous foundation. But if you build a shortcut directly into the language, you'll never be able to retrofit a reasonable model for how it works.

Please post the lens code here so that we may judge how expressive it is :)
With zero effort

    cfg.lens(tabs).composeOptional(index(2)).lens(_.title) set "Suspended"
You could certainly define a shortcut to simplify the `composeOptional` part, but doing it explicitly like this makes it clear that we actually have to make an important choice: what do you want to happen when there is nothing at index 2?
Thank you. To me that seems significantly more verbose, is it possible at least to pack it into a generic function and apply it to most/all assignments?
The mixing of the array access (which is another piece of language-level special-case syntax) with the properties is what makes it verbose - "normally" you could just do something like

    config.lens(tabs[2].title) set "Suspended"
Admittedly that relies on a macro, but the macro is pretty lightweight syntax sugar - if you wanted to do it in 100% vanilla code you'd need a .lens at every step and a slightly more explicit way to name the "properties", i.e.

    config.lens(_.tabs).lens(_(2)).lens(_.title) set "Suspended"
> is it possible at least to pack it into a generic function and apply it to most/all assignments?

I don't quite understand? You can certainly write generic functions that work for any lens whose "target" is a given type.