
Hi, Often when compiling with Hat I run into the Int vs Integer issue, in fact this is pretty much the biggest problem I have getting hat traces generated. I was considering if there was any possible change that could be performed by Hat to remove this restriction. The best I came up with makes semantic changes to the program, but these changes are "very minimal" at a guess :) The idea basically revolves around "type Int = Integer" - replace all occurances of Int with Integer at the type level, make all functions that operate on Int now operate on Integer instead, and all numeric literals can now become Integer, since there is no Int. There are two semantic changes from this which I have thought of: 1) big_number * 2 will never overflow, which will give a different semantics. Personally this sounds like a good idea, and having a hat-overflow tool to detect when an Integer goes above 2^31 would probably be a useful addition. I don't consider this change to be all that bad, since its compatible with the Haskell98 report (I think). 2) More seriously, type classes will lead to different code being invoked. For example while 0 == 0 might have invoked Int equality now it will invoke Integer equality. My guess is that if there is a program where the type class for Int is not a subset of the behaviour of that for Integer, its very weird and confusing and probably buggy. The changes to the generator that would need to be made are (as far as I can tell) as follows: * Replace all occurances of Int with Integer * Make all numeric literals 0 :: Integer * On encountering a typeclass if there existing an instance for one of Int or Integer, then use that one. If instances exists for both Int and Integer then throw away the Int version. For a prototype, allow-undecideable-instances & allow-overlapping-instances should handle this automatically. * Any primitive operations that are performed on Int and not Integer would need to be worked around, probably on a case by case basis, but this should be a small number. Comments or thoughts? Thanks Neil

On 24 Jun 2006, at 20:41, Neil Mitchell wrote:
Hi,
Often when compiling with Hat I run into the Int vs Integer issue, in fact this is pretty much the biggest problem I have getting hat traces generated. I was considering if there was any possible change that could be performed by Hat to remove this restriction.
The best I came up with makes semantic changes to the program, but these changes are "very minimal" at a guess :)
The idea basically revolves around "type Int = Integer" - replace all occurances of Int with Integer at the type level, make all functions that operate on Int now operate on Integer instead, and all numeric literals can now become Integer, since there is no Int.
There are two semantic changes from this which I have thought of:
1) big_number * 2 will never overflow, which will give a different semantics. Personally this sounds like a good idea, and having a hat-overflow tool to detect when an Integer goes above 2^31 would probably be a useful addition. I don't consider this change to be all that bad, since its compatible with the Haskell98 report (I think).
2) More seriously, type classes will lead to different code being invoked. For example while 0 == 0 might have invoked Int equality now it will invoke Integer equality. My guess is that if there is a program where the type class for Int is not a subset of the behaviour of that for Integer, its very weird and confusing and probably buggy.
The changes to the generator that would need to be made are (as far as I can tell) as follows:
* Replace all occurances of Int with Integer * Make all numeric literals 0 :: Integer * On encountering a typeclass if there existing an instance for one of Int or Integer, then use that one. If instances exists for both Int and Integer then throw away the Int version. For a prototype, allow-undecideable-instances & allow-overlapping-instances should handle this automatically. * Any primitive operations that are performed on Int and not Integer would need to be worked around, probably on a case by case basis, but this should be a small number.
Comments or thoughts?
The basic problem with this is that the bug may well be that an Int is overflowing... You don't want the bug to not manifest it's self in the self tracing version. Bob

Hi,
1) big_number * 2 will never overflow, which will give a different semantics. Personally this sounds like a good idea, and having a hat-overflow tool to detect when an Integer goes above 2^31 would probably be a useful addition. I don't consider this change to be all that bad, since its compatible with the Haskell98 report (I think).
The basic problem with this is that the bug may well be that an Int is overflowing... You don't want the bug to not manifest it's self in the self tracing version.
If we assume that most Haskell numbers are below 2 billion - both Int and Integer, then its easy enought to detect all the places where a number exceeds this in the trace. I suspect that for most programs this will be never. If it does occur, I suspect it will be very rare, and all these occurences can be listed, which would directly track down the bug really quickly (faster than with the current Hat tools). The theoretical "hat-overflow" tool can be written which does this. I suspect a bigger problem would be where the code for an Int instance is dubious, since that is actually a completely different code path. But again, I guess this happens really really rarely. I guess most Int/Integer instances are in the standard libraries, so relatively safe. To be clear, because of the semantic changes associated with this approach, this should be a configurable option. Thanks Neil

On 24 Jun 2006, at 21:11, Neil Mitchell wrote:
Hi,
1) big_number * 2 will never overflow, which will give a different semantics. Personally this sounds like a good idea, and having a hat-overflow tool to detect when an Integer goes above 2^31 would probably be a useful addition. I don't consider this change to be all that bad, since its compatible with the Haskell98 report (I think).
The basic problem with this is that the bug may well be that an Int is overflowing... You don't want the bug to not manifest it's self in the self tracing version.
If we assume that most Haskell numbers are below 2 billion - both Int and Integer, then its easy enought to detect all the places where a number exceeds this in the trace. I suspect that for most programs this will be never. If it does occur, I suspect it will be very rare, and all these occurences can be listed, which would directly track down the bug really quickly (faster than with the current Hat tools). The theoretical "hat-overflow" tool can be written which does this.
I think the question is more whether such a tool would ever be run. The users thought path is likely to be along the lines of "oh... it works now... I can't debug it if it worked" Bob

"Neil Mitchell"
Often when compiling with Hat I run into the Int vs Integer issue, in fact this is pretty much the biggest problem I have getting hat traces generated.
I think you are probably referring to the lack of defaulting for ambiguous numeric literals. This is not really an Int vs Integer thing. It occurs when an expression contains both numbers and numeric operations without a type signature to disambiguate which specific type to use for the operation. In normal Haskell'98, they would default to Integer. There is no Int involved at all. So your proposed solution (aliasing Int to Integer) would not actually solve the problem, which is about resolving class constraints.
1) big_number * 2 will never overflow, which will give a different semantics. Personally this sounds like a good idea, and having a hat-overflow tool to detect when an Integer goes above 2^31 would probably be a useful addition. I don't consider this change to be all that bad, since its compatible with the Haskell98 report (I think).
This kind of overflow detection would be somewhat easy to write in Tom's proposed Hat query language (WHat). find an application of (*) [ or (+) ] where the absolute value of both operands exceeds 1 where the absolute value of the result is smaller than the absolute value of either operand [ app | ((*) x y) <- app , absvalue(x) > 1 , absvalue(y) > 1 , (absvalue(app) < absvalue(x)) || (absvalue(app) < absvalue(y)) ] A similar property could also be written in QuickCheck, to find overflow errors through testing.
* Make all numeric literals 0 :: Integer
You could make a case for simply attaching a type signature to any numeric literal that does not already have one. It would certainly fix the numeric defaulting problem, because it removes all ambiguity. However, it would be incorrect for programs that do not currently suffer from numeric ambiguity. For instance, it is relatively common to define new numeric types e.g. Matrix, where a literal number n has a reasonable interpretation e.g. as the identity matrix scaled by n. Forcing the literal to be of type Integer would make the program type-incorrect. Unfortunately, hat-trans is a syntactic transformation which (deliberately) does not have access to type inference. If it did, then the defaulting problem would be easily solved. Regards, Malcolm
participants (3)
-
Malcolm Wallace
-
Neil Mitchell
-
Thomas Davie