From: bluestorm <bluestorm.dylc@gmail.com>
To: Andrew <newsgroups.fr@gmail.com>
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] Strange syntax used in queue.ml -- The "<-" operator
Date: Thu, 20 Jan 2011 20:44:31 +0100 [thread overview]
Message-ID: <AANLkTik+by=QSW7fzaKxfYkB-DQodOf9irUrE-hc1Cpq@mail.gmail.com> (raw)
In-Reply-To: <AANLkTimX34snA9Xuiao_mjipu1Fr4--JdtqFi600=2rB@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 5552 bytes --]
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 <bluestorm.dylc@gmail.com> 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 <newsgroups.fr@gmail.com> 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
>>
>>
[-- Attachment #2: Type: text/html, Size: 7646 bytes --]
prev parent reply other threads:[~2011-01-20 19:44 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-01-20 16:53 Andrew
2011-01-20 17:43 ` bluestorm
2011-01-20 19:44 ` bluestorm [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='AANLkTik+by=QSW7fzaKxfYkB-DQodOf9irUrE-hc1Cpq@mail.gmail.com' \
--to=bluestorm.dylc@gmail.com \
--cc=caml-list@inria.fr \
--cc=newsgroups.fr@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox