Folks, Another small but long-standing bug in the Haskell Library report: the recursive calls to 'reads' and 'shows' in the Read and Show instances for Ratio and Array should be calls to readsPrec and showsPrec respectively. The corrected defintions are below. (c.f. the example of derived instances in Appendix D of the language report.) Anyone disagree? (How do these bugs last so long?) Simon ================== Page 5 ======================== instance (Read a, Integral a) => Read (Ratio a) where readsPrec p = readParen (p > prec) (\r -> [(x%y,u) | (x,s) <- readsPrec (prec+1) r, ("%",t) <- lex s, (y,u) <- readsPrec (prec+1) t ]) instance (Integral a) => Show (Ratio a) where showsPrec p (x:%y) = showParen (p > prec) (showsPrec (prec+1) x . showString " % " . showsPrec (prec+1) y) ================== Page 24 ======================== instance (Ix a, Show a, Show b) => Show (Array a b) where showsPrec p a = showParen (p > arrPrec) ( showString "array " . showsPrec (arrPrec+1) (bounds a) . showChar ' ' . showsPrec (arrPrec+1) (assocs a) ) instance (Ix a, Read a, Read b) => Read (Array a b) where readsPrec p = readParen (p > arrPrec) (\r -> [ (array b as, u) | ("array",s) <- lex r, (b,t) <- readsPrec (arrPrec+1) s, (as,u) <- readsPrec (arrPrec+1) t ]) -- Precedence of the 'array' function is that of application itself arrPrec = 10
Simon Peyton-Jones <simonpj@microsoft.com> writes:
Another small but long-standing bug in the Haskell Library report: [...]
[...] (How do these bugs last so long?)
None of the compilers actually use the report Prelude/libraries. When writing the STG-Hugs backend I used the actual report code with some minor modifications (see note at end). The result was something that could be diffed against the original or could be executed and used with a testsuite. This turned up a lot of minor errors in the report. I think this is the only way we'll catch problems in the report. (Ideally, the report would take the form of a model Haskell compiler and library...) -- Alastair Reid alastair@reid-consulting-uk.ltd.uk Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair/ The main changes needed to the report to make it work with STG-Hugs were: 1) Fill in the ...'s 2) Since Hugs lacks mutually recursive modules, modify the module headers to read something like: Prelude.hs: module Prelude( <whatever Prelude exports> ) where import PreludeCore List.hs: module List( <whatever List exports> ) where import PreludeCore Char.hs: module Char( <whatever Char exports> ) where import PreludeCore PreludeCore.hs: #ifdef __HUGS__ module PreludeCore where #include "ReportPreludeList.hs" #include "ReportList.hs" #include "ReportChar.hs" #include "ReportNumeric.hs" #else /* use original text */ module Prelude( .... ) where import PreludeList import List import Char import Numeric #endif ... rest of file as in Prelude in Haskell Report
Alastair Reid <alastair@reid-consulting-uk.ltd.uk> writes:
[...] (How do these bugs last so long?)
None of the compilers actually use the report Prelude/libraries.
Not entirely true. A large chunk of the nhc98 (and hat) libraries is copied directly from the Report. The real problem (maybe this is what you meant), is that there is no comprehensive test suite for conformance. We make do with bits and pieces, but until someone actually uses the buggy part of a library and complains, we have no test to find it. So I guess that means very few people are using Array and Ratio, or at least we aren't show'ing and read'ing them, or the particular enclosing precedence value that triggered this bug is very rare. This has been said before, but maybe we need someone to formulate a huge set of QuickCheck properties about the Prelude/Libraries. That would root out quite a lot of remaining bugs relatively quickly I suspect. Regards, Malcolm
Malcolm:
Not entirely true. A large chunk of the nhc98 (and hat) libraries is copied directly from the Report.
I think we all copied from the report originally - the problem is that we fix our copies of the code and forget to fix the original. The method I described was intended to let me run off the actual files used in the report.
This has been said before, but maybe we need someone to formulate a huge set of QuickCheck properties about the Prelude/Libraries. That would root out quite a lot of remaining bugs relatively quickly I suspect.
I think we'd want a modified version of quickcheck which generated a file of results which were then checked by an external tool. The problem being that there's a wide range of compiler bugs which can make a program return 'True' without actually executing the program correctly. With that modification, I strongly agree. -- Alastair
Malcolm Wallace wrote: | This has been said before, but maybe we need someone | to formulate a huge set of QuickCheck properties about | the Prelude/Libraries. That would root out quite a | lot of remaining bugs relatively quickly I suspect. This sounds like an interesting (student) project, that would require to develop new methodologies for testing with QuickCheck. Alastair Reid wrote: | I think we'd want a modified version of quickcheck | which generated a file of results which were then | checked by an external tool. The problem being that | there's a wide range of compiler bugs which can make a | program return 'True' without actually executing the | program correctly. I do not understand what you mean here. Maybe an example helps? | With that modification, I strongly agree. I'm in! /Koen. -- Koen Claessen http://www.cs.chalmers.se/~koen Chalmers University, Gothenburg, Sweden.
On Wed, 24 Jul 2002, Koen Claessen wrote:
Malcolm Wallace wrote:
| This has been said before, but maybe we need someone | to formulate a huge set of QuickCheck properties about | the Prelude/Libraries. That would root out quite a | lot of remaining bugs relatively quickly I suspect.
GHC already uses QuickCheck to test the Haskell 98 Array Module. It does things like randomly permute the index-value pairs, then check that the array is same. It also compares with a reference implementation as provided in the Haskell report. Andy Gill
Alastair Reid:
I think we'd want a modified version of quickcheck which generated a file of results which were then checked by an external tool. The problem being that there's a wide range of compiler bugs which can make a program return 'True' without actually executing the program correctly.
Koen:
I do not understand what you mean here. Maybe an example helps?
The problem is in using Quickcheck for compiler regression testing stems from the fact that Quickcheck and the code it depends on (i.e., bits of the Prelude) are compiled with the same compiler as the library being tested. IIRC correctly, Quickcheck's output is either: 'passed' or 'failed with example x==42, y=27' That first answer ('passed') typically implies that a large number of minor tests succeeded. For example, I might write a quickcheck spec to make sure that a+b == a - (-b) and quickcheck would confirm this by testing 1000 pairs of values of a and b. Now imagine a buggy compiler which, because of some property of the way Quickcheck is written, the way the library under test is written or the way the quckcheck specification is written happens to always return True even if the test fails for some of the inputs. Now Quickcheck will fail to report a bug. [And, yes, the bugs in a mature compiler are sometimes as specific as requiring a combination of two or three libraries to reveal a bug.] The solution is in two parts: 1) Make the 'trusted computing base' smaller so that less of the testing apparatus will break if the compiler is broken. Do this by using Quickcheck to generate a file of data and a separate tool (e.g., a perl script) to check for errors. For example, quickcheck could report: Testing 'a+b == a - (-b)': 0 == 0 -- when a=0, b=0 1 == 1 -- when a=0, b=1 2 == 2 -- when a=0, b=2 1 == 1 -- when a=1, b=0 2 == 2 -- when a=1, b=1 3 == 3 -- when a=1, b=2 and a separate tool would test that the text on the left of the == is textually identical to the text on the right of the ==. [In practice, I'd probably make the output from quickcheck a bit easier for a machine to read at the expense of making it a bit less pleasant for a human to read. It should still be human readable, of course because humans have to be able to look at the output and figure out what went wrong.] 2) Compare the output from today's run against the output from yesterday's run (or, better, the output from the last successful run). Is this any clearer? -- Alastair Reid alastair@reid-consulting-uk.ltd.uk Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair/
participants (5)
-
Alastair Reid -
andy -
Koen Claessen -
Malcolm Wallace -
Simon Peyton-Jones