top | item 30296911

(no title)

halpert | 4 years ago

Sorry, but state is everything. If you don’t have state, then you’re essentially doing useless work computing an answer that is already known. Computation is only useful because of state.

discuss

order

momentoftop|4 years ago

Here's a pure computation:

    import Data.List (nubBy)

    refuteGoldbach :: Integer
    refuteGoldbach = head $ [ n
                            | n <- [4,6..]
                            , not $ n `elem` [ p1 + p2 | p1 <- primesTo n, p2 <- primesTo n ]
                            ]
      where primesTo n = takeWhile (< n) $ nubBy isMultiple [2..]
            isMultiple m n = n `rem` m == 0
If you think you already know the answer to this computation, get yourself a Field's medal.

And then there are pure functions. Every time you compute a function using an input no-one has tried before, you are probably computing something that is not already known. You do this routinely even with a calculator.

Scarblac|4 years ago

And if you don't store the answer in some kind of state, it's lost and computing the pure function was useless.

linspace|4 years ago

> get yourself a Field's medal.

Unfortunately I'm over 40, otherwise I would try

lloydatkinson|4 years ago

This is a really poor take and you know it. State can exist in functional systems - as results of computations passed to other computations. Recursion where the new argument is the state.

No one was saying "don't use state" they were saying we need to adjust how we use it.

jay_kyburz|4 years ago

This is what I don't understand about the mutable vs immutable, my functions only exist to mutate state.

kinjba11|4 years ago

> only exist to mutate state

Which part of the state, and when?

Is this your program?

   // change anything, anywhere, in the entire database, the biggest state
   execute_sql(user_input)
You might want controls around that state so not anyone can change it. It might be read only for some users - that is, immutable.

Is this your program?

    log_to_database(financial_event for $5.00)
You probably want your financial logs to be immutable. Nobody should be able to mutate that $5.00 event to be $500.00.

Is this your program?

    o.foo = complex_function(...)
    ... 1000 lines later ...
    o.foo = null
    ... 1000 lines later in another file ...
    o.foo.do_stuff() // oops! foo was set to null somehow - but where?
    
The above scenario has shared state with "foo". Somewhere it was set to null somewhere. It could be set to null anywhere in your program. Good luck tracking the bug. If "foo" was immutable, you would know immediately where null came from, because it can only be initialized one time. It lowers the cognitive load, knowing that certain actions are impossible makes it easier to focus on what matters.

Is this your program?

    thing = computation()
    return thing + 2
Many program are a series of computations - fresh state is created on each line, nothing is mutated. There is no reason not to be using immutability. In fact, if immutability were throughout, a compiler wouldn't have to worry about things like aliasing.

This is all the tip of the iceberg, there are many reasons to enjoy using immutability.

https://en.wikipedia.org/wiki/Aliasing_(computing)

brabel|4 years ago

With mutable state, your function mutates state somewhere in the environment (typically a global variable or the class in which the function resides). With immutable state, your function returns an immutable value, never modifying anything. I program Java for the most part, and this is how I do most things. Mutable state is the enemy, not OOP. Some people think mutable state and OOP are inseparable but they are just looking at a definition of it that is easy to criticize. If you make every object immutable , OOP actually becomes a much nicer model to work with.