From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by yquem.inria.fr (Postfix) with ESMTP id 3DEEABDDB for ; Sat, 27 Aug 2005 16:45:41 +0200 (CEST) Received: from pauillac.inria.fr (pauillac.inria.fr [128.93.11.35]) by concorde.inria.fr (8.13.0/8.13.0) with ESMTP id j7REje8X016585 for ; Sat, 27 Aug 2005 16:45:40 +0200 Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id QAA09487 for ; Sat, 27 Aug 2005 16:45:40 +0200 (MET DST) Received: from atreuscorp.com (p1150-ipbf213kyoto.kyoto.ocn.ne.jp [60.37.224.150]) by concorde.inria.fr (8.13.0/8.13.0) with ESMTP id j7REjbaB016582 for ; Sat, 27 Aug 2005 16:45:39 +0200 Received: from [172.31.0.52] ([172.31.0.52]) by atreuscorp.com (8.9.3/8.9.3) with ESMTP id XAA09858 for ; Sat, 27 Aug 2005 23:20:29 +0900 Message-ID: <43107BC6.2010508@andrej.com> Date: Sat, 27 Aug 2005 16:42:14 +0200 From: Andrej Bauer Reply-To: Andrej.Bauer@andrej.com User-Agent: Debian Thunderbird 1.0.2 (X11/20050331) X-Accept-Language: en-us, en MIME-Version: 1.0 To: Caml list Subject: Restarting a piece of code Content-Type: text/plain; charset=ISO-8859-2 Content-Transfer-Encoding: 7bit X-Miltered: at concorde with ID 43107C94.000 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Miltered: at concorde with ID 43107C91.000 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Spam: no; 0.00; andrej:01 andrej:01 rec:01 computes:01 exception:01 exception:01 functions:01 computation:01 computation:01 arithmetic:01 arithmetic:01 linear:02 failing:02 programming:03 raise:03 X-Spam-Checker-Version: SpamAssassin 3.0.3 (2005-04-27) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.1 required=5.0 tests=FORGED_RCVD_HELO autolearn=disabled version=3.0.3 I have a problem which I do not know how to program in The Right Way. I would be grateful to hear ideas on how to do it. Suppose I have a bunch of functions (the actual example is exact real number arithmetic) which optimistically compute results (e.g. we compute numbers up to some precision and hope it will be good enough) that may turn out not to be good enough later during the computation. When this happens, the entire computation needs to be restarted (e.g. we need to recompute the numbers again with higher precision). I will describe a specific made up example which demonstrates my point. Suppose we want to add numbers, but if we ever exceed max_value during addition, an exception is thrown: let max_value := ref 10 exception Overflow let add x y = let z = x + y in if z < !max_value then z else raise Overflow If in a computation Overflow is thrown, we want to catch it, increase max_value by some amount (say, double it), and try again. One way to do this is by wrapping the code with a "compute" function that does this: let rec compute code = try code () with Overflow -> (max_value := 2 * !max_value; compute code) To compute the sum 1 + 2 + 3 + .. + 100 we evaluate compute (fun () -> let s = ref 0 in for i = 1 to 100 do s := add !s i done ; s) While this idea works, there are two problems (side-effect are also an issue but I do not care about that): 1) The programer who has to enclose pieces of code that use "add" inside the "compute" wrapper that catches Overflow and restarts the computation. 2) max_value is a global variable. Sometimes we want nested "computes", each with its own max_value. What to do? I want the programmer to have a minimal overhead (syntactically and also in terms of having to think about what is going on). Which programming concept am I failing to use here? Thanks for your help, Andrej P.S. One idea is to remember enough info so that we can recompute better values on demand. This turns out to be bad in my case (real number arithmetic) because you end up using space linear in the number of arithmetic operations, which is too expensive (think a hundred billion arithmetic operations).