From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id p0KHhrTe031069 for ; Thu, 20 Jan 2011 18:43:53 +0100 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AnkBAGsDOE3RVdg2kGdsb2JhbACWBTKGBAGIDQgVAQEBAQkJDAcRBCCkfIl6gheEaC6IUgEBAwWFSwSBX4NNhXKGHYMt X-IronPort-AV: E=Sophos;i="4.60,352,1291590000"; d="scan'208,217";a="96050163" Received: from mail-qw0-f54.google.com ([209.85.216.54]) by mail1-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-MD5; 20 Jan 2011 18:43:47 +0100 Received: by qwj9 with SMTP id 9so869270qwj.27 for ; Thu, 20 Jan 2011 09:43:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:sender:in-reply-to:references:from :date:x-google-sender-auth:message-id:subject:to:cc:content-type; bh=66m/j6B6d9Vp0CMQNbsZhxsqv6g/82EMAalXRQ5xCU0=; b=srdAP3ceTtLRkEScxt9/SAozts8JNp+JVU3l1rN6xAqCxa8gonltuyRksW6YxA67be rS5ow7sfUSS/Q+1BH33elkZJsZ26RJv+8uhU1QNnhiwiNM3p9GFEf3jnZLMkOupvTxu7 4x9o44/rZquoEtuO+pwcFtFccVzeBYlT6KphU= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:sender:in-reply-to:references:from:date :x-google-sender-auth:message-id:subject:to:cc:content-type; b=kUaJxexBnuoHAgKK1adNoIFThChP/JncNN0422Tj0XJ5zkIp78hr8+VMPs7RCpHclf EGs1gy9N8dvbJl8nYxeNxhnrfj/rAS3p1gkdECg6Tpjhxr7RIsjxaUqQE6butm2G8j0P jQivJd6cverkW4G/u7cZM7mxBwuBWvipJ4HYA= Received: by 10.229.98.131 with SMTP id q3mr1955824qcn.236.1295545425844; Thu, 20 Jan 2011 09:43:45 -0800 (PST) MIME-Version: 1.0 Sender: gabriel.scherer@gmail.com Received: by 10.229.23.139 with HTTP; Thu, 20 Jan 2011 09:43:25 -0800 (PST) In-Reply-To: <4d386889.027bd80a.187c.ffffbda4@mx.google.com> References: <4d386889.027bd80a.187c.ffffbda4@mx.google.com> From: bluestorm Date: Thu, 20 Jan 2011 18:43:25 +0100 X-Google-Sender-Auth: u-x7jVt5WfClz24S0azBSXtHvwQ Message-ID: To: Andrew Cc: caml-list@inria.fr Content-Type: multipart/alternative; boundary=0016367f9c0ae5dd2a049a4aac2a Subject: Re: [Caml-list] Strange syntax used in queue.ml -- The "<-" operator --0016367f9c0ae5dd2a049a4aac2a Content-Type: text/plain; charset=ISO-8859-1 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 > > --0016367f9c0ae5dd2a049a4aac2a Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
The semantics of mutable fields and references has changed a lot (for go= od) between Caml Light and Objective Caml. Beware that this code is Caml Li= ght specific -- and if you want to learn Caml, you should rather be using O= bjective Caml, which is the implementation that is still maintained.

In Objective Caml, only records fields are mutable. Referenc= es are a derived concept, the type 'a ref is defined as :
=A0= =A0type 'a ref =3D { mutable contents : 'a }

