From: Max Kirillov <max630@mail.ru>
To: caml-list@inria.fr
Subject: Re: [Caml-list] static variables in a function
Date: Sun, 16 Jun 2002 02:19:02 +0700 [thread overview]
Message-ID: <20020616021902.A22564@max.home> (raw)
In-Reply-To: <86y9dgo6y6.fsf@laurelin.dementia.org>; from j.prevost@cs.cmu.edu on Sat, Jun 15, 2002 at 12:14:09PM -0400
[-- Attachment #1: Type: text/plain, Size: 2419 bytes --]
On Sat, Jun 15, 2002 at 12:14:09PM -0400, John Prevost wrote:
<...>
> If we change our focus, howeverm the technique becomes more
> interesting. Take a look at this, for example:
<...>
> let memoize f =
Hmm... this isn't executed at read time because function has
a parameter...
> 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
<...>
> let rec fib_r2 x =
> memoize (fib' fib_r2) x
The function memoize (and even "memoize (fib' fib_r2)" with
a variable first parameter) as called at every recursion
step and therefore no caching will be performed. (I've
tested it).
The working way is:
let fib_r3 = memoize fib_r1
which is, btw, very similar to
let fib_r3 = new memoize fib_r1
> 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.
Well, OO-biased programmer would say it's a good reson to
_make_ an object with only one exported method. Nearly any
programmer would say that we should make an object to
provide additional control, say, to clear the cache.
I've played with it a bit, and discover that there are many
ways to do the job. Three files attached contains three ways
of doing the same things via function returned from
initialization func (accPart.ml), commonly known OO-patterns
(accClass.ml) and modules system (accMod.ml). Tha task is to
remember a function and initial value, then sending operands
for successive applications of function.
To allow several "methods" to deal with data object we must
return several function, not just one. Moreover, we cannot
use inheritance, as we can with classes.
accMod.ml discovers generally the same features as
accClass.ml, but contains a bit more verbose writing. Maybe,
modules is not a good way to contain persistent mutable
value.
Max.
PS: maybe in version2 one could use record with labelled
things, to make it a bit nicer.
[-- Attachment #2: accPart.ml --]
[-- Type: text/plain, Size: 641 bytes --]
let p s n = print_string (s^string_of_int n^"\n"); flush stdout
(*version 1*)
let acc f init =
let vR = ref init in
let fApp x =
let newX = f !vR x in
vR := newX;
newX in
fApp
let f1 = acc (+) 0
let _ = p "f1:" (f1 1)
let _ = p "f1:" (f1 1)
let _ = p "f1:" (f1 1)
(*version 2*)
let acc' f init =
let vR = ref init in
let fApp x =
let newX = f !vR x in
vR := newX;
newX
and fIni x = (vR := x) in
(fApp,fIni)
let (f1a,f1i) = acc' (+) 0
let _ = p "f1a:" (f1a 1)
let _ = p "f1a:" (f1a 1)
let _ = p "f1a:" (f1a 1)
let _ = f1i (-5)
let _ = p "f1a:" (f1a 1)
let _ = p "f1a:" (f1a 1)
let _ = p "f1a:" (f1a 1)
[-- Attachment #3: accClass.ml --]
[-- Type: text/plain, Size: 667 bytes --]
let p s n = print_string (s^string_of_int n^"\n"); flush stdout
(*version 1*)
class ['a,'b] acc f init = object
val mutable v = (init:'a)
val func = (f:'a -> 'b -> 'a)
method app x =
let newX = func v x in
v <- newX;newX
end
let f1 = new acc (+) 0
let _ = p "f1:" (f1#app 1)
let _ = p "f1:" (f1#app 1)
let _ = p "f1:" (f1#app 1)
(*version 2*)
class ['a,'b] acc' f init = object
inherit ['a,'b] acc f init
method init x = v <- x
end
let f2 = new acc' (+) 0
let _ = p "f2:" (f2#app 1)
let _ = p "f2:" (f2#app 1)
let _ = p "f2:" (f2#app 1)
let _ = f2#init (-5)
let _ = p "f2:" (f2#app 1)
let _ = p "f2:" (f2#app 1)
let _ = p "f2:" (f2#app 1)
[-- Attachment #4: accMod.ml --]
[-- Type: text/plain, Size: 951 bytes --]
let p s n = print_string (s^string_of_int n^"\n"); flush stdout
module type AccArgT = sig
type t and t1
val init: t
val f: t -> t1 -> t
end
module AccArgInt(I:sig val init:int val f:int->int->int end) = struct
type t = int and t1 = int
let init = I.init and f = I.f
end
(*version 1*)
module Acc(T:AccArgT) = struct
let vR = ref T.init
let func = T.f
let app x =
let newX = func !vR x in
vR := newX;newX
end
module F1 = Acc(AccArgInt(struct let init = 0 and f = (+) end))
let _ = p "f1:" (F1.app 1)
let _ = p "f1:" (F1.app 1)
let _ = p "f1:" (F1.app 1)
(*version 2*)
module Acc1(T:AccArgT) = struct
module A = Acc(T)
include A
let init x = vR:=x
end
module F2 = Acc1(AccArgInt(struct let init = 0 and f = (+) end))
let _ = p "f2:" (F2.app 1)
let _ = p "f2:" (F2.app 1)
let _ = p "f2:" (F2.app 1)
let _ = F2.init (-5)
let _ = p "f2:" (F2.app 1)
let _ = p "f2:" (F2.app 1)
let _ = p "f2:" (F2.app 1)
next prev parent reply other threads:[~2002-06-15 19:21 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
2002-06-15 19:19 ` Max Kirillov [this message]
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=20020616021902.A22564@max.home \
--to=max630@mail.ru \
--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