Kazu Yamamoto | 5 Jun 2012 07:14
Picon
Gravatar

Data.Ratio and exceptions

Hello, 

Some functions in Data.Ratio call the error function. The following is
an example:

    recip (0:%_)        = error "Ratio.%: zero denominator"

We cannot catch this error as ArithException since it is ErrorCall.
Are there any reasons to not use ArithException?

--Kazu
Henning Thielemann | 5 Jun 2012 11:24
Picon

Re: Data.Ratio and exceptions


On Tue, 5 Jun 2012, Kazu Yamamoto (山本和彦) wrote:

> Some functions in Data.Ratio call the error function. The following is
> an example:
>
>    recip (0:%_)        = error "Ratio.%: zero denominator"
>
> We cannot catch this error as ArithException since it is ErrorCall.
> Are there any reasons to not use ArithException?

It is intended that you do not divide by zero, also because it is so 
simple to check it before calling the function. The best solution would 
certainly be a number type that excludes zero values, such that division 
by zero can be catched at compile time. But currently Haskell's type 
system may not be expressive enough to handle this without a lot of 
explicit type conversion.
_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
Kazu Yamamoto | 5 Jun 2012 11:47
Picon
Gravatar

Re: Data.Ratio and exceptions

Hello Henning,

Thank you for reply.

> It is intended that you do not divide by zero, also because it is so
> simple to check it before calling the function. 

I'm not convinced. For instance, for division by zero of Int, it is
also easy to check it before calling the "div" function. But we have
DivideByZero.

> The best solution
> would certainly be a number type that excludes zero values, such that
> division by zero can be catched at compile time. But currently
> Haskell's type system may not be expressive enough to handle this
> without a lot of explicit type conversion.

I'm not suggesting such a drastic change. What I want to suggest is to
define a new data constructor for ArithException and to change % so
that it throws the new data constructor.

In test code, we want to check the exception of Data.Ratio with
hspec-shouldbe as follows:

	evaluate (1 `div'` 0) `shouldThrow` anyArithException

--Kazu
Henning Thielemann | 5 Jun 2012 11:59
Picon

Re: Data.Ratio and exceptions


On Tue, 5 Jun 2012, Kazu Yamamoto (山本和彦) wrote:

> Hello Henning,
>
> Thank you for reply.
>
>> It is intended that you do not divide by zero, also because it is so
>> simple to check it before calling the function.
>
> I'm not convinced. For instance, for division by zero of Int, it is
> also easy to check it before calling the "div" function. But we have
> DivideByZero.

I know people get annoyed quickly if I start a new round of "errors vs. 
exceptions" ...

In Haskell there is only one undefined value and that should be equivalent 
to an infinite loop. Every distinction between 'error', 'undefined', 
infinite loop, DivideByZero is only for debugging purposes. Don't rely on 
being able to catch them! The only correct way to cope with division by 
zero is to not let it happen.
_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
Felipe Almeida Lessa | 5 Jun 2012 12:45
Picon
Gravatar

Re: Data.Ratio and exceptions

Then why don't we change it to ArithException for debugging purposes? =)

Cheers,

--
Felipe – enviado do meu Galaxy Tab.

_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
Kazu Yamamoto | 5 Jun 2012 15:20
Picon
Gravatar

Re: Data.Ratio and exceptions

Hello Henning,

> I know people get annoyed quickly if I start a new round of "errors
> vs. exceptions" ...

Would you explain how they get annoyed concretely?

> In Haskell there is only one undefined value and that should be
> equivalent to an infinite loop. Every distinction between 'error',
> 'undefined', infinite loop, DivideByZero is only for debugging
> purposes. Don't rely on being able to catch them! The only correct way
> to cope with division by zero is to not let it happen.

Let's define a new constructor of ArithException for debugging
purposes.

--Kazu
Conrad Parker | 6 Jun 2012 03:35
Favicon
Gravatar

Re: Data.Ratio and exceptions

