caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: skaller <skaller@users.sourceforge.net>
To: Edgar Friendly <thelema314@gmail.com>
Cc: caml-list@yquem.inria.fr
Subject: Re: [Caml-list] Ocaml compiler features
Date: Wed, 17 Jan 2007 14:28:47 +1100	[thread overview]
Message-ID: <1169004527.8941.77.camel@rosella.wigram> (raw)
In-Reply-To: <45AD2672.2090206@gmail.com>

On Tue, 2007-01-16 at 13:24 -0600, Edgar Friendly wrote:
> skaller wrote:
> > What about it? C manages to handle all that .. and has no exceptions.
> > 
> I think the point here is that because OCaml has exceptions (that other
> people use, maybe not you), it should also have finally blocks to allow
> them to easily do what you do without exceptions.

That is a reasonable argument to examine: but I'm not sure
finally is actually all that useful. If you're thinking of:

	try maybe_throw X; do something
	finally -> cleanup done

then it can be coded in Ocaml like:

	begin try maybe_throw X; do something; cleanup
	with x -> cleanup; throw x end

Now you can argue the repetition of 'cleanup' is a bad,
and I would agree, BUT in Ocaml this is no big deal:

	begin let cleanup = .. in try ... end

In Java and other brain dead languages without lexical scoping
you cannot do this. 

So Java really NEEDS finally, whereas in Ocaml the utility
is less. I note C++ can use RAII:

	class file { 
		FILE * f; file(string x) : f(open(x)) {}
		~file() { close(f); }
	};
	..
	{ 
		file f(name); maybe throw ..
	}

and here needs no finally, but in general in C++ you have
the same problem as Java: no lexical scoping.

> > But adding 'finally' may not be the best solution,
> > the try/let construction looks better to me.
> > 
> I can't find an example of this.  Something about doing variable binding
> as part of the try statement, and then finalizing how?

I have lost the URL, sorry. But the problem is localisation:
the only sane way to use exceptions is like:

	let result = try Some (open f) with Error -> None in
	match result with None -> ... Some ....

If you try to do it like:

	try 
		before
		open f 
		middle
		close f
		after
	with _ -> close f

then you have all sorts of problems if a different exception
is thrown in the before or after parts. Using type information
to distinguish the kind of exception is clearly a hack:
what if you're opening two files?

So roughly, this structure is not amenable to composition.
Adding 'finally' doesn't solve that problem, and that
problem is far worse than the lack of finally.
[Sorry this is a really bad explanation ..]

> > But typically I do that kind of
> > thing the C way, which is generally the Ocaml way too:
> > you propagate return codes from functions using variants
> > up call chains.
> > 
> The OCaml standard library seems to be programmed using exceptions over
> variants.  I'll have to say I don't like or use exceptions much, but I'm
> forced to by the standard libraries.

Yes, but you can do what many people do: map the exceptions into
variants like:

	let hfind x y  = 
		try Some(Hashtbl.find x y) 
		with Not_found -> None 

religiously, eliminating the exceptions. And you can convert
to exceptions from variants like:

	let efind x y = 
		match hfind x y with
		| Some r -> r
		| None -> raise Not_found

So really the library gives one of two cases, and allows you
to code the other easily. You aren't forced to use "long throw"
handlers, i.e. handlers which are a long way from the point
of the throwing code lexically.

The wrapper above eliminates any need for a finally clause
since ordinary conditionals and matches can be used instead --
in the case you're converting to variants.

It still leaves open the case of "long throw" exceptions
where you want to use exceptions: that may well benefit
from a finally clause but you see now the number of use
cases is reduced because the wrapper technique will be
appropriate in some cases.

IN FACT the problem is not entirely an issue with exceptions!
Examining the 'exception free' case using fopen below
we have the SAME problem:

	let fopen f lock = try Some (open f) with Error -> None in
	let lck = mutex () in lock mutex;
	let f = fopen name lck in
	match f with
	| Some file -> ... close, release lck
	| None -> release lck

WOOPS! Again we had to repeat the cleanup code.
Releasing the mutex AFTER the whole code works, but
if we want separate control flows for the two cases
we have to test the variant again:

	begin match f with .. end; release lck;
	match f with .. (* fork again  *)

So actually, you could use a 'finally' here too: the problem
doesn't appear to be special to exception handling, but rather
a case where you have a control fork and want some code done in
the middle of both branches of the fork.

Roughly .. block structure (nesting) can't handle interleaved
execution very cleanly: you can minimise the impact with
lexically scoped subroutine call, but you still need to call
it twice. 

Whereas with 'finally' clause you don't, the problem is
that you're restricted to the balanced (block) structure so the
code location of the 'finally' clause is right for both
branches. In complex cases .. the finally clause isn't
useful because it imposes too much nested structure
that turns out to be wrong anyhow: you have a state machine
which just can't be represented with a pushdown stack,
not even one that supports a second control path via
stack unwinding.

