Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

represent stateful things in functional languages

I've been playing around with functional languages (F# in particular) and am really liking the whole immutable/concept. However, I'm a bit lost on how you're suppose to represent stateful things in functional languages.

For example, how would one rewrite the following in a functional language? (any functional language is fine... just need to wrap my head around it)

class state
{
    int current_time;
    bool is_completed() { 
        return current_time() - start_time > 30 seconds
    }
    double get_progress() { 
        return (current_time() - start_time) / 30 seconds
    }
    void start() {
        start_time = current_time();
    }
}
void main() {
    state s;
    s.start();
    while(s.is_completed() == false) { 
          print s.get_progress();
    }
    print "finished";
}
like image 298
jameszhao00 Avatar asked Jun 19 '11 00:06

jameszhao00


2 Answers

Your example contains a few things that would work differently in a functional language:

  • The class is mutable - in functional languages, you would use an immutable type
  • You're using current_time to get the current time, but this is not a pure function (it depends on some global changing state). In pure functional languages (Haskell), this is not allowed (and you have to use monads), but most of the impure functional languages (F#, OCaml) allow this.
  • Your main function uses a loop - loops are generally discouraged in functional languages (although some support them).

The idiomatic F# solution would deal with the first and the last point like this:

let currentTime() =
  System.DateTime.Now

type State(startTime) =
  static member Start() =
    State(currentTime())
  member x.IsCompleted =
    (currentTime() - startTime).TotalSeconds > 30.0
  member x.Progress =
    (currentTime() - startTime).TotalSeconds / 30.0

let main() =
  let s = State.Start()
  let rec loop () =
    if not s.IsCompleted then
      printf "%A" s.Progress
      loop ()
  loop ()
  printf "finished"

The type State is immutable in the sense that it never changes the value of its local field. It is not purely functional, because it depends on the (changing) current time, but that's not a problem in F# (you just have to be aware of that). If you needed some method that modifies the state (which you don't) then the method would return a new instance of State (just like .NET string).

The main function is written using recursion instead of a loop - in this case, it doesn't really matter (loop would be fine in F# too). The point of using a recursion is that you could pass the current state as an argument and use a new instance when making a recursive call (which essentially changes the current state during the computation).

like image 81
Tomas Petricek Avatar answered Sep 28 '22 08:09

Tomas Petricek


I'm a bit lost on how you're suppose to represent stateful things in functional languages.

Ultimately, the computers we commonly use are stateful things. Programming languages have to cope with this fact at some level, or forego some of the abilities of their host computer.

FP languages deal with this fact by either:

  • Allowing you to write functions that take state, and produce new state (therefore making the function stateless)
  • Wrapping the stateful concept in a Monad (or in F#, a Computation Expression)

As for your code, you'd want to look at the first of these options. Rewrite your functions to accept the current time as an argument.

like image 39
Merlyn Morgan-Graham Avatar answered Sep 28 '22 06:09

Merlyn Morgan-Graham