On 5 June 2012 17:24, Henning Thielemann <lemming <at> henning-thielemann.de> wrote:
>
> On Tue, 5 Jun 2012, Kazu Yamamoto (山本和彦) wrote:
>
>> Some functions in Data.Ratio call the error function. The following is
>> an example:
>>
>>   recip (0:%_)        = error "Ratio.%: zero denominator"
>>
>> We cannot catch this error as ArithException since it is ErrorCall.
>> Are there any reasons to not use ArithException?
>
>
> It is intended that you do not divide by zero, also because it is so simple
> to check it before calling the function.

Surely if that expectation (that the user not divide by zero) was
actually part of the design intention, then the check within the
function itself would be redundant.

There is already a check within the function. Perhaps changing its
behaviour to use the existing ArithException DivideByZero would be
consistent with other types?

+1 to Kazu's suggestion to throw DivideByZero.

For the implementation, if the underlying type throws DivideByZero on
division by zero anyway, perhaps all that is requried is to remove the
check.

> The best solution would certainly
> be a number type that excludes zero values, such that division by zero can
> be catched at compile time. But currently Haskell's type system may not be
> expressive enough to handle this without a lot of explicit type conversion.

Indeed, it'd be fun to implement this properly in a different
language. For now let's narrow our options down to things that work in
Haskell.

Conrad.

_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
Edward Kmett | 6 Jun 2012 04:24
Picon
Gravatar

Re: Data.Ratio and exceptions

I have to admit I rather prefer the notion of throwing a DivideByZero in this case as well, especially since a lot of things that would otherwise by Double/Float round trip through Rational temporarily during conversion.


-Edward

On Tue, Jun 5, 2012 at 9:35 PM, Conrad Parker <conrad <at> metadecks.org> wrote:
On 5 June 2012 17:24, Henning Thielemann <lemming <at> henning-thielemann.de> wrote:
>
> On Tue, 5 Jun 2012, Kazu Yamamoto (山本和彦) wrote:
>
>> Some functions in Data.Ratio call the error function. The following is
>> an example:
>>
>>   recip (0:%_)        = error "Ratio.%: zero denominator"
>>
>> We cannot catch this error as ArithException since it is ErrorCall.
>> Are there any reasons to not use ArithException?
>
>
> It is intended that you do not divide by zero, also because it is so simple
> to check it before calling the function.

Surely if that expectation (that the user not divide by zero) was
actually part of the design intention, then the check within the
function itself would be redundant.

There is already a check within the function. Perhaps changing its
behaviour to use the existing ArithException DivideByZero would be
consistent with other types?

+1 to Kazu's suggestion to throw DivideByZero.

For the implementation, if the underlying type throws DivideByZero on
division by zero anyway, perhaps all that is requried is to remove the
check.

> The best solution would certainly
> be a number type that excludes zero values, such that division by zero can
> be catched at compile time. But currently Haskell's type system may not be
> expressive enough to handle this without a lot of explicit type conversion.

Indeed, it'd be fun to implement this properly in a different
language. For now let's narrow our options down to things that work in
Haskell.

Conrad.

_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
wren ng thornton | 6 Jun 2012 06:51

Re: Data.Ratio and exceptions

On 6/5/12 9:35 PM, Conrad Parker wrote:
> +1 to Kazu's suggestion to throw DivideByZero.

Another +1 from me.

The essential nature of the function wouldn't be altered any, it'd just 
give a more precise error. Seems like an improvement regardless of how 
one feels about errors/exceptions/bottoms.

Also, I think using DivideByZero is appropriate here. No need to invent 
a new exception type.

--

-- 
Live well,
~wren
Kazu Yamamoto | 6 Jun 2012 07:11
Picon
Gravatar

Re: Data.Ratio and exceptions

Hello,

> The essential nature of the function wouldn't be altered any, it'd
> just give a more precise error. Seems like an improvement regardless
> of how one feels about errors/exceptions/bottoms.
> 
> Also, I think using DivideByZero is appropriate here. No need to
> invent a new exception type.

GHC.Real uses the error function in some places. I believe that most
cases should be throw ArithException. I will survey and make a
comprehensive proposal.

If there are other modules to be surveyed, please let me know.

--Kazu
Simon Marlow | 12 Jun 2012 13:08
Picon

Re: Data.Ratio and exceptions

