MyBug18
MyBug18

Reputation: 2230

Can't understand the logic of F# mutable variable inside function body

I'm learning F# and get stuck with the concept of mutable keyword.

Please see the below example:

let count =
    let mutable a = 1
    fun () -> a <- a + 1; a

val count: unit -> int

Which increases by 1 every time it's called with (). But next code does not:

let count =
    let mutable a = 1
    a <- a + 1
    a

val count: int

Which is always 2.

In the book I'm studying with, it says with the first example, "The initialization of mutable value a is done only once, when the function has called first time."

When I started learning FP with haskell, the way it handled side effects like this totally burnt my brain, but F# mutable is destroying my brain again, with a different way. What's the difference between above two snippets? And, what's the true meaning and condition of above sentence, about the initialization of mutable value?

Upvotes: 1

Views: 161

Answers (2)

Lee
Lee

Reputation: 144126

Your second example

let count =
    let mutable a = 1
    a <- a + 1
    a

Defines a mutable variable initialised to 1, then assigns a new value (a + 1) to it using the <- operator before returning the updated value on the last line. Since a has type int and this is returned from the function the return type of the function is also int.

The first example

let count =
    let mutable a = 1
    fun () -> a <- a + 1; a

also declares an int a initialised to 1. However instead of returning it directly it returns a function which closes over a. Each time this function is called, a is incremented and the updated value returned. It could be equivalently written as:

let count =
    let mutable a = 1
    let update () =
        a <- a + 1
        a
    update

fun () -> ... defines a lambda expression. This version returns a 1-argument function reflected in the different return type of unit -> int.

Upvotes: 6

dumetrulo
dumetrulo

Reputation: 1991

The first example of count initializes a mutable variable, and returns a closure around this variable. Every time you call that closure, the variable is increased, and its new value returned.

The second example of count is just an initialization block that sets the variable, increases it once, and returns its value. Referring to count again only returns the already computed value again.

Upvotes: 3

Related Questions