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 p0KGrRBw029327 for ; Thu, 20 Jan 2011 17:53:32 +0100 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AvcAALP3N01KfVI0kGdsb2JhbACWNo4TCBUBAQEBCQkMBxEEIKRJiXqCF4RtLohSAQEDBYVLBI8u X-IronPort-AV: E=Sophos;i="4.60,352,1291590000"; d="scan'208";a="96038558" Received: from mail-ww0-f52.google.com ([74.125.82.52]) by mail1-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-MD5; 20 Jan 2011 17:53:31 +0100 Received: by wwd20 with SMTP id 20so828382wwd.9 for ; Thu, 20 Jan 2011 08:53:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:from:to:subject:date:message-id:mime-version :content-type:content-transfer-encoding:x-mailer:thread-index :content-language; bh=8YLXg+2yHrIV2Ulqk8pqkWpp718UppJDWkgbiHrc6/A=; b=p+pfL+ona5bmD5oaJR83KOO6owFeT67+eCXbh/jm87ut9fgJFzvqieAotoOmQy6DmZ gi1t8pDDs8Sq3Me4lenCFcAz6a+H19GQ/EBETd+lay6/Uv820XyyFjEyVzwqlnlCsDFD XchphTE4Zt8T/W5u+87NOk6Y9e4yPYbLTFLL8= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:subject:date:message-id:mime-version:content-type :content-transfer-encoding:x-mailer:thread-index:content-language; b=Hr8RRrloaSuLDrdF6+MA+fIgT16/KgvKSHAdB5kJtJVIvWl3+vpRzFyDGDBDJNPD3H G/gCwSRczbCTnUqgdtoEadPBebXilC+Xb7hX5nq5420LmzMqtlF5RPdtCO7ACCBgMWKr isnLkaAPMBldNWyqp/ys+VZoU1nlybBGhVhgQ= Received: by 10.216.1.145 with SMTP id 17mr2189483wed.50.1295542411405; Thu, 20 Jan 2011 08:53:31 -0800 (PST) Received: from clemlaptop (ip-43.net-81-220-116.brest.rev.numericable.fr [81.220.116.43]) by mx.google.com with ESMTPS id u2sm1747273weh.36.2011.01.20.08.53.28 (version=TLSv1/SSLv3 cipher=RC4-MD5); Thu, 20 Jan 2011 08:53:29 -0800 (PST) From: Andrew To: Date: Thu, 20 Jan 2011 17:53:28 +0100 Message-ID: <4d386889.027bd80a.187c.ffffbda4@mx.google.com> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-Mailer: Microsoft Office Outlook 12.0 Thread-Index: Acu4wo/PhoYJtL0nTgu7hYXdpxkREg== Content-Language: fr Subject: [Caml-list] Strange syntax used in queue.ml -- The "<-" operator 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!