Version française
Home     About     Download     Resources     Contact us    
Browse thread
Re: [Caml-list] Bugs with pattern-matching and exceptions
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Louis Gesbert <louis.gesbert@l...>
Subject: Re: [Caml-list] Bugs with pattern-matching and exceptions
> >  However, if you try to pattern-match against it, the process just hangs.
>
> Can you give an example to reproduce that?  The program above works fine.

My mistake, O'Caml didn't hang: the complex situation where this
problem occured just led to a deadlock, the states of the processes
having become inconsistent (two of them could make different decisions
out of the same data, depending on wether it was locally created or
received from another).

> More precisely, it doesn't distinguish an exception constructor from
> a string reference. Marshalling and unmarshalling produce a shallow
> copy.

Thanks, that explains it.

> I don't see a good semantics for such a program, except considering that
> unmarshalled exceptions must always be different (w.r.t. pattern
> matching) from exceptions defined in the current program, which AFAIK is
> the current semantics.

Right, that's an interesting problem. I wasn't aware exceptions were
imperative to that extent, being registered dynamically whenever
defined: they look much more like type definitions at first. The
always-different semantics doesn't feel satisfying to me however,
neither does the fact that an exception can escape the scope of the
types it includes (thus becoming a black box). We fall back to the
debate about local exceptions here.

However, couldn't a semantics where exceptions defined in local
modules are always different, but other kinds of exceptions are
compared with an incremented global counter be consistent ? The main
issue is that there is no unique id for an exception, it is shown as
Mod.Exn but Mod as well as Exn can be redefined... hence the pointer
comparison, as I understand it. Note that exceptions defined in local
modules are already somewhat different from the others (unprefixed):

# module M1 = struct exception E end
  let module M2 = struct exception E end
  in M1.E,M2.E
  - : exn * exn = (M1.E, E)

The point is, most often you won't redefine your exceptions and there is no
ambiguity in Mod.Exn, so it would be very satisfactory for the exception
exchange to work in that case. A semantics that allows that and handles
more difficult cases probably exists.

Some inconsistency remains anyway with always-different marshalled
exceptions (although they might be imputed to the unsafe marshalling):
an unmarshalled exception is of type exn, but you can't raise it (or
you will get a Failure "input_value: bad object").

Whatever the solution, I think we need a very clear semantics
here. That exceptions shouldn't be marshalled should at least be
mentioned in the Marshal documentation.

Regards,
Louis