caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Yoann Padioleau <padator@wanadoo.fr>
To: Jon Harrop <jon@ffconsultancy.com>
Cc: caml-list@yquem.inria.fr
Subject: Visitor in OCaml [was Re: [Caml-list] C++/C# inheritance is bad?]
Date: Mon, 19 Jan 2009 10:22:08 -0600	[thread overview]
Message-ID: <871vuz2rm7.fsf_-_@aryx.cs.uiuc.edu> (raw)
In-Reply-To: <200901171659.36732.jon@ffconsultancy.com> (Jon Harrop's message of "Sat\, 17 Jan 2009 16\:59\:36 +0000")

Jon Harrop <jon@ffconsultancy.com> 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()
   | _ -> <find_a_way_to_recurse_for_all_the_other_cases> 
 )

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


  parent reply	other threads:[~2009-01-19 16:22 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-01-16 15:18 C++/C# inheritance is bad? Kuba Ober
2009-01-16 15:58 ` [Caml-list] " Richard Jones
2009-01-16 16:28   ` On the benefits of OO, Was: " Jan Kybic
2009-01-17 12:40     ` Oliver Bandel
2009-01-16 18:27 ` Raoul Duke
2009-01-16 21:42   ` Kuba Ober
2009-01-17  3:14     ` Sashan Govender
2009-01-17 14:07       ` Kuba Ober
2009-01-18  6:24         ` Stefano Zacchiroli
2009-01-17 13:27 ` Jon Harrop
2009-01-17 14:35   ` Kuba Ober
2009-01-17 16:59     ` Jon Harrop
2009-01-17 21:22       ` Kuba Ober
2009-01-17 22:17         ` Jon Harrop
2009-01-17 23:29           ` David Teller
2009-01-17 23:49             ` Jon Harrop
2009-01-19 16:22       ` Yoann Padioleau [this message]
2009-01-19 16:41         ` Visitor in OCaml [was Re: [Caml-list] C++/C# inheritance is bad?] blue storm
2009-01-19 17:49           ` Richard Jones
2009-01-19 17:52           ` Visitor in OCaml Christophe TROESTLER
2009-01-21 20:09           ` Yoann Padioleau
2009-01-22  4:03             ` [Caml-list] " Yaron Minsky

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=871vuz2rm7.fsf_-_@aryx.cs.uiuc.edu \
    --to=padator@wanadoo.fr \
    --cc=caml-list@yquem.inria.fr \
    --cc=jon@ffconsultancy.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).