Hacker News new | past | comments | ask | show | jobs | submit login

One way you could do it is by using mutable state. Impure languages, such as Scheme or Ocaml, let you use mutable like normal imperative languages do and in Haskell you can use mutable references inside some special monads (and you even ave more than one kind of mutalbe reference, depending on what monad you are on: IORef, STRef, etc)

The other way is to not use state. If you squint a bit, you can see that if you explicitly encode your "state" as function arguments you can kind of update it by calling the function recursively:

   go 0 acc = acc
   go n acc = go (n-1) (n * acc)

   fact n = go n 1
In the previous example, the code I wrote does exactly the same thing as the usual imperative loop might have done, but the accumulator is a parameter on the helper function instead of being a mutable variable.

In general, if you are OK with this kind of non-destructive updates that I used here, you can encode all your state as extra parameters that you thread around your functions. You can do this by hand in most cases but in some situations the state is very pervasive and correctly threading it around can be complex and error prone. In that case, you can look into use things like the State monad (not to be confused with the ST monad!) to do that implicitly pass that parameter around for you.




But for a game your state needs to update at specific time intervals, otherwise you walk too slow or too fast. How can that ever be purely expressed?

Personally, I would love to see more functional possibilities in imperative languages, but have regular imperative possibilities as well. E.g. running the game and keeping state seems pretty suitable for imperative code. But doing certain updates or calculations could be expressed better with functional code.


> But for a game your state needs to update at specific time intervals, otherwise you walk too slow or too fast. How can that ever be purely expressed?

In this case you want ot have a system that reacts to an event that fires on a regular interval (as well as other sorts of input events). If you search for Functional Rdeactive Programming you will find some example libraries out there that try to do this in a pure manner (although I would personally have to say that this is all still a bit on the experimental side of things).

That said, Haskell still lets you do things the imperative way if you want! All you need to do is put the impure code in the IO monad, where it belongs.

You are only forced to be purely functional if you want to or if whoever is calling you must be a pure function. So basically, the idea is that your `main` function is impure code in the IO monad and it can call either more impure code or pure "helper" functions. Increasing the percentage of your code that is pure is a nice thing but its not mandatory.


>How can that ever be purely expressed?

A loop is a recursive function. State is the arguments to the function. You pass an updated state to the next iteration of the loop. Haskell provides nice abstractions to make this seamless.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: