0
$\begingroup$

Functional programming does not have mutation. Mutation is usually harmful, however mutation is sometimes beneficial. e.g. Creating a [random number] generator.

In the same way that goto is considered harmful, but now we have structured languages that give us access to a safe set of goto patterns. Is there a safe set of mutation patterns? Is there currently any research into language features that implement them?

$\endgroup$
  • $\begingroup$ Asking for programming languages is offtopic here; removing that part. $\endgroup$ – Raphael Sep 20 '17 at 17:39
  • $\begingroup$ Short answer "monad", especially "state monad" are the pattern used in functional programming that allows "side effects of mutable object" to be captured in a function signature rather than hidden away. $\endgroup$ – Apiwat Chantawibul Sep 20 '17 at 21:10
  • 3
    $\begingroup$ @raphael: Why can't the OP ask for examples of the phenomenon being described? Your comment is like someone asking about NP-completeness but without being able to ask for an example of NP completeness. $\endgroup$ – Dave Clarke Sep 21 '17 at 11:12
  • 1
    $\begingroup$ @Raphael: Programming languages are computer science. $\endgroup$ – Dave Clarke Sep 21 '17 at 13:11
  • 1
    $\begingroup$ Programming languages as a field, yes. Python, Java, etc? Nope, definitely not. If that were true, we'd have to revise our scope considerably. Do you want to take this to Computer Science Meta? $\endgroup$ – Raphael Sep 21 '17 at 13:15
4
$\begingroup$

Ask not how to get rid of the evil mutable state, but rather how to tame it by provding structured and predictable ways of using it.

Just because goto is harmful you wouldn't remove all flow control from a language, right? You'd rather think of ways of using control flow in a structured way, and then you would invent the while loops.

There is not single best solution on how to structure and control mutable state, but there are some good ones. For example, you can have the programmer describe quite explicitly which part of the program can do what and who "owns" stateful parts of memory. The compiler will then check for compliance. An example of this sort of thing is Rust.

There is a more general phenomenon which encompasses mutable state, namely computational effects. Mutable state is tricky to get right, but so is concurrency, I/O can be tricky depending on what you do, etc. These are all computational effects, and we can ask whether there are general and structured ways of dealing with them.

The most popular general way of controlling computational effects is to use monads. These are programming language constructs that allow you to express presence of certain computational effects (could be mutable state) with typing information. This way the programmer will be able to see that a certain piece of code may cause effects, and the compiler will complain if things don't fit.

Another method that has caught some interest lately is algebraic effects and handlers. It's less general than monads, but it also organizes your code in a way that is often a bit more flexible than monads (The people of the Internet want to know this too.) Briefly, handlers are a generalization of the familiar exception handlers that allow you to intercept any computational effect and do something with it. I like to explain their usefulness with the slogan $$\frac{\mathtt{handlers}}{\mathtt{callcc}} = \frac{\mathtt{while}}{\mathtt{goto}}. $$ That is, just like while is the structured way to do goto, handlers are the structured way to do non-local flow control in a functional setting (callcc has been called "the goto of functional programming").

$\endgroup$
1
$\begingroup$

"Mutation considered harmful" is a pretty strong statement that many people would disagree with.

Among the group that dislikes mutation there are at least two reasons for immutability:

  1. Immutable data is automatically thread-safe
  2. Immutable data makes it easier to reason about the software.

If you want to guarantee thread safety in the presence of mutation, you could use a type system that tracks ownership and forbids mutating the same data from different threads simultaneously. Rust is a language that does this. Another option is Software Transactional Memory, that can be implemented in a number of languages.

The second objection to mutability is a lot fuzzier. People generally agree that you shouldn't share mutable state among too many parts of your software. This is inherently a software design problem that has no general solution.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.