caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Gabriel Scherer <gabriel.scherer@gmail.com>
To: Arthur Wendling <art.wendling@gmail.com>
Cc: David Allsopp <dra-news@metastack.com>,
	Oliver Bandel <oliver@first.in-berlin.de>,
	 "caml-list@inria.fr" <caml-list@inria.fr>
Subject: Re: [Caml-list] Simple exception - different behaviour between toplevel and compiled
Date: Wed, 19 Aug 2015 07:35:13 +0200	[thread overview]
Message-ID: <CAPFanBFX3z0MFteh-5P8NuARR7cQJgpg-j3QN+v=qCZqZUUJgw@mail.gmail.com> (raw)
In-Reply-To: <CADfBENkzvX7BBLgfpcr40NPKkma4uwXjGifp=4GjxwUdJ+nXWA@mail.gmail.com>

To Arthur's excellent answer, one can add that you can register
user-defined exception printers to batch programs (this does not
affect the toplevel):

$ cat test.ml
exception Foo of (int * int)

let () = Printexc.register_printer (function
  | Foo (a, b) ->
    Some (Printf.sprintf "Foo (%d, %d), with best regards" a b)
  | _ -> None
)

let v = (1, 2)
let () = raise (Foo v)

$ ocamlc -o test test.ml && ./test
Fatal error: exception Foo (1, 2), with best regards

On Wed, Aug 19, 2015 at 2:06 AM, Arthur Wendling <art.wendling@gmail.com> wrote:
>> 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
>
>

  reply	other threads:[~2015-08-19  5:35 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-18 22:41 Oliver Bandel
2015-08-18 23:32 ` David Allsopp
2015-08-19  0:06   ` Arthur Wendling
2015-08-19  5:35     ` Gabriel Scherer [this message]
2015-08-19 11:53       ` Oliver Bandel
2015-08-19 11:16 ` Oliver Bandel
2015-08-19 11:22   ` Mr. Herr
2015-08-19 11:26     ` Oliver Bandel

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='CAPFanBFX3z0MFteh-5P8NuARR7cQJgpg-j3QN+v=qCZqZUUJgw@mail.gmail.com' \
    --to=gabriel.scherer@gmail.com \
    --cc=art.wendling@gmail.com \
    --cc=caml-list@inria.fr \
    --cc=dra-news@metastack.com \
    --cc=oliver@first.in-berlin.de \
    /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).