From: CREGUT Pierre FTRD/DTL/LAN <pierre.cregut@rd.francetelecom.fr>
To: caml-list@inria.fr
Subject: Re: unwind-protect?
Date: Fri, 17 Nov 2000 14:54:07 +0100 [thread overview]
Message-ID: <20001117145407.A24233@lat4149.lannion.cnet.fr> (raw)
In-Reply-To: <200011171228.NAA21785@pauillac.inria.fr>; from Pierre.Weis@inria.fr on ven, nov 17, 2000 at 01:28:46 +0100
Pierre's solution repeat chdir which is often the long part of the code.
I like to use the following constructs (I am looking for smarter constructs.
I am also looking for a standard way of doing it that would go in the
standard library) :
type 'a result = Normal of 'a | Exception of exn
let catch f a = try Normal (f a) with e -> Exception e
let throw = function Normal a -> a | Exception e -> raise e
let with_fallback v f fallback =
match v with Normal a -> f a | Exception e -> fallback e
There are some contexts where it is as ubiquitous as the 'a option type.
For example, RPC on cin :
let cout, msg = sync(receive cin) in sync(send (catch f msg))
On the other side you will find :
let channel = new_channel () in
sync(send (channel,msg)); throw (sync (receive channel))
In the chdir problem (or if you use any kind of lock construct) you can write :
chdir ...;
let r = catch (f a);
chdir ...;
throw r
The with_fallback function can be used to simulate the so much missing
trylet .... in .... with ...
capturing only errors in the let part.
Pierre
ANNEX
=====
i am not convinced that with_fallback is the definitive answer for a fine
grained control of exceptions. To complete a previous post, I would prefer a
new "context" construct
let complex_function .... =
try
let v = context c1 f x1 x2 ... in
....
g (context c2 h y1 y2 ...) z1 z2 ...
...
with
E1 in c1 -> ....
| E2 in c2 -> ....
| E -> ....
Combined with a tool like ocamlexc, you can
- have readable code that separates exceptional cases from the regular
treatment.
- be sure that all your exceptions are trapped
- be convinced that your error handling code is trapping the right exception
not another one that happened to have the same name (typical of Not_found
exception handlers).
(Note that the "looped approximation' of recursive datatype by ocamlexc could
limit the power of the analysis as we use an exception containing another
exception.)
Here is a crude prototype in CAMLP4 (lists are not needed, but you must
remember which context is embedded in which one. There are also issues
with tail recursion that can be broken.
********** exc.ml *************
exception Located of exn * string list
let extract = function Located(e,l) -> e,l | e -> e,[]
let present exc l = List.mem exc l
**********excemption.ml*************
open Pcaml
open MLast
let match_case = Grammar.Entry.find expr "match_case"
let try_case = Grammar.Entry.create Pcaml.gram "try_case"
DELETE_RULE
expr: "try"; expr; "with"; OPT "|"; LIST1 match_case SEP "|"
END
EXTEND
expr :
[ [ "try"; x = expr; "with"; OPT "|"; l = LIST1 try_case SEP "|" ->
let l' = l @ [(<:patt<_>>,None,<:expr<raise _exc_>>)] in
<:expr< try $x$ with [ _exc_ ->
let (_e_,_loc_) = Exc.extract _exc_ in
match _e_ with [ $list:l'$ ] ] >>
| "context"; name = UIDENT; e = expr ->
<:expr<
try $e$ with
[ Exc.Located(e,l) -> raise (Exc.Located(e, [ $str:name$ :: l]))
| e -> raise (Exc.Located(e,[$str:name$]))] >> ]]
;
try_case :
[[ p = patt; aso = OPT [ "as"; p = patt -> p ];
at_location = OPT ["in"; location = UIDENT -> location];
w_opt = OPT [ "when"; e = expr -> e ]; "->"; e = expr ->
let p_with_as =
match aso with
Some as_pat -> <:patt< ($p$ as $as_pat$) >>
| _ -> p in
let w_with_at =
begin match w_opt,at_location with
| Some w,Some lc -> Some(<:expr<($w$) && (Exc.present $str:lc$ _loc_)>>)
| None,Some lc -> Some (<:expr<Exc.present $str:lc$ _loc_>>)
| _,None -> w_opt
end in
(p_with_as, w_with_at, e) ]]
;
END
--
Pierre Cregut - pierre.cregut@rd.francetelecom.fr - +33 2 96 05 16 28
FTR&D - DTL/MSV - 2 avenue Pierre Marzin - 22307 Lannion Cedex - France
next prev parent reply other threads:[~2000-11-19 14:50 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2000-11-17 6:23 unwind-protect? Colin Walters
2000-11-17 12:28 ` unwind-protect? Pierre Weis
2000-11-17 13:54 ` CREGUT Pierre FTRD/DTL/LAN [this message]
2000-11-17 14:01 unwind-protect? Damien Doligez
2000-11-21 9:36 ` unwind-protect? Pierre Weis
2000-11-17 14:37 unwind-protect? David McClain
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=20001117145407.A24233@lat4149.lannion.cnet.fr \
--to=pierre.cregut@rd.francetelecom.fr \
--cc=caml-list@inria.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