3

Is there a way in OCaml for a variable inside a function to keep its value between function calls? It should work like Pythons default argument, which is a reference to the same object in every function call or the function should rather yield and not explicitly return a value. The effect should be the following (if the function was to return natural numbers):

foo ();;
0
foo ();;
1
glennsl
  • 28,186
  • 12
  • 57
  • 75
  • 1
    Does the variable *have* to be local to the function? You can make the variable local to a module. That said, this sounds like a bad idea; ocaml encourages functional, side-effect-free programming, and this isn't that. Why do you want to do this? What's the real problem? – Eric Lippert Nov 25 '17 at 16:34
  • @EricLippert has to be local to function. Cannot be global. –  Nov 25 '17 at 16:36
  • I'm not understanding why local to a module and hidden by an interface to that module is unacceptable. How is that observationally different than local to a function? – Eric Lippert Nov 25 '17 at 16:37
  • 1
    Usually you do this by using something like a state monad. A function that somehow also takes the state (for instance as (implicit) input, and then alters the state (or passes the new state as a extra output parameter). – Willem Van Onsem Nov 25 '17 at 16:37

1 Answers1

7

Yes this is possible. You need to define a local ref outside of the closure and access its value and modify it every time the closure is used like so:

let foo =
  (* local variable x *)
  let x = ref 0 in
  (* the closure that will be named foo *)
  fun () -> let r = !x in
            x := r+1; r
gallais
  • 11,823
  • 2
  • 30
  • 63
  • 1
    Or even just `let foo = let x = ref 0 in fun () -> incr x; !x` – Yawar Nov 25 '17 at 18:44
  • 1
    Your `foo` starts counting at `1` instead of `0`. Of course you could use `-1` as the initial value for the `ref` but I'd argue it's not very elegant. – gallais Nov 25 '17 at 19:01