Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: Jacques Garrigue <garrigue@math.nagoya-u.ac.jp>
To: pedagand@gmail.com
Cc: caml-list@yquem.inria.fr
Subject: Re: [Caml-list] "Ref" and copy of functions
Date: Sun, 16 Dec 2007 14:17:25 +0900 (JST)	[thread overview]
Message-ID: <20071216.141725.55512483.garrigue@math.nagoya-u.ac.jp> (raw)
In-Reply-To: <6cb897b30712130927m7df88e3axec56eacba4d47fdf@mail.gmail.com>

From: "Pierre-Evariste Dagand" <pedagand@gmail.com>

> I'm looking for advices about a "clean way" of doing something which,
> by design, isn't. So, let states the problem.
> 
> I'm doing a combinator library based on Arrows for a Yampa-like system :
> 
> type ('a,'b) arrow = Arrow of ( 'a -> 'b )

[...]

> But now, I would like to be able to "copy" a built arrow and to be
> able to execute the copy without side-effecting on the first one.
> Obviously, I cannot do that in this implementation.

Here is yet another solution, using objects, which actually combines
Zheng's and Oleg's ideas. That is, it separates state and function,
but provides only access to state through a cloning method, so that it
is completely type safe. This is just what objects are good at!

class ['a,'b] arrow (f : 'a -> 'b) =
  object (self) method call = f method copy = self end

let (>>>) rf rg : ('a,'b) arrow =
  object
    val rf : ('a,'c) arrow = rf
    val rg : ('c,'b) arrow = rg
    method call x = rg#call (rf#call x)
    method copy = {< rf = rf#copy; rg = rg#copy >}
  end

let loop init rf : ('b,'c) arrow =
  object
    val mutable state = init
    val rf : ('a*'b,'a*'c) arrow = rf
    method call x =
      let state', y = rf#call (state, x) in
      state <- state'; y
    method copy = {< rf = rf#copy >}
  end

let arr = new arrow
let arr_counter = loop 0 (arr (fun (counter,x) -> counter+1, counter+x))
let arr_double = arr (fun x -> 2*x)
let arr_my_small_arrow = arr_counter >>> arr_double

The key here is the {< ... >} construct, which creates a shallow copy
of an object, eventually with some fields changed. As a result, in
loop there is no need to handle the state explicitly: the state field
in the copied object will be distinct from the state field in the
original object. On the other hand, you must explicitly update fields
holding arrows, since the copy is shallow. Note that the explicit
"val" fields are needed to allow updating their contents when copying.

One difference with Oleg's approach is that we take a copy of the
original object, rather than creating a completely new record. In this
case, this doesn't mean much, since there is no extra computation
involved. Still, the state after copying is not the original but the
current one. And this may matter more if the construction is more
complicated.

Jacques Garrigue


  parent reply	other threads:[~2007-12-16  5:17 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-12-13 17:27 Pierre-Evariste Dagand
2007-12-14 10:49 ` Zheng Li
2007-12-14 14:51   ` [Caml-list] " David Teller
2007-12-14 16:19     ` Zheng Li
2007-12-14 14:54   ` [Caml-list] " Pierre-Evariste Dagand
2007-12-14 16:12     ` Zheng Li
2007-12-14 16:55       ` [Caml-list] " Pierre-Evariste Dagand
2007-12-14 16:30     ` Loup Vaillant
     [not found]       ` <6cb897b30712140848j52e5628avbf0e3dadcb771f71@mail.gmail.com>
2007-12-14 16:57         ` Pierre-Evariste Dagand
2007-12-16  5:17 ` Jacques Garrigue [this message]
2007-12-16 16:39   ` [Caml-list] " Pierre-Evariste Dagand
2007-12-16 18:27     ` Pierre-Evariste Dagand

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=20071216.141725.55512483.garrigue@math.nagoya-u.ac.jp \
    --to=garrigue@math.nagoya-u.ac.jp \
    --cc=caml-list@yquem.inria.fr \
    --cc=pedagand@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