From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id 31DB47EEBF for ; Wed, 19 Aug 2015 02:06:12 +0200 (CEST) Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of art.wendling@gmail.com) identity=pra; client-ip=209.85.218.41; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="art.wendling@gmail.com"; x-sender="art.wendling@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail2-smtp-roc.national.inria.fr: domain of art.wendling@gmail.com designates 209.85.218.41 as permitted sender) identity=mailfrom; client-ip=209.85.218.41; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="art.wendling@gmail.com"; x-sender="art.wendling@gmail.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-oi0-f41.google.com) identity=helo; client-ip=209.85.218.41; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="art.wendling@gmail.com"; x-sender="postmaster@mail-oi0-f41.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0A+AwD6x9NVmynaVdFdg29pBoMfqiqEbYsegiEBCYV7AoE1B0wBAQEBAQESAQEBAQEGCwsJIS6EIwEBAQMBAQIPEQQZARsSCwEDAQsGAwILAwoNHQICIgERAQUBChIGExIICId2AQMKCA2eJI8/gS8+MYtAgWyCeYsEChknAwpXhQABAQEBAQEEAQEBAQEBAQEUAQUOi0WFBgQHgmmBQwWFbAyGaIhChQSHaIFKRpQ4ghsSI4EXEQaCToFAPDOCTAEBAQ X-IPAS-Result: A0A+AwD6x9NVmynaVdFdg29pBoMfqiqEbYsegiEBCYV7AoE1B0wBAQEBAQESAQEBAQEGCwsJIS6EIwEBAQMBAQIPEQQZARsSCwEDAQsGAwILAwoNHQICIgERAQUBChIGExIICId2AQMKCA2eJI8/gS8+MYtAgWyCeYsEChknAwpXhQABAQEBAQEEAQEBAQEBAQEUAQUOi0WFBgQHgmmBQwWFbAyGaIhChQSHaIFKRpQ4ghsSI4EXEQaCToFAPDOCTAEBAQ X-IronPort-AV: E=Sophos;i="5.15,705,1432591200"; d="scan'208";a="174014390" Received: from mail-oi0-f41.google.com ([209.85.218.41]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 19 Aug 2015 02:06:11 +0200 Received: by oiev193 with SMTP id v193so110236354oie.3 for ; Tue, 18 Aug 2015 17:06:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=B0168uQj25ZFwd8vcvHJEXoJ3zPbZ/2NjCuuv9IFSOU=; b=DHK/wIShI7AurNvZ56g5rwozzvZMbo5+ubNnPSi5SDHdl5/ECbkQ2VO9qaO8XprIhQ iOyisQ3JiS+offPrWbjbDRuMk54ttJWwCeSfnlAGYJDhBmWkqqtT56Z9vWHlDW4Xpn8O 4xaqhAnxoC2moRb9ILrIKYgcBT1dF0z0QU2IXGI0MYMfFfptK1r3jMZSI4mT4YYnOvj3 P8lrR9aLza0EkBNOsby4ORWNNBP21Ve7WrFqZlhIjP0SfmIvL0M4BtxG9XJ3lN7587VN tGFOcDWDfzR3e7+mqRQKxuULbCh87ru5UB+MrYP4KerKtT4nDmppgW2lMOfG+n1in/yg rRDQ== MIME-Version: 1.0 X-Received: by 10.202.211.65 with SMTP id k62mr7952634oig.34.1439942769552; Tue, 18 Aug 2015 17:06:09 -0700 (PDT) Received: by 10.202.86.65 with HTTP; Tue, 18 Aug 2015 17:06:09 -0700 (PDT) In-Reply-To: <00A7715E-A042-4847-89F4-BA6F8AF20662@metastack.com> References: <20150819004103.Horde.gmnxtcrVOwNtWht0UpT4DzE@webmail.in-berlin.de> <00A7715E-A042-4847-89F4-BA6F8AF20662@metastack.com> Date: Wed, 19 Aug 2015 02:06:09 +0200 Message-ID: From: Arthur Wendling To: David Allsopp Cc: Oliver Bandel , "caml-list@inria.fr" Content-Type: multipart/alternative; boundary=001a113d23e046b2d2051d9ecd5f Subject: Re: [Caml-list] Simple exception - different behaviour between toplevel and compiled --001a113d23e046b2d2051d9ecd5f Content-Type: text/plain; charset=UTF-8 > 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 = 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 wrote: > > On 19 Aug 2015, at 00:41, Oliver Bandel > 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 > --001a113d23e046b2d2051d9ecd5f Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
> exception A of int * in= t

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 ac= tually matters:

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

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

Anyway, now, reg= arding the output of the interpreter/compiler:
- A of int * int is= printable by both, because the runtime can guess that the two arguments ar= e integers (because they aren't pointers.)
- B of (int * int) = is only printed correctly by the interpreter, because it keeps the source i= nformation. 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 i= t: it could be something else than a tuple from the point of view of the us= er (like a record { x : int ; y : int }, but the names x,y have been forgot= ten, so the runtime representation is identical to (int * int)).

<= br>
On Wed, Aug 19, 2015 at 1:32 AM, David Allsop= p <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:
>
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D
> Testcase A
> exception A of int * int
> let _ =3D 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 _ =3D raise ( B(3,4) )
> Exception: B (3, 4).
> Fatal error: exception Excb.B(_)
> Fatal error: exception Excb.B(_)
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D
>
> 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 beh= ave 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 oca= mlc/ocamlopt (the runtime only knows the name of the exception - beyond tha= t, it's just presented with a standard variant block). I haven't go= t a compiler to hand, but I think you'll also see differences if you us= e a variant instead of numbers (ocaml will display the constructor name, th= e compilers will display its constructor number) and I think you'll als= o see the same output as the compilers if you compile excb.cmo and then #lo= ad it in the toplevel.

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


David

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

--001a113d23e046b2d2051d9ecd5f--