caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: John Prevost <jprevost@panasas.com>
To: "David McClain" <barabh@qwest.net>
Cc: <caml-list@inria.fr>
Subject: Re: [Caml-list] Error Reporting
Date: 30 Sep 2001 20:52:31 -0400	[thread overview]
Message-ID: <jkg0945ghc.fsf@kinsman.panasas.com> (raw)
In-Reply-To: <004401c1483d$8d1bd160$210148bf@dylan>

>>>>> "dm" == David McClain <barabh@qwest.net> writes:

    dm> I must confess that I don't understand this statement...

    dm> Let's take a trivial example of a sequence of 3 "primitive"
    dm> operations -- a primitive operation being one which cannot
    dm> make use of a continuation argument.

    dm> Normal OCaml syntax for such a function would be:

    dm> let seqFn () = aFn (); bFn (); cFn ()

    dm> Now let's write what the compiler would translate this
    dm> into....

    dm> let cPart () kont = cFn (); kont ()

    dm> let bPart () kont = bFn (); cPart () kont

    dm> let aPart () kont = aFn (); bPart () kont

This is a very specific for of tail calls where no continuation has
any argument--and yet, your assertion that you don't know anything
about history is incorrect.

The continuation passed to each function is very similar to a stack
frame.  Let's look at a more interesting example:

let plus a b = a + b
let mult a b = a * b
let a = plus (mult 3 5) (plus 8 (mult 7 10))

a CPS conversion of this would be:

let plus a b k = k (a + b)
let mult a b k = k (a * b)
let a = mult 3 5
       (fun x -> mult 7 10
         (fun y -> plus 8 y
          (fun z -> plus x z
           (fun w -> w))))

In this case, we see that the continuations are a bit more
interesting.  For a start, they take non-unit arguments.  Then we can
notice the dependencies between them.  Each application takes the code
to be run when the call "returns".  Now imagine this version of your
original code.  First, let's make aFn and friends be written in CPS
instead of somehow being outside it (the other bothersome thing about
your example):

val aFn : (unit -> 'a) -> unit -> 'a
val bFn : (unit -> 'a) -> unit -> 'a
val bFn : (unit -> 'a) -> unit -> 'a

(* example:
    let aFn k () = Printf.printf "a\n"; k () *)

let seqFn k = aFn (bFn (cFn k))

let program = seqFn id

program () results in:
a
b
c


This is a more realistic example of continuations in action.  Now, we
can extend this in a useful way!


let cont d f = (d,f)
let app (_,f) = f
let desc (d,_) = d

let aFn k () = Printf.printf "a (will return to %s)\n" (desc k); app k ()
let bFn k () = Printf.printf "b (will return to %s)\n" (desc k); app k ()
let cFn k () = Printf.printf "c (will return to %s)\n" (desc k); app k ()


let seqFn k =
  let seqFn_cont lineno f =
    cont ("seqFn (line " ^ string_of_int lineno ^ ")") f
  in
    aFn (seqFn_cont 2 (bFn (seqFn_cont 3 (cFn k))))

let program = seqFn (cont "main program" id)

program () results in:

a (will return to seqFn (line 2))
b (will return to seqFn (line 3))
c (will return to main program)


Again--these continuations are *just like stack frames*.  The only
difference is that in CPS they are treated as explicit manipulable
values.  In fact, SML/NJ uses continuations internally allocated on
the heap, rather than using a normal stack.

The right way to think about things is probably that a stack is, in
fact, a very simple continuation system which does not allow
continuations to be used in any way other than LIFO.


John.
-------------------
Bug reports: http://caml.inria.fr/bin/caml-bugs  FAQ: http://caml.inria.fr/FAQ/
To unsubscribe, mail caml-list-request@inria.fr  Archives: http://caml.inria.fr


  reply	other threads:[~2001-10-01  7:14 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-09-28 16:49 David McClain
2001-10-01  0:52 ` John Prevost [this message]
2001-10-01 14:17 ` Frank Atanassow
2001-10-01 15:44   ` David McClain
  -- strict thread matches above, loose matches on Subject: below --
2001-09-27 13:32 Krishnaswami, Neel
2001-09-27 20:36 ` David McClain
2001-09-28 15:24   ` Frank Atanassow
2001-09-28 16:41     ` David McClain
2001-09-27 22:34 ` David McClain
2001-09-27 13:00 Damien Doligez
2001-09-26 22:55 David McClain

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=jkg0945ghc.fsf@kinsman.panasas.com \
    --to=jprevost@panasas.com \
    --cc=barabh@qwest.net \
    --cc=caml-list@inria.fr \
    /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;
as well as URLs for NNTP newsgroup(s).