Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
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 --]

      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