An addendum for "ref" patterns. They're not a specific syntacitc sugar, but are actually genuine mutable variant types: type 'a ref = ref of mutable 'a In Caml Light (but not in OCaml), variant constructor may begin with a lowercase. "ref" (as a term) is therefore the constructor for the ref type, and can be naturally used when a pattern matching. It also appears as a function (ref : 'a -> 'a ref) because Caml Light, like Haskell but not OCaml, automatically turns constructors into functions. The ref type is defined here in the documentation: http://caml.inria.fr/pub/docs/manual-caml-light/node14.15.html On Thu, Jan 20, 2011 at 6:43 PM, bluestorm wrote: > The semantics of mutable fields and references has changed a lot (for good) > between Caml Light and Objective Caml. Beware that this code is Caml Light > specific -- and if you want to learn Caml, you should rather be using > Objective Caml, which is the implementation that is still maintained. > > In Objective Caml, only records fields are mutable. References are a > derived concept, the type 'a ref is defined as : > type 'a ref = { mutable contents : 'a } > > You change a mutable field with the syntax foo.bar <- baz (where "bar" is > a record field, and foo and baz are any expression, foo being of a record > type) > > In Caml Light, record fields are mutable, but sum type fields (variants) > are mutable as well; mutable variant fields are however not used here. See > http://caml.inria.fr/pub/docs/manual-caml-light/node4.6.html for > documentation. > > In Caml Light, a record may return a mutable location, akin to a lvalue in > C-like languages. For example, with the mutable variant > type foo = Foo of mutable int > you may write: > let set_foo (f : foo) (n : int) = > match f with > | Foo loc -> > loc <- n > > "foo <- bar" is used here to assign a value "bar" to a lvalue "foo" bound > in a mutable pattern. > > In your example, two mutable patterns are used : > | { tail = Cons(_, ref newtail) as oldtail } -> > > - oldtail is a mutable pattern denoting the mutable "tail" field of the > record > - (ref newtail) is a specific syntax, a pattern on references. It binds a > mutable pattern "newtail" corresponding to the location of the reference > > In other words, in Caml Light you can write the ":=" operator as such: > let prefix := r v = > match r with > | ref loc -> > loc <- v > > Hope that helps. > > On Thu, Jan 20, 2011 at 5:53 PM, Andrew wrote: > > Hello everyone, >> >> While browsing the Caml Light library for programming examples, I stumbled >> across the following code, taken from the Caml Light queue.ml file: >> >> type 'a queue_cell = >> Nil >> | Cons of 'a * 'a queue_cell ref >> ;; >> >> type 'a t = >> { mutable head: 'a queue_cell; >> mutable tail: 'a queue_cell } >> ;; >> >> let add x = function >> { head = h; tail = Nil as t } -> (* if tail = Nil then head = >> Nil >> *) >> let c = Cons(x, ref Nil) in >> h <- c; t <- c >> | { tail = Cons(_, ref newtail) as oldtail } -> >> let c = Cons(x, ref Nil) in >> newtail <- c; oldtail <- c >> ;; >> >> This implementation of FIFO data structures puzzles me. I get the general >> idea, to keep a pointer to the last entry in the structure, so that >> appending at the end is possible. This makes perfect sense to me. However, >> it's the syntax of how this is done that bugs me. >> >> Consider the following: >> >> | { tail = Cons(_, ref newtail) as oldtail } -> >> let c = Cons(x, ref Nil) in >> newtail <- c; oldtail <- c >> >> I have a problem with types here. By the type definition, "newtail" should >> be of type "'a queue cell", since it's retrieved using "Cons(_, ref >> newtail)" in the pattern matching: if I understand correctly, this would >> mean that "newtail" binds the value pointed by the second member of the >> "tail" record field (which is a reference). >> >> So what does the "newtail <- c" means? If I try to replace this statement >> by >> "(fun x -> x <- c) newtail", I get a "The identifier x is not mutable.", >> whereas the code sounds perfectly similar to the original variant to me. >> >> Would rewriting these few lines to read as follows mean the same? >> >> | { tail = Cons(_, newtail) as oldtail } -> >> let c = Cons(x, ref Nil) in >> newtail := c; oldtail <- c >> >> Taking the question one step further, what does the following code >> actually >> do? >> >> type t = Nil | Node of (t ref);; >> type box = {mutable field: t};; >> >> let poke = function >> | {field = Node(ref n)} -> n <- Nil >> | {field = Nil} -> () >> ;; >> >> let test = {field = Node(ref (Node(ref Nil)))};; >> poke test;; >> test;; >> >> Is it the same to write >> {field = Node(n)} -> n := Nil >> and >> {field = Node(ref n)} -> n <- Nil >> ? >> >> Even stranger: the following code returns "The value identifier a is >> unbound." >> let a = Nil;; >> a <- Nil;; (* The value identifier a is unbound. *) >> >> >> Could someone take the time to clarify the use of "<-" for me? The various >> examples here are pretty puzzling to me... >> Thanks! >> >> >> -- >> Caml-list mailing list. Subscription management and archives: >> https://sympa-roc.inria.fr/wws/info/caml-list >> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners >> Bug reports: http://caml.inria.fr/bin/caml-bugs >> >>