Note:

hWaitForInput stdin 4294968296


is using fromInteger, not fromIntegral. fromInteger is the member of Num. fromIntegral is defined in terms of it and toInteger.

Deprecating fromIntegral would do nothing to the example you offered at all as it isn't being called.

Like it or not the existing numeric types in the Haskell ecosystem wrap, and changing this behavior would have non-trivial ramifications for almost all Haskell source code written to date.

This isn't a small change you are proposing.

If your goal is to address this micro-issue, it would be a much easier target to aim for hWaitForInput taking an Integer rather than an Int, removing the issue at the source. There are already packages providing safer delays, e.g.

https://hackage.haskell.org/package/unbounded-delays

It has gradually become clear that using Int in delay and hWaitForInput and delay the like was a mistake. After all if you're going to set up to block anyways the overhead of allocating a single Integer constructor is trivial.

For comparison, I have zero objection to going after the type signature of hWaitForInput!

Changing fromInteger on the other hand is a Prelude affecting change that bubbles all the way down into Num. I'm very much against breaking every single Num instance, and making every Haskell developer audit every application of a very common function to fix one overflow in one naively designed system call.

-Edward

On Thu, Sep 21, 2017 at 1:26 PM, Niklas Hambüchen <mail@nh2.me> wrote:
Hey Edward,

I'm not going after Num here.

What I care about is that base provide conversion functions with clear
names that indicate what they do, so that the intent of the author
becomes obvious.

Currently we cram all number conversion functionality into
`fromIntegral`, and offer no standard way for talking about code that
has no intent to wrap.

This code:

  fdReady ... (fromIntegral msecs)

does not look obviously incorrect, but this code would:

  fdReady ... (fromIntegralWrap msecs)

Of course it would be great if a name change came along with a set of
type classes that make it compile-time-impossible to do an unintended
cast, but in absence of one agreed way to do that, more functions with
better names and appropriate error behaviour would already go a long way
for avoiding bugs like this.

To throw out some concrete examples, there could be:

* maybeFromInteger / maybeFromIntegral
  - that return Nothing when the input doesn't fit
* runtimeCheckedFromInteger / runtimeCheckedFromIntegral
  - `error` on Nothing
* fromIntegerWrap / fromIntegralWrap
  - what the current functions do
* fromInteger / fromIntegral
  - unchanged semantics, but emitting a deprecation warning

Deprecation seems the best method by which we can systematically
highlight all use sites where a replacement with a function of a better
name, or missing edge case handling, should be inserted, without
breaking code.

Niklas