Please note again I'm not arguing against adding finally
(though I might do so!) I'm arguing the need for it isn't
as common as you might think in Ocaml, and part of the need
is only a symptom of a wider problem.

Some other languages provide continuations instead
of exceptions, and it is much easier to manage control
flow in such a language, since in effect 'goto' targets
are first class (can be stored in variables). I guess
it is also easier to *lose* control too :)


-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net


  reply	other threads:[~2007-01-17  3:28 UTC|newest]

Thread overview: 75+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-01-13  5:37 Edgar Friendly
2007-01-13  5:56 ` [Caml-list] " Tom
2007-01-14 17:35   ` Edgar Friendly
2007-01-14 17:59     ` ketty
2007-01-14 18:21       ` Edgar Friendly
2007-01-14 18:29         ` Jon Harrop
2007-01-13  7:41 ` David Baelde
2007-01-13  9:31   ` ketty
2007-01-14 17:33   ` Edgar Friendly
2007-01-14 18:23     ` Jon Harrop
2007-01-14 18:41       ` Vincent Hanquez
2007-01-14 20:49         ` Jon Harrop
2007-01-14 23:38           ` Gabriel Kerneis
2007-01-15  0:55             ` Jon Harrop
2007-01-15  6:12               ` skaller
2007-01-15  0:05           ` Vincent Hanquez
2007-01-15  5:59             ` skaller
2007-01-15 20:23             ` Martin Jambon
2007-01-15 21:30               ` Jon Harrop
2007-01-15 22:13                 ` Try finally (was Re: [Caml-list] Ocaml compiler features) Daniel Bünzli
2007-01-15 22:27                   ` Vincent Hanquez
2007-01-15 22:40                     ` Quôc Peyrot
2007-01-15 23:08                       ` Vincent Hanquez
2007-01-15 22:17               ` [Caml-list] Ocaml compiler features Vincent Hanquez
2007-01-16  1:18                 ` skaller
2007-01-16  2:11                   ` Jon Harrop
2007-01-16  5:18                     ` Edgar Friendly
2007-01-16  6:36                       ` skaller
2007-01-16  6:33                     ` skaller
2007-01-16 13:55                     ` Brian Hurt
2007-01-16  9:00                   ` Vincent Hanquez
2007-01-16 14:14                     ` skaller
2007-01-16 15:00                       ` Vincent Hanquez
2007-01-16 17:47                         ` skaller
2007-01-16 19:24                           ` Edgar Friendly
2007-01-17  3:28                             ` skaller [this message]
2007-01-17 11:41                               ` Vincent Hanquez
2007-01-17 12:53                                 ` Olivier Andrieu
2007-01-17 13:18                                   ` Vincent Hanquez
2007-01-17 14:09                                 ` skaller
2007-01-16 19:42                           ` Jon Harrop
2007-01-16 21:15                             ` Florian Weimer
2007-01-17  3:46                             ` skaller
2007-01-17 11:50                               ` Vincent Hanquez
2007-01-15  5:56           ` skaller
2007-01-15  9:35         ` Nicolas Pouillard
2007-01-15 18:28           ` Martin Jambon
2007-01-15 19:02             ` ls-ocaml-developer-2006
2007-01-14 19:01       ` Edgar Friendly
2007-01-14 18:51     ` Vincent Hanquez
2007-01-14 20:49       ` Jon Harrop
2007-01-15  0:19         ` Vincent Hanquez
2007-01-20 19:19           ` Jon Harrop
2007-01-20 21:40             ` skaller
2007-01-14 21:47     ` Tom
2007-01-15 10:36 ` Richard Jones
2007-01-15 14:24   ` Vincent Hanquez
2007-01-16  8:45     ` Hendrik Tews
2007-01-16  9:08       ` Vincent Hanquez
2007-01-21 17:07         ` [Caml-list] native-code stack backtraces (was: Ocaml compiler features) Xavier Leroy
2007-01-21 18:53           ` Pierre Etchemaïté
2007-01-16  5:21   ` [Caml-list] Ocaml compiler features Edgar Friendly
2007-01-16  5:33     ` ketty
2007-01-16  6:00       ` Edgar Friendly
2007-01-16  6:10         ` ketty
2007-01-16  5:55     ` Christophe TROESTLER
2007-01-16 17:51       ` Edgar Friendly
2007-01-16 19:09         ` Jon Harrop
2007-01-16 19:21         ` Brian Hurt
2007-01-16 20:06         ` Jonathan Roewen
2007-01-16 20:13         ` Florian Weimer
2007-01-16  6:51     ` skaller
2007-01-16 18:01       ` Edgar Friendly
2007-01-17  2:23         ` skaller
2007-01-16  8:00   ` Florian Hars

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=1169004527.8941.77.camel@rosella.wigram \
    --to=skaller@users.sourceforge.net \
    --cc=caml-list@yquem.inria.fr \
    --cc=thelema314@gmail.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).