From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: 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 3069DBB81 for ; Mon, 13 Dec 2004 11:20:52 +0100 (CET) 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 iBDAKp1l015763 for ; Mon, 13 Dec 2004 11:20:51 +0100 Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id LAA24689 for ; Mon, 13 Dec 2004 11:20:51 +0100 (MET) Received: from mail.physik.uni-muenchen.de (mail.physik.uni-muenchen.de [192.54.42.129]) by nez-perce.inria.fr (8.13.0/8.13.0) with ESMTP id iBDAKoYL015757 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL) for ; Mon, 13 Dec 2004 11:20:51 +0100 Received: from localhost (unknown [127.0.0.1]) by mail.physik.uni-muenchen.de (Postfix) with ESMTP id 963322000B; Mon, 13 Dec 2004 11:20:50 +0100 (CET) Received: from mail.physik.uni-muenchen.de ([127.0.0.1]) by localhost (mail.physik.uni-muenchen.de [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 25249-01-22; Mon, 13 Dec 2004 11:20:48 +0100 (CET) Received: from mailhost.cip.physik.uni-muenchen.de (kaiser.cip.physik.uni-muenchen.de [141.84.136.1]) by mail.physik.uni-muenchen.de (Postfix) with ESMTP id 16FF020005; Mon, 13 Dec 2004 11:20:48 +0100 (CET) Received: from eiger.cip.physik.uni-muenchen.de (eiger.cip.physik.uni-muenchen.de [141.84.136.54]) by mailhost.cip.physik.uni-muenchen.de (Postfix) with ESMTP id E6D0826E87; Mon, 13 Dec 2004 11:20:47 +0100 (CET) Received: by eiger.cip.physik.uni-muenchen.de (Postfix, from userid 3092) id DE35B3FCF; Mon, 13 Dec 2004 11:20:47 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by eiger.cip.physik.uni-muenchen.de (Postfix) with ESMTP id D643C2D686; Mon, 13 Dec 2004 11:20:47 +0100 (CET) Date: Mon, 13 Dec 2004 11:20:47 +0100 (CET) From: Thomas Fischbacher To: Jacques Garrigue Cc: caml-list@inria.fr Subject: Re: [Caml-list] environment idiom In-Reply-To: <20041213.182117.79057361.garrigue@math.nagoya-u.ac.jp> Message-ID: References: <877e9a170412121844b633bb8@mail.gmail.com> <877e9a1704121218456af9df9@mail.gmail.com> <20041213.182117.79057361.garrigue@math.nagoya-u.ac.jp> X-BOFH: Daemons did it MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-Virus-Scanned: amavisd-new at physik.uni-muenchen.de X-Miltered: at nez-perce with ID 41BD6D03.001 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Miltered: at nez-perce with ID 41BD6D02.002 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Spam: no; 0.00; caml-list:01 wrote:01 monadic:01 closures:01 haskell:01 syntax:01 char:01 bool:01 char:01 monadic:01 getline:01 getline:01 evidently:01 haskell:01 abbreviation:01 X-Spam-Checker-Version: SpamAssassin 3.0.0 (2004-09-13) on yquem.inria.fr X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=disabled version=3.0.0 X-Spam-Level: On Mon, 13 Dec 2004, Jacques Garrigue wrote: > > Of course, it's possible to just forget about all that and fall back to > > transliterating imperative code to IO monad code, but it is just as well > > possible to find the sum of all the numbers from 1 to 1000 using the > > following piece of Maple code: > > You make me curious. Most of the code I've seen using the IO monad (or > the state transformer monad) was just transliterating imperative to > monadic code. Of course using closures, but not that much, and you can > certainly do that in an impure functional language also. First, I should perhaps mention that in my point of view, John does have a valid point in what he says. It's only that he expressed it in a way I just *cannot* agree with. > So what is so incredible about the IO monad? There is nothing "in-credible" about it. It is just plainly nothing else as working with values that describe "plans" to do IO. We do have a magic place that can bring such plans to life, causing them to be executed, but from the pure Haskell point of view this is not relevant. All we do is to construct plans how to do IO. > By the way, if you want an example of non referentially code, this > looks easy: > > do > x <- readInt > y <- readInt > return (x-y) > (The syntax and functions may be wrong but you get the idea.) Okay. Let's see. Well, readInt is Prelude> :type readInt readInt :: Integral a => a -> (Char -> Bool) -> (Char -> Int) -> ReadS a so this is indeed not monadic. Let's instead talk about, say > do > x <- getLine > y <- getLine > return (y++x) Which, I suppose, conveys the very same idea you had in mind. > Of course according to your definition this contains nothing that is > not referentially transparent once you've taken the syntactic sugar. Precisely. To go a bit more into detail: Referential transparency is about the substitution of definitions. Evidently, x <- ... is _not_ a definition. But according to e.g. the haskell98 tutorial, this do-syntax actually is nothing more but an abbreviation. Let me cite: >> The do syntax provides a simple shorthand for chains of monadic operations. The essential translation of do is captured in the following two rules: do e1 ; e2 = e1 >> e2 do p <- e1; e2 = e1 >>= \p -> e2 << So the "official" notation of what is written in shorthand above is: main = getLine >>= (\x -> (getLine >>= \y -> putStr (">> "++y++x))) Okay? The notion of "substitution" of course only makes sense for this "official" form. It's not quite clear what one might want to substitute here, but everything that one could imagine just works. For example: main = let plan_to_read = getLine in plan_to_read >>= (\x -> (plan_to_read >>= \y -> putStr (">> "++y++x))) In a certain sense, this "do" notation - which is NOT a special extension of the powers of pure, functional haskell but only a short-hand notation for things that can be spelled out explicitly - is "poison" that allows one to "just hack one's imperative thoughts into haskell without even having know about the abstract point of view". This is a bit like FORTRAN programmers asked to adjust themselves to C showing the attitude that "at least, they can forget all that for/while/etc. mumbo-jumbo and do everything with goto, as they are used to". > But looking at the code, it looks like readInt is executed twice > returning different results, i.e. this function does not always return > 0. Well, as I said, if one looks at the code in such a way, one just grossly misreads what actually is written down. The code is about combining plans, not about "executing something twice". > So I suppose this is just an instance of what you see is _not_ what > you get, but wasn't referencial transparency about avoiding that? So, yes, "do" notation is a tool that exists in order to help you to misread code, or let your code be misread. In an ideal world, it would certainly not be here to stay. But considering the large mass of present and future C programmers that yet has to make this transition to a much more abstract point of view, this is bound to (1) stay for quite a while, and (2) give many people (especially those depending on functional code written by that fraction of imperative programmers that have problems adjusting to abstract ideas, I fear) a major headache during the next thirty years. Coming back to the original question, which was whether one may "just stick in some monadic stuff to get a notion of an `environment'", I'm inclined to say that from the purely functional point of view, this perhaps is not a good idea, as this is not just "a minor change to the code" but changes pretty much anything of its original properties. -- regards, tf@cip.physik.uni-muenchen.de (o_ Thomas Fischbacher - http://www.cip.physik.uni-muenchen.de/~tf //\ (lambda (n) ((lambda (p q r) (p p q r)) (lambda (g x y) V_/_ (if (= x 0) y (g g (- x 1) (* x y)))) n 1)) (Debian GNU)