On 06/06/2012 06:11, Kazu Yamamoto (山本和彦) wrote:
> Hello,
>
>> The essential nature of the function wouldn't be altered any, it'd
>> just give a more precise error. Seems like an improvement regardless
>> of how one feels about errors/exceptions/bottoms.
>>
>> Also, I think using DivideByZero is appropriate here. No need to
>> invent a new exception type.
>
> GHC.Real uses the error function in some places. I believe that most
> cases should be throw ArithException. I will survey and make a
> comprehensive proposal.
>
> If there are other modules to be surveyed, please let me know.

I'll go ahead and make this change.  Thanks for the suggestion!

Cheers,
	Simon

_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
Simon Hengel | 13 Jun 2012 12:57
Gravatar

Re: Data.Ratio and exceptions

> I'll go ahead and make this change.  Thanks for the suggestion!

I agree that ArithException feels more appropriate here.  But I make two
observations:

(1) It replaces specific error messages with less specific ones.

    The error message will not include the function/operator name
    anymore, e.g.:

    ghci> 1 % 0
    *** Exception: Ratio.%: zero denominator

    would become:

    ghci> 1 % 0
    *** Exception: divide by zero

(2) It is a breaking API change, and the complier won't help you to
    detect it in client code.

I'm not saying that this is a bad idea, I just try to understand what
the benefits of this breaking change are.  If it only gives us less
useful error messages, than I'm not convinced**.

Cheers,
Simon

** If we had stack traces with source locations that are enabled by
   default, I would be less reluctant to this change.
wren ng thornton | 14 Jun 2012 03:27

Re: Data.Ratio and exceptions

On 6/13/12 6:57 AM, Simon Hengel wrote:
>> I'll go ahead and make this change.  Thanks for the suggestion!
>
> I agree that ArithException feels more appropriate here.  But I make two
> observations:
>
> (1) It replaces specific error messages with less specific ones.
>
>      The error message will not include the function/operator name
>      anymore, e.g.:
>
>      ghci>  1 % 0
>      *** Exception: Ratio.%: zero denominator
>
>      would become:
>
>      ghci>  1 % 0
>      *** Exception: divide by zero

That's no good. I wonder whether ArithExceptions should be given their 
code location a la assertion failures[1]. Probably all the built-in 
exception types should do so.

[1] http://www.haskell.org/ghc/docs/7.4.1/html/users_guide/assertions.html

--

-- 
Live well,
~wren
Simon Marlow | 14 Jun 2012 12:32
Picon

Re: Data.Ratio and exceptions

On 14/06/2012 02:27, wren ng thornton wrote:
> On 6/13/12 6:57 AM, Simon Hengel wrote:
>>> I'll go ahead and make this change. Thanks for the suggestion!
>>
>> I agree that ArithException feels more appropriate here. But I make two
>> observations:
>>
>> (1) It replaces specific error messages with less specific ones.
>>
>> The error message will not include the function/operator name
>> anymore, e.g.:
>>
>> ghci> 1 % 0
>> *** Exception: Ratio.%: zero denominator
>>
>> would become:
>>
>> ghci> 1 % 0
>> *** Exception: divide by zero
>
> That's no good. I wonder whether ArithExceptions should be given their
> code location a la assertion failures[1]. Probably all the built-in
> exception types should do so.
>
>
> [1] http://www.haskell.org/ghc/docs/7.4.1/html/users_guide/assertions.html

But that wouldn't help - you'd just get a code location somewhere deep 
in the base package every time.

So we could make a separate RatioZeroDenominator exception, and add that 
to ArithException.  That would mean no loss of information relative to 
the current state of affairs.

Cheers,
	Simon
wren ng thornton | 16 Jun 2012 07:12

Re: Data.Ratio and exceptions

On 6/14/12 6:32 AM, Simon Marlow wrote:
> On 14/06/2012 02:27, wren ng thornton wrote:
>> That's no good. I wonder whether ArithExceptions should be given their
>> code location a la assertion failures[1]. Probably all the built-in
>> exception types should do so.
>
> But that wouldn't help - you'd just get a code location somewhere deep
> in the base package every time.

Shouldn't it give the location of the use site of (%)? No, I suppose 
that'd require more special magic...

--

-- 
Live well,
~wren

Gmane