4 ms·
I like to think of mutation as a performance optimisation. Correctness first, then optimisation. Unless performance is a problem, don't ever mutate state.
by maxeonyx 6y 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.
- nyanpasu64 6y agoMutation 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.
- waynesonfire 6y agoYou 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.
- lmm 6y agoYou 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.
- blub 6y agoPlease post the lens code here so that we may judge how expressive it is :)
- lmm 6y agoWith 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?
- blub 6y agoThank 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?
- lmm 6y agoThe 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.
- nyanpasu64 6y agoI've heard about lenses, but never actually worked with them. This syntax seems to construct a "path" of sorts from the root to a field. What language is this? What type does the `set` operator/keyword return?
- lmm 6y agoIt's Scala with Monocle (and it's off the top of my head, so apologies for any mistake). `set` usually returns a function for transforming values of the root type, but this simplified syntax will apply it immediately to `config`, so it'll return a copy of config with the modification applied to it.
- beders 6y agoI suggest you check out efficient mutable data-structures which are safe by default. Clojure and ClojureScript come to mind.
- UncleMeat 6y agoThey are still less efficient. Compare even modern stuff like HAMTs to ordinary sets. Close, but no cigar.