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 nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by yquem.inria.fr (Postfix) with ESMTP id B6F56BB81 for ; Tue, 27 Sep 2005 01:25:49 +0200 (CEST) Received: from pauillac.inria.fr (pauillac.inria.fr [128.93.11.35]) by nez-perce.inria.fr (8.13.0/8.13.0) with ESMTP id j8QNPnnj013246 for ; Tue, 27 Sep 2005 01:25:49 +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 BAA18135 for ; Tue, 27 Sep 2005 01:25:48 +0200 (MET DST) Received: from first.in-berlin.de (dialin-145-254-063-147.arcor-ip.net [145.254.63.147]) by concorde.inria.fr (8.13.0/8.13.0) with ESMTP id j8QNPk6c027976 for ; Tue, 27 Sep 2005 01:25:47 +0200 Received: by first.in-berlin.de (Postfix, from userid 501) id 24AFC15E0A2; Tue, 27 Sep 2005 01:25:11 +0200 (CEST) Date: Tue, 27 Sep 2005 01:25:11 +0200 From: Oliver Bandel To: caml-list@inria.fr Subject: Re: [Caml-list] Efficiency of let/and Message-ID: <20050926232511.GA792@first.in-berlin.de> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.6i X-Miltered: at nez-perce with ID 4338837D.001 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Miltered: at concorde with ID 4338837A.000 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Spam: no; 0.00; oliver:01 bandel:01 oliver:01 in-berlin:01 caml-list:01 set-:01 expr:01 expr:01 parallelism:01 recursive:01 rec:01 val:01 val:01 stack:01 recursion:01 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 On Sun, Sep 25, 2005 at 08:31:55AM -0500, Brian Hurt wrote: > > Say I have two variables I want to set- variable a to the value expr1 and > variable b to the value expr2. The two expressions are pure (no side > effects), and neither one depends upon the other (neither expr1 nor expr2 > contain either a or b as a value), so they can be evaluated in either > order or in parallel with no harm. With expressions like these, I've > gotten into the habit of using let/and to express the parallelism, that is > I go: > > let a = expr1 > and b = expr2 > in > ... > > rather than: > let a = expr1 in > let b = expr2 in > > So my question is: is there any value (other than the documentation value) > in doing this? When you write it in the second form, then the "let a =" must be evaluated before the "let b =" expression, because "a" is used in the "b" expression (or might be used, but "a" is part of "b"'s environment, so that it must be evaluated first). You can use this form also for doing imperative operations in a certain order, because the more-outer expression is evaluated first. If you use the form with "and" you can use definitions for functions, that call each other, so called mutually recursive functions. (For types this is also possible (e.g. tree-stuff).) An example (that makes no sense to be used and will raise an Stack-overflow exception, but I want to show, what is possible to define): ============================================================= # let rec f1 x = f2 x + 10 and f2 x = f1 x + 100;; val f1 : 'a -> int = val f2 : 'a -> int = # f2 3;; Stack overflow during evaluation (looping recursion?). # ============================================================= One could try to use "rec" for binding of simple values (not functions with parameters), but this would make no sense, and if evaluated would also create an overflow exception. When defining mutually recursive functions, the recursion would start, when calling the function with it's arguments, so that the resulting value would be calculated. E.g. in the toplevel, you can do this by calling the functions with a parameter (as done above). But when you have a simple value, and not a function, then it's value would be calculated right after the definition, and so the definition of that value would rise the exception, because the expression would be immediately evaluated (eager evaluation). This would probably yield to difficulties, and that seems to me to be the reason, why it is forbidden to use such an expression: ============================================================ first:~ oliver$ ocaml Objective Caml version 3.08.0 # let rec a = 4 and b = 6;; val a : int = 4 val b : int = 6 # let rec a = b + 4 and b = a * 8;; This kind of expression is not allowed as right-hand side of `let rec' # ============================================================ So, you can use "and" for defining some variables at the same scope/environment in parallel, that do not depend on each other... ... but if you define functions, you can also define functions, that depend on each other (mutually recursive calls). Hope this helps. Ciao, Oliver