caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Martin Jambon <martin_jambon@emailuser.net>
To: Luc Maranget <luc.maranget@inria.fr>
Cc: Christophe Raffalli <christophe.raffalli@univ-savoie.fr>,
	sejourne_kevin <sejourne_kevin@yahoo.fr>,
	caml-list <caml-list@inria.fr>
Subject: Re: [Caml-list] Request for complete pattern matching
Date: Wed, 23 Nov 2005 12:56:04 -0800 (PST)	[thread overview]
Message-ID: <Pine.LNX.4.63.0511231120410.3572@munge> (raw)
In-Reply-To: <20051123183134.GB6446@yquem.inria.fr>

On Wed, 23 Nov 2005, Luc Maranget wrote:

>>
>> No this is not a problem of test. I want to be able to write
>>
>> match e with
>>   (0 <= 0, g) -> g
>> | (f, 0 <= 0) -> f
>> | (f, g) -> fun x -> f x + g x
>>
> Well, I understand better and (as you may have guessed yourself!) I do
> not incline to adopt the idea.
>
> However provided you have some 'break' construct to transfert control to
> next matching, you can perhaps compile your construct by syntactic
> transformation.
> 
> My idea is to transform your patterns into
> normal ones, replacing p <= e1 e2 ... en by fresh variables (say v)
> and then to match 'v e1 ... en' against p.
>
> Here you have :
>
> match e with
> | (v1, g) -> (match v1 0 with 0 -> g |_ -> break)
> | (f, v2) -> (match v2 0 with 0 -> f |_ -> break)
> | f, g -> fun x -> f x + g x
>
> At a little additional cost in complexity,
> you can replace 'break' (which does not exists) by exceptions as follows
>
> let x = e in
> try (match x with
>  | (v1, g) -> (match v1 0 with 0 -> g |_ -> raise Exit)
>  | _ -> raise Exit)
> with Exit ->
> try (match x with
>  | (f, v2) -> (match v2 0 with 0 -> f |_ -> raise Exit)
>  | _ -> raise Exit)
> with Exit ->
> (match x with  f, g -> fun x -> f x + g x)
>
>
> I am not familiar enough with Camlp4, but I have the feeling
> that some purely syntactic compilation of your construct is doable.
> Since, only from the presence of <=,
> can you introduce the extra matchings and try .. with Exit)
> I am not saying it is easy, just that it looks feasible.

That's basically what I did for Micmatch 
(http://martin.jambon.free.fr/micmatch.html).
It was not so simple to implement with Camlp4, but it works. Exceptions 
are used extensively as you describe. So it is actually possible to 
insert arbitrary computations into ML patterns! Of course the complexity 
is not O(size of the pattern) anymore.

For instance, you can write:

(* toto.ml *)
try
   while true do
     match read_line () with
 	/ upper / | / _* "." eos / -> print_endline "looks like a sentence"
       | "." | / ("bye"~ space*)+ / -> print_endline "Bye!"; exit 0
       | _ -> print_endline "???"
   done
with End_of_file -> ()

Notes:
- the stuff between slashes are regexps
- "." and the last _ are regular OCaml patterns
- regexps are replaced by an identifier which is matched after the 
arrow using library functions, then it is decided whether to jump to the 
next case or to execute the user-given expression.

Here is a session using the silly program above:

$ micmatch toto.ml
Hello
looks like a sentence
ho ho ho.
looks like a sentence
!@#$%^&
???
goodbye
???
bye bye
Bye!
$


> Typing and warnings are yet another issue!

Warnings regarding incomplete match cases can be suppressed by adding 
'when true' guards and superfluous catch-all cases.

Tail-call optimizations are preserved by this transformation:
(* f may raise an exception Exn, but not g which is tail-recursive.
    So we don't write this: *)
let rec g arg =
   ...
   try f x; g y
   with Exn -> h z

(* but that: *)
let rec g arg =
   ...
   (try
      f x;
      fun () -> g y
    with
      Exn -> fun () -> h z) ()


You can run "camlp4o pr_o.cmo -I `ocamlfind query micmatch_pcre` pa_micmatch_pcre.cma toto.ml"
to see the final ocaml code.

So it is definitely possible to create a generic camlp4 library which 
allows the insertion of custom tests/bindings into ocaml patterns. In 
addition to string/regexp matching, the library could be used for the 
following extensions:
- 'when' tests appearing inside of the pattern
- evaluation and matching of lazy data
- regular expressions over anything (lists, arrays, trees, ...)
- views (as far as I understand the concept)
- matching objects using method calls as record fields
- other?

I have no plan of implementing this myself, but it might be a good 
project for a student...


Martin

--
Martin Jambon, PhD
http://martin.jambon.free.fr

Store and share your bioinformatics tips at http://wikiomics.org


  reply	other threads:[~2005-11-23 20:56 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-11-22 22:43 Christophe Raffalli
2005-11-23  5:54 ` [Caml-list] " Luc Maranget
2005-11-23 14:37   ` Christophe Raffalli
2005-11-23 10:06 ` Michal Moskal
2005-11-23 15:26   ` Christophe Raffalli
     [not found] ` <43842069.3070700@yahoo.fr>
2005-11-23 14:47   ` Christophe Raffalli
2005-11-23 18:31     ` Luc Maranget
2005-11-23 20:56       ` Martin Jambon [this message]
2005-11-23 21:30         ` skaller
2005-11-23 22:25           ` Martin Jambon
2005-11-24  9:29         ` Luc Maranget
2005-11-25 23:01           ` Martin Jambon
2005-11-23 20:56       ` Christophe Raffalli
2005-11-24  9:41         ` Luc Maranget

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=Pine.LNX.4.63.0511231120410.3572@munge \
    --to=martin_jambon@emailuser.net \
    --cc=caml-list@inria.fr \
    --cc=christophe.raffalli@univ-savoie.fr \
    --cc=luc.maranget@inria.fr \
    --cc=sejourne_kevin@yahoo.fr \
    /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).