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";
}
Your example contains a few things that would work differently in a functional language:
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.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).
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With