From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=disabled version=3.1.3 Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by yquem.inria.fr (Postfix) with ESMTP id 92E02BC6B for ; Thu, 28 Jun 2007 13:01:27 +0200 (CEST) Received: from moutng.kundenserver.de (moutng.kundenserver.de [212.227.126.186]) by concorde.inria.fr (8.13.6/8.13.6) with ESMTP id l5SB1Rls023175 for ; Thu, 28 Jun 2007 13:01:27 +0200 Received: from [141.84.136.30] (helo=[152.78.96.56]) by mrelayeu.kundenserver.de (node=mrelayeu7) with ESMTP (Nemesis), id 0ML2xA-1I3rka0uLx-0003oF; Thu, 28 Jun 2007 13:01:24 +0200 Message-ID: <4683950E.3060609@functionality.de> Date: Thu, 28 Jun 2007 12:01:34 +0100 From: Thomas Fischbacher User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.12) Gecko/20060607 Debian/1.7.12-1.2 X-Accept-Language: en MIME-Version: 1.0 To: Jon Harrop Cc: caml-list@yquem.inria.fr Subject: Re: [Caml-list] The Implicit Accumulator: a design pattern using optional arguments References: <200706271314.35134.jon@ffconsultancy.com> <46826C69.5060802@functionality.de> <200706271653.27116.jon@ffconsultancy.com> In-Reply-To: <200706271653.27116.jon@ffconsultancy.com> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-Provags-ID: V01U2FsdGVkX18re1MqtlI+Lt5TNIf7z/AXyxqFt8PmFsUBKwU TKFruiMtykqofK00KHd+Ld7kso/cp+/HM9JCGdOpEH5x5VjrTA fafkjNgdmNe4qyd8TINIg== X-Miltered: at concorde with ID 46839507.000 by Joe's j-chkmail (http://j-chkmail . ensmp . fr)! X-Spam: no; 0.00; mutation:01 recursive:01 closures:01 wrote:01 abstract:01 rec:01 rec:01 avoids:01 caml-list:01 functions:01 tail:01 pair:01 imperative:01 nums:01 nums:01 Jon Harrop wrote: > I think Thomas is referring to continuation passing style (CPS). That isn't an > optimization though (it slows things down) but it does let you abstract away > mutation. However, it is not entirely safe in the absence of linear types. Which one do you prefer? let sum_nums n = let rec work sum todo = if todo=0 then sum else work (sum+todo) (todo-1) in work 0 n ;; let sum_nums2 n = let rec work (sum,todo) = if todo=0 then sum else work ((sum+todo),(todo-1)) in work (0,n) ;; Certainly the first one, right? On the one hand, it is simpler, and on the other hand, also faster, because it avoids consing the pair cells that are passed around in the second example. It is important to note that the recursive call to work can not only be seen as a tail call, but in particular also as a continuation call. Viewed in such a way, this is a strategy to provide more than one "return value" to a continuation. The call to "work" could just as much be a call to any other continuation that takes two arguments, so this can be a nice way to reduce unnecessary consing - provided you can make sure the continuation closures are not heap-allocated over and over again. Having said that, it is just as easy to get carried away by all these nice little oprimization ideas in a functional language as it is in an imperative language. While for some parts of the code, and in particular in library functions, optimization is an issue, this more often than not is not a good thing... -- best regards, Thomas Fischbacher tf@functionality.de