caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Simple exception - different behaviour between toplevel and compiled
@ 2015-08-18 22:41 Oliver Bandel
  2015-08-18 23:32 ` David Allsopp
  2015-08-19 11:16 ` Oliver Bandel
  0 siblings, 2 replies; 8+ messages in thread
From: Oliver Bandel @ 2015-08-18 22:41 UTC (permalink / raw)
  To: caml-list

[-- Attachment #1: Type: text/plain, Size: 743 bytes --]

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...

OCaml version is 4.02.1


Ciao,
    Oliver

[-- Attachment #2: exca.ml --]
[-- Type: text/plain, Size: 50 bytes --]

exception A of int * int
let _ = raise ( A(3,4) )

[-- Attachment #3: excb.ml --]
[-- Type: text/plain, Size: 50 bytes --]

exception B of (int*int)
let _ = raise ( B(3,4) )

[-- Attachment #4: testexc.bash --]
[-- Type: text/plain, Size: 203 bytes --]


echo Testcase A
FILE=exca.ml
cat    $FILE
ocaml  $FILE
ocamlc $FILE
./a.out
ocamlopt $FILE
./a.out


echo Testcase B
FILE=excb.ml
cat    $FILE
ocaml  $FILE
ocamlc $FILE
./a.out
ocamlopt $FILE
./a.out



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] Simple exception - different behaviour between toplevel and compiled
  2015-08-18 22:41 [Caml-list] Simple exception - different behaviour between toplevel and compiled Oliver Bandel
@ 2015-08-18 23:32 ` David Allsopp
  2015-08-19  0:06   ` Arthur Wendling
  2015-08-19 11:16 ` Oliver Bandel
  1 sibling, 1 reply; 8+ messages in thread
From: David Allsopp @ 2015-08-18 23:32 UTC (permalink / raw)
  To: Oliver Bandel; +Cc: caml-list

> 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

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] Simple exception - different behaviour between toplevel and compiled
  2015-08-18 23:32 ` David Allsopp
@ 2015-08-19  0:06   ` Arthur Wendling
  2015-08-19  5:35     ` Gabriel Scherer
  0 siblings, 1 reply; 8+ messages in thread
From: Arthur Wendling @ 2015-08-19  0:06 UTC (permalink / raw)
  To: David Allsopp; +Cc: Oliver Bandel, caml-list

[-- Attachment #1: Type: text/plain, Size: 3427 bytes --]

> 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
>

[-- Attachment #2: Type: text/html, Size: 4619 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] Simple exception - different behaviour between toplevel and compiled
  2015-08-19  0:06   ` Arthur Wendling
@ 2015-08-19  5:35     ` Gabriel Scherer
  2015-08-19 11:53       ` Oliver Bandel
  0 siblings, 1 reply; 8+ messages in thread
From: Gabriel Scherer @ 2015-08-19  5:35 UTC (permalink / raw)
  To: Arthur Wendling; +Cc: David Allsopp, Oliver Bandel, caml-list

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
>
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] Simple exception - different behaviour between toplevel and compiled
  2015-08-18 22:41 [Caml-list] Simple exception - different behaviour between toplevel and compiled Oliver Bandel
  2015-08-18 23:32 ` David Allsopp
@ 2015-08-19 11:16 ` Oliver Bandel
  2015-08-19 11:22   ` Mr. Herr
  1 sibling, 1 reply; 8+ messages in thread
From: Oliver Bandel @ 2015-08-19 11:16 UTC (permalink / raw)
  To: caml-list

Hello,


maybe the problem is, that the one type is a curried int * int.
In the compiled version there seems no way to print it's contents?
But the toplevel does print the exception clearly with the containing  
int * int.
Can the toplevel's verbosity be made available in the compiled version?

Ciao,
    Oliver


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] Simple exception - different behaviour between toplevel and compiled
  2015-08-19 11:16 ` Oliver Bandel
@ 2015-08-19 11:22   ` Mr. Herr
  2015-08-19 11:26     ` Oliver Bandel
  0 siblings, 1 reply; 8+ messages in thread
From: Mr. Herr @ 2015-08-19 11:22 UTC (permalink / raw)
  To: caml-list

On 19.08.2015 13:16, Oliver Bandel wrote:
> Hello,
>
>
> maybe the problem is, that the one type is a curried int * int.
> In the compiled version there seems no way to print it's contents?
> But the toplevel does print the exception clearly with the containing int * int.
> Can the toplevel's verbosity be made available in the compiled version?
>
> Ciao,
>    Oliver
>
>

see the answers by Arthur 02:06h, and by gasche 07:35h with an explicit example.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] Simple exception - different behaviour between toplevel and compiled
  2015-08-19 11:22   ` Mr. Herr
@ 2015-08-19 11:26     ` Oliver Bandel
  0 siblings, 0 replies; 8+ messages in thread
From: Oliver Bandel @ 2015-08-19 11:26 UTC (permalink / raw)
  To: caml-list


Zitat von "Mr. Herr" <misterherr@freenet.de> (Wed, 19 Aug 2015 13:22:10 +0200)

> On 19.08.2015 13:16, Oliver Bandel wrote:
>> Hello,
>>
>>
>> maybe the problem is, that the one type is a curried int * int.
>> In the compiled version there seems no way to print it's contents?
>> But the toplevel does print the exception clearly with the  
>> containing int * int.
>> Can the toplevel's verbosity be made available in the compiled version?
>>
>> Ciao,
>>   Oliver
>>
>>
>
> see the answers by Arthur 02:06h, and by gasche 07:35h with an  
> explicit example.

Thanks for the hint.

Just too much mails in the inbox... so I didn't even saw there were answers.

Ciao,
    Oliver



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] Simple exception - different behaviour between toplevel and compiled
  2015-08-19  5:35     ` Gabriel Scherer
@ 2015-08-19 11:53       ` Oliver Bandel
  0 siblings, 0 replies; 8+ messages in thread
From: Oliver Bandel @ 2015-08-19 11:53 UTC (permalink / raw)
  To: caml-list

Hello,

thanks to all, who answered.
It made me clear, why the toplevel knows more then the compiled versions.

For functions like Printexc.register_printer I wondered, why they
are there... who would ever need them? Now they make sense to me. :-)

And now I think about... possibly using exceptions and exception printers
more usually - not just as a last resort -
and more sophisticated - not just "exceptional" minimalistic messages -
might make the code becoming better.


Ciao,
    Oliver






Zitat von Gabriel Scherer <gabriel.scherer@gmail.com> (Wed, 19 Aug  
2015 07:35:13 +0200)

> 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
>>
>>
>
> --
> 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




^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2015-08-19 11:54 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-18 22:41 [Caml-list] Simple exception - different behaviour between toplevel and compiled Oliver Bandel
2015-08-18 23:32 ` David Allsopp
2015-08-19  0:06   ` Arthur Wendling
2015-08-19  5:35     ` Gabriel Scherer
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

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).