stumped
stumped

Reputation: 3293

Ocaml refs not retaining its value

(* junk.ml *)
let flag = ref false

let get_flag = !flag

let play_cards card =
    Printf.printf "%s-clause\n" (if card >= 27 && card <= 39 then "true" else "false");
    (flag := if card >= 27 && card <= 39 then true else !flag);
    Printf.printf "check: %B  " get_flag;

In utop, I imported junk.ml and received this output

val flag : bool ref = {contents = false} val get_flag : bool = false val play_cards : int -> unit = <fun>

I called play_cards 30;; and received this output:

true-clause
check: true - : unit = ()

However, when I called get_flag I received false. I was wondering if there is a concept of using refs that I misunderstood while writing this code.

Upvotes: 0

Views: 574

Answers (2)

Andreas Rossberg
Andreas Rossberg

Reputation: 36088

Your code doesn't make sense as shown, hearts_broken and get_hearts_broken are never defined. If, however, you have made these definitions somewhere else, then it is no wonder you see the result you're seeing, because play_cards doesn't actually modify flag, as you seem to assume.

I guess you have renamed hearts_broken to flag at some point, but forgot to fix play_cards? And that happened to not cause an error because you didn't restart the toplevel, so that the old definition was still around?

Upvotes: 0

Jeffrey Scofield
Jeffrey Scofield

Reputation: 66818

Your variable get_flag is an immutable name for the value of !flag at the time it's defined. You shouldn't expect its value to change; OCaml variables have values that are immutable.

(Some values, like flag, are immutable names for things that themselves are mutable. In other words, flag is always going to be a name for the same reference, but the value stored in the reference, !flag, can change.)

Your comments indicate you want get_flag to have different values different times. One way to get this result is to define it as a function:

let get_flag () = !flag

Now you can call the function, and at each call it returns the value of flag at the moment of the call.

# let flag = ref false 
  let get_flag () = !flag;;
val flag : bool ref = {contents = false}
val get_flag : unit -> bool = <fun>
# get_flag ();;
- : bool = false
# flag := true;;
- : unit = ()
# get_flag ();;
- : bool = true

Upvotes: 2

Related Questions