You change a mutable field with the syntax =A0 foo.bar <- baz (where &qu= ot;bar" is a record field, and foo and baz are any expression, foo bei= ng of a record type)

In Caml Light, record fields = are mutable, but sum type fields (variants) are mutable as well; mutable va= riant fields are however not used here. See=A0http://caml.inria.fr/pub/docs/man= ual-caml-light/node4.6.html=A0for 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=
=A0=A0type foo =3D Foo of mutable int
you may write:
=A0=A0let set_foo (f : foo)=A0(n : int) =3D
=A0=A0 =A0match = f with
=A0=A0 =A0| Foo loc ->
=A0=A0 =A0 =A0 loc <= ;- n

"foo <- bar" is used here to ass= ign a value "bar" to a lvalue "foo" bound in a mutable = pattern.

In your example, two mutable patterns are used :
<= div>=A0=A0 =A0 | { tail =3D Cons(_, ref newtail) as oldtail } ->
=

- oldtail is a mutable pattern denoting the mutable "tail" f= ield of the record
- (ref newtail) is a specific syntax, a patter= n on references. It binds a mutable pattern "newtail" correspondi= ng to the location of the reference

In other words, in Caml Light you can write the ":= =3D" operator as such:
=A0=A0let prefix :=3D r v =3D
=A0=A0 =A0match r with
=A0=A0 =A0| ref loc ->
=A0= =A0 =A0 =A0loc <- v

Hope that helps.

On Thu, Jan 20, 2011 at 5:53 PM, Andrew=A0<newsgroups.fr@gm= ail.com>=A0wrote:
Hello everyone,

While browsing the Caml Light library for programmin= g examples, I stumbled
across the following code, taken from the Caml Li= ght=A0queue.ml=A0file:
=A0 =A0type 'a queue_cell =3D
=A0 =A0 =A0 =A0Nil
=A0 =A0 =A0| Con= s of 'a * 'a queue_cell ref
=A0 =A0;;

=A0 =A0type 'a = t =3D
=A0 =A0 =A0{ mutable head: 'a queue_cell;
=A0 =A0 =A0 =A0mu= table tail: 'a queue_cell }
=A0 =A0;;

=A0 =A0let add x =3D function
=A0 =A0 =A0 =A0{ head =3D h; tail =3D = Nil as t } -> =A0 =A0(* if tail =3D Nil then head =3D Nil
*)
=A0 = =A0 =A0 =A0 =A0let c =3D Cons(x, ref Nil) in
=A0 =A0 =A0 =A0 =A0 =A0h &l= t;- c; t <- c
=A0 =A0 =A0| { tail =3D Cons(_, ref newtail) as oldtail= } ->
=A0 =A0 =A0 =A0 =A0let c =3D Cons(x, ref Nil) in
=A0 =A0 =A0 =A0 =A0 =A0= newtail <- c; oldtail <- c
=A0 =A0;;

This implementation of= FIFO data structures puzzles me. I get the general
idea, to keep a poin= ter to the last entry in the structure, so that
appending at the end is possible. This makes perfect sense to me. However,<= br>it's the syntax of how this is done that bugs me.

Consider th= e following:

=A0 =A0 =A0| { tail =3D Cons(_, ref newtail) as oldtail= } ->
=A0 =A0 =A0 =A0 =A0let c =3D Cons(x, ref Nil) in
=A0 =A0 =A0 =A0 =A0 =A0= newtail <- c; oldtail <- c

I have a problem with types here. B= y 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 wou= ld
mean that "newtail" binds the value pointed by the second m= ember 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 pe= rfectly similar to the original variant to me.

Would rewriting these few lines to read as follows mean the same?
=A0 =A0 =A0| { tail =3D Cons(_, newtail) as oldtail } ->
=A0 =A0 = =A0 =A0 =A0let c =3D Cons(x, ref Nil) in
=A0 =A0 =A0 =A0 =A0 =A0newtail = :=3D c; oldtail <- c

Taking the question one step further, what does the following code actually=
do?

=A0 =A0type t =3D Nil | Node of (t ref);;
=A0 =A0type box =3D= {mutable field: t};;

=A0 =A0let poke =3D function
=A0 =A0 =A0| {= field =3D Node(ref n)} -> n <- Nil
=A0 =A0 =A0| {field =3D Nil} -&= gt; ()
=A0 =A0;;

=A0 =A0let test =3D {field =3D Node(ref (Node(re= f Nil)))};;
=A0 =A0poke test;;
=A0 =A0test;;

Is it the same to write
=A0 = =A0{field =3D Node(n)} -> n :=3D Nil
and
=A0 =A0{field =3D Node(re= f n)} -> n <- Nil
?

Even stranger: the following code retur= ns "The value identifier a is
unbound."
=A0 =A0let a =3D Nil;;
=A0 =A0a <- Nil;; (* The val= ue identifier a is unbound. *)


Could someone take the time to cl= arify the use of "<-" for me? The various
examples here are= pretty puzzling to me...
Thanks!


--
Caml-list mailing list. = =A0Subscription management and archives:
https://sympa-roc.inria.fr/wws= /info/caml-list
Beginner's list:=A0http://groups.yahoo.com/group/ocaml_beginnersBug reports:=A0http://caml.inria.fr/bin/caml-bugs

--0016367f9c0ae5dd2a049a4aac2a--