How can you do anything useful without mutable state?

后端 未结 18 1757
栀梦
栀梦 2020-11-28 17:12

I\'ve been reading a lot of stuff about functional programming lately, and I can understand most of it, but the one thing I just can\'t wrap my head around is stateless codi

18条回答
  •  迷失自我
    2020-11-28 17:41

    Short answer: you can't.

    So what's the fuss about immutability then?

    If you're well-versed in imperative language, then you know that "globals are bad". Why? Because they introduce (or have the potential to introduce) some very hard-to-untangle dependencies in your code. And dependencies are not good; you want your code to be modular. Parts of program not influence other parts as little as possible. And FP brings you to the holy grail of modularity: no side effects at all. You just have your f(x) = y. Put x in, get y out. No changes to x or anything else. FP makes you stop thinking about state, and start thinking in terms of values. All of your functions simply receive values and produce new values.

    This has several advantages.

    First off, no side-effects means simpler programs, easier to reason about. No worrying that introducing a new part of program is going to interfere and crash an existing, working part.

    Second, this makes program trivially parallelizable (efficient parallelization is another matter).

    Third, there are some possible performance advantages. Say you have a function:

    double x = 2 * x
    

    Now you put in a value of 3 in, and you get a value of 6 out. Every time. But you can do that in imperative as well, right? Yep. But the problem is that in imperative, you can do even more. I can do:

    int y = 2;
    int double(x){ return x * y; }
    

    but I could also do

    int y = 2;
    int double(x){ return x * (y++); }
    

    The imperative compiler doesn't know whether I'm going to have side effects or not, which makes it more difficult to optimize (i.e. double 2 needn't be 4 every time). The functional one knows I won't - hence, it can optimize every time it sees "double 2".

    Now, even though creating new values every time seems incredibly wasteful for complex types of values in terms of computer memory, it doesn't have to be so. Because, if you have f(x) = y, and values x and y are "mostly the same" (e.g. trees which differ only in a few leafs) then x and y can share parts of memory - because neither of them will mutate.

    So if this unmutable thing is so great, why did I answer that you can't do anything useful without mutable state. Well, without mutability, your entire program would be a giant f(x) = y function. And the same would go for all parts of your program: just functions, and functions in the "pure" sense at that. As I said, this means f(x) = y every time. So e.g. readFile("myFile.txt") would need to return the same string value every time. Not too useful.

    Therefore, every FP provides some means of mutating state. "Pure" functional languages (e.g. Haskell) do this using somewhat scary concepts such as monads, while "impure" ones (e.g. ML) allow this directly.

    And of course, functional languages come with a host of other goodies which make programming more efficient, such as first-class functions etc.

提交回复
热议问题