> exception A of int * int

This is an exception with two arguments.

> exception B of (int*int)

This is an exception with a single argument, which is a product of two values. So the parenthesis actually matters:

# fun x -> A x ;;
Error: The constructor A expects 2 argument(s),
       but is applied here to 1 argument(s)
# fun x -> B x ;;
- : int * int -> exn = <fun>

I agree that the syntax is a bit surprising, since we are used to ignore extra parenthesis.

Anyway, now, regarding the output of the interpreter/compiler:
- A of int * int is printable by both, because the runtime can guess that the two arguments are integers (because they aren't pointers.)
- B of (int * int) is only printed correctly by the interpreter, because it keeps the source information. The compiler erases all that, so the runtime only sees a single argument, that contains two ints, but it doesn't know how to display it: it could be something else than a tuple from the point of view of the user (like a record { x : int ; y : int }, but the names x,y have been forgotten, so the runtime representation is identical to (int * int)).


On Wed, Aug 19, 2015 at 1:32 AM, David Allsopp <dra-news@metastack.com> wrote:
> On 19 Aug 2015, at 00:41, Oliver Bandel <oliver@first.in-berlin.de> wrote:
>
> Hello,
>
>
> using the attached files (executing testexc,bash)
> I got different results between toplevel and compiled:
>
> =====================================================
> Testcase A
> exception A of int * int
> let _ = raise ( A(3,4) )
> Exception: A (3, 4).
> Fatal error: exception Exca.A(3, 4)
> Fatal error: exception Exca.A(3, 4)
> Testcase B
> exception B of (int*int)
> let _ = raise ( B(3,4) )
> Exception: B (3, 4).
> Fatal error: exception Excb.B(_)
> Fatal error: exception Excb.B(_)
> =====================================================
>
> So just adding parantheses in a definition of an exception
> yields in these differing results, with not-shown exception-values.
>
> IMHO looks like a case for the bugtracker...

There's no requirement for the toplevel and the compilers to behave the same way for reporting the exception. The output, for example, also differs in the way the exception message is formatted, there's no 'Fatal error:' and so on - do you want that to be a bug too?

The toplevel has access to typing information which is not available to ocamlc/ocamlopt (the runtime only knows the name of the exception - beyond that, it's just presented with a standard variant block). I haven't got a compiler to hand, but I think you'll also see differences if you use a variant instead of numbers (ocaml will display the constructor name, the compilers will display its constructor number) and I think you'll also see the same output as the compilers if you compile excb.cmo and then #load it in the toplevel.

It's not normal to want to terminate your compiled program with an uncaught exception, hence the simpler default exception printer in compiled code. If you really want the exception printed accurately, you can register a printer (see Printexc.register_printer).


David

--
Caml-list mailing list.  Subscription management and archives:
https://sympa.inria.fr/sympa/arc/caml-list
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs