From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by yquem.inria.fr (Postfix) with ESMTP id 07AD8BB91 for ; Fri, 10 Dec 2004 11:52:15 +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 iBAAqEVK004996 for ; Fri, 10 Dec 2004 11:52:14 +0100 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 LAA00933 for ; Fri, 10 Dec 2004 11:52:14 +0100 (MET) Received: from haka.fmf.uni-lj.si (haka.fmf.uni-lj.si [193.2.67.18]) by concorde.inria.fr (8.13.0/8.13.0) with ESMTP id iBAAqB0i017478 for ; Fri, 10 Dec 2004 11:52:14 +0100 Received: from localhost ([127.0.0.1] ident=andrej) by haka.fmf.uni-lj.si with esmtp (Exim 3.36 #1 (Debian)) id 1CciNb-0001LR-00; Fri, 10 Dec 2004 11:52:07 +0100 Message-ID: <41B97FD7.50309@andrej.com> Date: Fri, 10 Dec 2004 11:52:07 +0100 From: Andrej Bauer User-Agent: Mozilla Thunderbird 0.9 (X11/20041119) X-Accept-Language: en-us, en MIME-Version: 1.0 To: caml-list@inria.fr Cc: "HENRIKSON, JEFFREY" Subject: Re: [Caml-list] environment idiom References: <9410EC84C0872141B27A2726613EF45D02A52E08@psmrdcex01.psm.pin.safeco.com> In-Reply-To: <9410EC84C0872141B27A2726613EF45D02A52E08@psmrdcex01.psm.pin.safeco.com> Content-Type: text/plain; charset=ISO-8859-2 Content-Transfer-Encoding: 7bit X-Miltered: at nez-perce with ID 41B97FDE.001 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Miltered: at concorde with ID 41B97FDB.000 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Spam: no; 0.00; andrej:01 andrej:01 caml-list:01 henrikson:01 wrote:01 variants:01 type-checked:01 ocamlnet:01 ocamlnet:01 encodes:01 compiler:01 cheated:98 grandiose:98 polymorphic:01 idiom: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: HENRIKSON, JEFFREY wrote: > > I am interested in the idiom of passing a number of parameters by some > kind of "environment" variable. Think of a web server with hundredes of > functions for processing markup and other things, only 3 of which need > to detect the browser. It's bad maintainability to explicitly pass > browserid through hundreds of functions which don't use it. I have had some experience with precisely this sort of task. I expected, as you do, that explicit passing of arguments would be bad. So I came up with a solution that is a bit like your lists of polymorphic variants. It worked out ok, but was a bit hairy. However, I was wrong. Later I also implemented another web application in which I explicitly passed around arguments (I used labels because so many arguments were strings that it was too easy to mix them up). Contrary to my expectations, the code was neater and cleaner, not to mention that it was type-checked at compile time. All in all, I want to convey my experience: in sane programming languages it is ok to pass around arguments explicitly, even if it looks like there will be a lot of uncessary passing. In fact, this is an illusion. The language forces you to organize your code neatly and you will end up passing just the right things to just the right functions. A good compromise turned out to be the following. I used the ocamlnet library which has the "cgi" object that encapsulates everything that needs to be known about the HTTP/CGI request. Passing this object around when needed, rather than passing little pieces of it (such as browser id), turned out to be the right way. To be honest, you'll never pass around "Bananas" and "Apples" but actual info that came from the HTTP/CGI request. All the info is already known at the beginning, it is neatly wrapped up in the cgi object (if you use ocamlnet), and you will never wish to add anything to it. So you can forget about "extending objects/records incrementally" because you don't need that (try to come up with a realistic example). If you do wish to pass around additional arguments, then you just pass them explicitly, and leave alone the object that encodes the request you're handling. Perhaps one piece of information that you want to pass around, and is not stored in the object describing the cgi request, is database info. You want to know what database you're connected to. Since my application is not multi-threaded, I cheated and used a global variable for that. You may want to pass around database info. In my experience, you should always pass precisely the arguments a given function needs, and no others. If you think "I will always pass the cgi and database arguments, because I do not know who will need them, and my code will achieve grandiose uniformity" you are likely to make a mistake. You _should_ know who needs the cgi and database info in the first place, and so should the compiler. So be as strict as possible--it pays off in smaller and more managable code. I tried it. It works. Best regards, Andrej