[GHC] #15646: ghci takes super long time to find the type of large fractional number
GHC
ghc-devs at haskell.org
Sun Sep 23 12:04:24 UTC 2018
#15646: ghci takes super long time to find the type of large fractional number
-------------------------------------+-------------------------------------
Reporter: Johannkokos | Owner:
| JulianLeviston
Type: bug | Status: new
Priority: normal | Milestone: 8.6.1
Component: GHCi | Version: 8.4.3
Resolution: | Keywords: newcomer
Operating System: Unknown/Multiple | Architecture:
Type of failure: Compile-time | Unknown/Multiple
performance bug | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by simonpj):
Some thoughts
* I don't think we should rely on laziness in the compiler. It'll come
back to bite us.
* It's not unreasonable that programs with silly literals will blow up at
runtime, if it is evaluated, because of the `fromRational r` semantics.
But it should not blow up at compile time.
* The underlying problem is that, in the compiler, we represent the
literal as a `Rational`. In `BasicTypes` we have:
{{{
data FractionalLit
= FL { fl_text :: SourceText -- How the value was written in the
source
, fl_neg :: Bool -- See Note [Negative zero]
, fl_value :: Rational -- Numeric value of the literal
}
}}}
This `FractionalLit` is used in `HsLit` and `HsOverLit`. And it is
finally desugar in `Match.dsLit`:
{{{
dsLit :: HsLit GhcRn -> DsM CoreExpr
dsLit l = ...
HsRat _ (FL _ _ val) ty -> do
num <- mkIntegerExpr (numerator val)
denom <- mkIntegerExpr (denominator val)
return (mkCoreConApps ratio_data_con [Type integer_ty, num, denom])
}}}
That is we finally generate Core for `(n % d)`.
* But ''why'' do we produce a compile-time `Rational` for the literal??
For integral values it makes sense to do so, so that we can do constant
folding (turning `1 + 2` into `3` at compile time). But by the time we
get to Core, we've turned it into `n % d` and I don't think we then do any
useful compile time work.
So my solution is this:
1. Drop the `fl_value` field in `FractionalLit`
2. Change `dsLit` on `FractionalLit` to desugar to `readRational <str>`,
where`<str>` is the string the user wrote, recorded in the `fl_text`
field. That is, defer the construction of the `Rational` to runtime.
I think that'd be simple to do.
If we were going to parse a string at runtime, we'd want to be sure that
parsing would succeed, but I think the lexer has ensured that it's
parseble. I suppose another alternative would be to have
{{{
data FractionalLit
= FL { fl_text :: SourceText -- How the value was written in the
source
, fl_neg :: Bool -- See Note [Negative zero]
, fl_before, fl_after, fl_exp :: Integer
-- Denotes <before>.<after>E<exp>
}
}}}
THat is, parse the pieces of the string, and record them in the literal.
Then desugar to `makeRational before after exp` which again defers to
runtime the building of the `Rational` itself.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/15646#comment:14>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list