Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning a function with a closure

Tags:

f#

The following code:

let CreateFunc=
    let counter = ref 0
    fun () -> counter := !counter + 1; !counter

let f1 = CreateFunc
let f2 = CreateFunc

printfn "%d" (f1())
printfn "%d" (f1())
printfn "%d" (f2())
printfn "%d" (f2())

Outputs:

1
2
3
4

So, basically, what we see here is f1 and f2 being the same function - as they're obviously sharing the same instance of 'counter'.

The expected output is:

1
2
1
2

QUESTION: Shouldn't f1 and f2 be two separate instances? After all they are created by the two different calls to 'CreateFunc'???

Thanks

like image 267
ay.metallo Avatar asked Nov 08 '11 10:11

ay.metallo


People also ask

How do you return a closure from a function?

In the same way that you can pass a closure to a function, you can get closures returned from a function too. The syntax for this is a bit confusing a first, because it uses -> twice: once to specify your function's return value, and a second time to specify your closure's return value.

Can you return from a closure?

Closures can also return values, and they are written similarly to parameters: you write them inside your closure, directly before the in keyword.

Can closure return value Swift?

Swift's closures can return values as well as take parameters, and you can use those closures in functions. Even better, those functions can also return values, but it's easy for your brain to get a bit fuzzy here because there's a lot of syntax.

What is a closure in Javascript How does it work?

A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function's scope from an inner function.


1 Answers

let CreateFunc() =
    let counter = ref 0
    fun () -> counter := !counter + 1; !counter

let f1 = CreateFunc()
let f2 = CreateFunc()

printfn "%d" (f1())
printfn "%d" (f1())
printfn "%d" (f2())
printfn "%d" (f2())

Output is

1
2
1
2

Explanation:

In your original solution, CreateFunc was a function, but always the same function (CreateFunc, f1 and f2 were all synonyms, all pointing to the same function). In my solution CreateFunc is a function which returns a new function whenever it is called, thus each function has its own state (i.e. counter).

In short: the original CreateFunc was a value, always the same value.

like image 62
Ramon Snir Avatar answered Sep 22 '22 17:09

Ramon Snir