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.7 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 mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by yquem.inria.fr (Postfix) with ESMTP id A96DBBBAF for ; Mon, 19 Jan 2009 17:22:12 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AvMAALM3dEmArgWolGdsb2JhbACCO5FMAQEBAQkLCAkRBL4EBoVt X-IronPort-AV: E=Sophos;i="4.37,290,1231110000"; d="scan'208";a="21708213" Received: from expredir7.cites.uiuc.edu ([128.174.5.168]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-SHA; 19 Jan 2009 17:22:11 +0100 Received: from axyr (aryx.cs.uiuc.edu [128.174.236.106]) by expredir7.cites.uiuc.edu (8.14.2/8.14.2) with ESMTP id n0JGM604023225; Mon, 19 Jan 2009 10:22:06 -0600 (CST) To: Jon Harrop Cc: caml-list@yquem.inria.fr Subject: Visitor in OCaml [was Re: [Caml-list] C++/C# inheritance is bad?] References: <200901171327.19141.jon@ffconsultancy.com> <200901171659.36732.jon@ffconsultancy.com> From: Yoann Padioleau Date: Mon, 19 Jan 2009 10:22:08 -0600 In-Reply-To: <200901171659.36732.jon@ffconsultancy.com> (Jon Harrop's message of "Sat\, 17 Jan 2009 16\:59\:36 +0000") Message-ID: <871vuz2rm7.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 datatypes:01 syntax:01 verbose:01 ctype:01 pointer:01 ctype:01 expr:01 expr:01 iter:01 iter:01 beginner's:01 ocaml:01 bug:01 2009:98 Jon Harrop writes: > On Saturday 17 January 2009 14:35:22 Kuba Ober wrote: > > In contrast, metaprogramming is the pedagogical example for algebraic > datatypes. There is almost no need for users to extend the abstract syntax > tree but there is huge value in being able to rewrite expressions using > pattern matching. > There is an idiomatic OOP solution to this problem that > involves visitor patterns and so forth but it is comparatively verbose, > obfuscated and unmaintainable. Actually I think there are some good ideas in the visitor pattern. I personnaly use a mix of pattern matching and of the visitor idiom in one of my project about C program transformation (http://www.emn.fr/x-info/coccinelle/). The problem we had is that we manipulate the AST of C programs and some of our analysis need only to specify an action for specific cases, such as the function call case, and recurse for the other cases. Here is an simplification of our AST: type ctype = | Basetype of ... | Pointer of ctype | Array of expression option * ctype | ... and expression = | Ident of string | FunCall of expression * expression list | Postfix of ... | RecordAccess of .. | ... and statement = ... and declaration = ... and program = ... 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. Our solution is to mix the ideas of visitor, pattern matching, and continuation. Here is how it looks like in our coccinelle project using our hybrid-visitor API: let my_analysis program = Visitor.visit_iter program { Visitor.kexpr = (fun k e -> match e with | FunCall (e, es) -> do_something() | _ -> k e ); } You can of course also give action "hooks" for kstatement, ktype, or kdeclaration. But we don't overuse visitors and so it would be stupid to provide kfunction_call, kident, kpostfix hooks as one can just use pattern matching with kexpr to achieve the same effect. The code in Visitor.visit_iter is then of course a little bit tricky. You can have a look in the source of coccinelle. > > -- > Dr Jon Harrop, Flying Frog Consultancy Ltd. > http://www.ffconsultancy.com/?e > > _______________________________________________ > Caml-list mailing list. Subscription management: > http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list > Archives: http://caml.inria.fr > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs