caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: John Prevost <j.prevost@cs.cmu.edu>
To: Max Kirillov <max630@mail.ru>
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] static variables in a function
Date: 15 Jun 2002 12:14:09 -0400	[thread overview]
Message-ID: <86y9dgo6y6.fsf@laurelin.dementia.org> (raw)
In-Reply-To: <20020615215124.C1425@max.home>

>>>>> "mk" == Max Kirillov <max630@mail.ru> writes:

    mk> Oh, thank you for clarification. I'm very new to functional
    mk> programming, and didn't know yet about tricks like this. As I
    mk> understand, the point was to call 'ref' at initialization
    mk> stage. I thought about using 'lazy' for that, but still placed
    mk> it inside a full function definition, so it didn't help.

    mk> This makes a possibility to write very funny functions. For
    mk> example:

# let acc v =
    let vR = ref v in
    fun f -> 
            let newV = f !vR in
          vR := newV;
          newV  ;;

    mk> I'm not sure if this style of coding better than placing the
    mk> mutable values to be hidden inside modules or classes. Even
    mk> when possible (in other languages), I prefer to use latter way
    mk> to do. Well it's a matter of taste.

It also depends precisely what you're trying to do.  In the case we
first saw (we have a specific function that wants to have an input
buffer, essentially), I'm not sure it makes a great amount of sense.
The problem is that using a variable in the closure doesn't help do
anything except hide the value from the rest of the module.  And,
well, we'd probably be better off leaving it open to the module and
using the module interface to hide it from other modules.

If we change our focus, howeverm the technique becomes more
interesting.  Take a look at this, for example:

type 'a memoval =
  | Val of 'a
  | Exn of exn

let memoize f =
  let stow = Hashtbl.create 20 in
  fun x -> begin
    if not (Hashtbl.mem stow x) then begin
      try (let v = f x in Hashtbl.replace stow x (Val v))
        with e -> Hashtbl.replace stow x (Exn e)
     end;
    match Hashtbl.find stow x with
      | Val x -> x
      | Exn e -> raise e
  end

(* this is the fibonacci sequence, but we delaying "binding" the
   recursion until later. *)
let fib' fib' =
  function
    | 0 -> 1
    | 1 -> 1
    | n -> fib' (n-1) + fib' (n-2);;

(* example of how to bind the recursion in a simple way *)
let rec fib_r1 x =
  fib' fib_r1 x

(* and now binding it "through" the memoize function *)
let rec fib_r2 x =
  memoize (fib' fib_r2) x

In this case, the whole point of the function is that it produces a
function identical in every way to the original function, except that
it memoizes its work so as not to repeat.  There's no convenient
"object" to stuff the value into, because the function *is* our
object.  The only way we can store the data correctly is to have the
information somehow attached to the function we're creating.

There are a number of places where this is useful.  The key insight is
that in a functional language, the primary objects in the system are
functions, and this mechanism we're using above is simply what happens
when a variable goes out of scope for everything except the function
in question.

JOhn.
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


  reply	other threads:[~2002-06-15 16:08 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-06-14 17:08 Shannon --jj Behrens
2002-06-14 17:40 ` Stefano Zacchiroli
2002-06-14 17:58 ` Yutaka OIWA
2002-06-14 20:43   ` Shannon --jj Behrens
2002-06-15  4:42   ` Max Kirillov
2002-06-15  6:36     ` John Prevost
2002-06-15 14:51       ` Max Kirillov
2002-06-15 16:14         ` John Prevost [this message]
2002-06-15 19:19           ` Max Kirillov
2002-06-15 23:16             ` John Prevost
2002-06-16 23:19             ` Remi VANICAT
2002-06-17 13:56               ` [Caml-list] Memoizing (was: static variables...) Benedikt Rosenau
2002-06-18  8:40                 ` William Lovas
2002-06-18  9:16                   ` Jacek Chrzaszcz
2002-06-18 21:52                     ` William Lovas
2002-06-18 13:07                   ` Christopher Quinn
2002-06-18 14:07                     ` Remi VANICAT
2002-06-18 17:52                       ` Christopher Quinn
2002-06-19 14:42                   ` John Max Skaller
2002-06-23 21:18                     ` Pierre Weis
2002-06-19  4:38   ` [Caml-list] static variables in a function Shannon --jj Behrens

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=86y9dgo6y6.fsf@laurelin.dementia.org \
    --to=j.prevost@cs.cmu.edu \
    --cc=caml-list@inria.fr \
    --cc=max630@mail.ru \
    /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).