caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Strange syntax used in queue.ml -- The "<-" operator
@ 2011-01-20 16:53 Andrew
  2011-01-20 17:43 ` bluestorm
  0 siblings, 1 reply; 3+ messages in thread
From: Andrew @ 2011-01-20 16:53 UTC (permalink / raw)
  To: caml-list

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! 


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Caml-list] Strange syntax used in queue.ml -- The "<-" operator
  2011-01-20 16:53 [Caml-list] Strange syntax used in queue.ml -- The "<-" operator Andrew
@ 2011-01-20 17:43 ` bluestorm
  2011-01-20 19:44   ` bluestorm
  0 siblings, 1 reply; 3+ messages in thread
From: bluestorm @ 2011-01-20 17:43 UTC (permalink / raw)
  To: Andrew; +Cc: caml-list

[-- Attachment #1: Type: text/plain, Size: 4671 bytes --]

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: 6495 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Caml-list] Strange syntax used in queue.ml -- The "<-" operator
  2011-01-20 17:43 ` bluestorm
@ 2011-01-20 19:44   ` bluestorm
  0 siblings, 0 replies; 3+ messages in thread
From: bluestorm @ 2011-01-20 19:44 UTC (permalink / raw)
  To: Andrew; +Cc: caml-list

[-- 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 --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2011-01-20 19:44 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-20 16:53 [Caml-list] Strange syntax used in queue.ml -- The "<-" operator Andrew
2011-01-20 17:43 ` bluestorm
2011-01-20 19:44   ` bluestorm

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).