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=1.6 required=5.0 tests=AWL,DNS_FROM_RFC_POST autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by yquem.inria.fr (Postfix) with ESMTP id AD130BBAF for ; Wed, 21 Jan 2009 21:09:07 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AsgBAJbhdkmArgVhkWdsb2JhbACTewEBAQEJCwoHEQS5NwaFbQ X-IronPort-AV: E=Sophos;i="4.37,302,1231110000"; d="scan'208";a="19970974" Received: from expredir6.cites.uiuc.edu ([128.174.5.97]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-SHA; 21 Jan 2009 21:09:06 +0100 Received: from axyr (aryx.cs.uiuc.edu [128.174.236.106]) by expredir6.cites.uiuc.edu (8.14.2/8.14.2) with ESMTP id n0LK92R9002658; Wed, 21 Jan 2009 14:09:02 -0600 (CST) To: "blue storm" Cc: "Yoann Padioleau" , caml-list@yquem.inria.fr Subject: Re: Visitor in OCaml References: <200901171327.19141.jon@ffconsultancy.com> <200901171659.36732.jon@ffconsultancy.com> <871vuz2rm7.fsf_-_@aryx.cs.uiuc.edu> <527cf6bc0901190841l3247ada1kfc86847aac1445d1@mail.gmail.com> From: Yoann Padioleau Date: Wed, 21 Jan 2009 14:09:03 -0600 In-Reply-To: <527cf6bc0901190841l3247ada1kfc86847aac1445d1@mail.gmail.com> (blue storm's message of "Mon\, 19 Jan 2009 17\:41\:35 +0100") Message-ID: <87tz7szajk.fsf@aryx.cs.uiuc.edu> User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Spam: no; 0.00; ocaml:01 expr:01 expr:01 camlp:01 camlp:01 storm:98 folders:98 idiom:01 wrote:01 functions:01 inherit:01 writes:01 implemented:02 match:02 string:02 "blue storm" writes: > On 1/19/09, Yoann Padioleau wrote: >> What we want is really give code like >> >> let my_analysis program = >> analyze_all_expressions program (fun expr -> >> match expr with >> | FunCall (e, es) -> do_something() >> | _ -> >> ) >> >> The problem is how to write analyze_all_expressions >> and find_a_way_to_recurse_for_all_the_other_cases. > > You should have a look at the Camlp4 "metaprogramming" facilities : > http://brion.inria.fr/gallium/index.php/Camlp4MapGenerator I've been there. I once implemented in camlp4 my own map-generator but I now prefer not using fancy features or langage extensions. I prefer to go back to basics. My solution does not use any fancy stuff; just higher order functions, the continuation idiom, and records. People reading your code, or downloading your code then do not need to care about camlp4 (or objects). Moreover, sometimes you need to do things slightly differently from what is auto-generated and it becomes painful. For instance it's possible to auto-generate the string_of_xxx for each type xxx, but at some point you may want to do the printing slightly differently, hide a few things, do some indentation work (and use the Format library), etc, and at this point you will have to write the tedious code. Camlp4 metaprogramming may save you some time at the beginning, but but do you really win that much time in the end ? > > You would write something like : > let my_analysis program = > let analysis = object (self) > inherit fold as super > method expr = function > | FunCall (e, es) -> do_something (); self > | other -> super#expr other > end in analysis#expr > > While sometimes a bit hairy, the object oriented layer makes it easy > to use a refine mapper or folders without writing all the heavy > plumbing yourself. Thx, always interesting to see different ways to solve the same problem.