RE: happy/LALR.hs doesn't compile
With sources (and GHC) as checked out at 3am BST today: /usr/local/pub-bkb/ghc/ghc-latest/bin/ghc -cpp -fglasgow-exts -O -H12m -c LALR.lhs -o LALR.o -osuf o LALR.lhs:314: Variable not in scope: `newArray' LALR.lhs:316: Variable not in scope: `freezeArray' LALR.lhs:336: Variable not in scope: `readArray' LALR.lhs:337: Variable not in scope: `writeArray' LALR.lhs:342: Variable not in scope: `readArray' Fixed. Simon
Re: improving error messages
(Sent to glasgow-haskell-users rather than haskell, as it is GHC-specific.) If we were writing a C library rather than a Haskell library, we could make "head" a macro which included an appropriate message referring to __FILE__ and __LINE__. The equivalent in Glasgow Haskell would be to make head inline, and include a primHaskellFile (and if possible, though I doubt it, primHaskellLine) which got replaced at a late stage by the actual name of the current module. This would be useful for locating other error messages as well. For example I have a debug action which (if debugging is turned on) prints out messages to a file; if we had a primHaskellFile I could make this debug message automatically refer to the calling module, which would be nice.
Re: improving error messages
Sergey, I could not agree more. I sent the following message to the Hugs implementors a few months ago. I have taught Hugs for a couple of years and enjoy using it. Students like to have a system they can take home and install for free, and the system seems pretty robust. One problem students do have, however, is with error messages, which often leave a bit to be desired. An incorrectly terminated block of definitions can lead to the message ERROR "test.lhs" (line 2): Syntax error in input (unexpected `;') for a file in which there is no a `;' in sight. Using = for an equality comparison instead of == leads to the magisterial ERROR "test.lhs" (line 6): Attempt to use Typed Records with Extensions while parsing an expression. This feature is disabled in this build of Hugs. To help students I have compiled a list of messages and examples of code that provoke them. In many cases a little effort would, I guess, lead to vastly more informative error messages. I'd be interested to hear what you (and the Hugs group) think. The catalogue of errors is at http://www.cs.ukc.ac.uk/people/staff/sjt/craft2e/errors.html Regards Simon Thompson
RE: improving error messages
take :: Int - [a] - [a] If you want to define your own take mytake :: Show a = Int - [a] - [a] that's fine, but it's a different function. And for (head []) there's really no useful info to hand. So I'm stumped. Although you can't show the value (because there isn't one), you can at least show the type of the expression: class ShowType a where showType :: a - String instance ShowType a = ShowType [a] where showType xs = "[" ++ showType x ++ "]" where ~(x:_) = xs Then myhead :: ShowsType a = [a] - a myhead xs@[] = error ("myhead of empty list at type "++ showType xs) myhead (x:_) = x which, like "mytake", is a different function from the one defined in the Prelude, but might give you enough info to help track down the error. Regards, Malcolm
improving to improving error messages
To my suggestion on the error messages Ketil Malde [EMAIL PROTECTED] writes [..] e.g instead of Hugs' Prelude head: head :: [a] - a head (x:_)= x we can use: head :: [a] - a head [] = error "Error: taking the 'head' of an empty list" head (x:_)= x The Haskell implementation I use reports something of this sort. But this does not help. Also "head []" is the only error that may happen to `head'. I wrote that, generally, for the Prelude Functions, it would help in error messages to print some part of value and type expression. But with head [], I had, probably, mistaken. -- Because the program for `head' itself cannot find the type of `[]'; this may hope to do other functions, where `head' is called. Probably, we cannot improve the function `head' itself. (?) But the things like take (-1) [(1,'b'),(2,'a')], (1) let x = 0 in 0 ^ 0,(2) y % 0 (3) could produce better messages. Here x :: Num a = a, y :: Integral b = b for some a,b. One needs the values and type expression to be displayed. The latter is desirable too. Because `0',`1' may denote zero, unity of many different Num instances. If the data were of Show instance, class Show included the operation showType, with the reasonable standard instances, Show was a superclass of Num, then, one could express such type displaying in Haskell language for the cases (2), (3). With `take', it is harder. We need the possibility of overlapping values to define take :: Show a = Int - [a] - [a] that overlaps with more generic take :: Int - [a] - [a] The first specialization would produce better error report at the run-time. Note that take already does bomb out if given a negative argument. And I take this `take' only as example, --- for there was earlier the discussion in this mail list on how to treat negative or too large index in `take'. -- Sergey Mechveliani [EMAIL PROTECTED]
Re: ServiceShow for error messages
Sergey writes: Maybe, there exists another possibility to print the values in the error message like for take (-1) xs, y % 0 The implementors declare the "internal" class ServiceShow where serviceShows :: ... invisible for the user, make *everything* to be the instance of ServiceShow, The problem with this is that there is a performance penalty to be paid for overloading a function in this way. `take' is implemented as a function of two arguments, as you would expect. It is given a number and a list; it has no idea what type the list has, nor does it need to: it just picks elements off it and returns them. But because it has no idea what type the list has, it has no idea how to print the contents of that list. Enter the class mechanism. If we have class ServiceShow where serviceShows :: ... mytake :: ServiceShow a = Int - [a] - [a] then mytake is now implemented as a function of *three* arguments: the number and the list, as before, but also a `dictionary' which looks like this: data ServiceShowDict a = ServiceShowDict { serviceShows :: ... } mytake_implementation :: ServiceShowDict a - Int - [a] - [a] [it's no accident that class constraints `C a =' are written the way they are... they are really extra arguments `CDict a -'.] and wherever `serviceShows' is called, the code really looks like: mytake_implementation d n (x:xs) = ... (serviceShows d) x ... In other words, if you implement the above proposal, every invocation of take will be passed an extra argument, which will be only very rarely used. Perhaps this could be turned on with a debugging option, but in general it would be a Very Bad Thing performance-wise. HTH. --KW 8-)
RE: ServiceShow for error messages
The problem with this is that there is a performance penalty to be paid for overloading a function in this way. `take' is implemented as a function of two arguments, as you would expect. It is given a number and a list; it has no idea what type the list has, nor does it need to: it just picks elements off it and returns them. In Hugs, there's no need to do the dictionary passing because it has a polymorphic show function (used to be called show', is it something like primShow now?). In GHC, you can't do this kind of built-in overloading because there isn't enough type information in the heap at run-time, so you'd have to do the dictionary passing. Cheers, Simon
Re: deBruijn sequences
From: Jan de Wit [EMAIL PROTECTED] Pray tell, what *are* base-2 deBruijn sequences? I know what deBruijn terms are, and have some code for them, but as for sequences... I think you are going to get a lot of replies like this one ;-) The following three are examples of binary de Bruijn sequences: 8bit sequence for 3bit words 00010111 32bit sequence for 5bit words 010001100101001110101101 256bit sequence for 8bit words 1001101010111100110111101111 100010001001100010101000101110001100100011011000111010001001 001010010011100101011001011010010001100110101001101110011101 1000100110101010111010110110101011001110 The sequences are cyclic and any n bits in an associated p^n sequence are unique, therefore all p^n unique patterns occur. I certainly didn't expect any of the type of replies you are inferring. de Bruijn sequences have been kicking around in one form or another for over 50 years - you can find the basics of the theorem in most books on discrete math or combinatrics. The method I was "taught" to make the sequences involves drawing out a p^(n-1) node and p^n edge (directed) graph (more or less a FSM), labelling it appropriately, and finding an Euler cycle through it. I was able to get some very sloppy C code to do the job, but I'm far from happy with it... it came completely undocumented and is quite difficult to trace through. The other code I have is concise and (supposedly) efficient, but it is in NESL, which I have no way of running. Wayne
Re: .gz files
Thanks for this workaround, it worked. This might be a tip to be put on the mailing list, since other people using Windows NT and Winzip might have the same problem. Friendly Jan Brosius - Original Message - From: Simon Peyton-Jones [EMAIL PROTECTED] To: 'Jan Brosius' [EMAIL PROTECTED] Sent: Friday, March 31, 2000 1:58 PM Subject: RE: .gz files | However if you have no problems opening these files with | winzip, then I | don't know | anymore. I do have a problem. I download them. If winzip complains I remove the .gz suffix. Then ghostview reads them fine. I have no idea why they are invisibly uncompressed. I'm just telling you a workaround that works for me Simon
ServiceShow class for messages
Keith Wansbrough [EMAIL PROTECTED] writes Sergey writes: Maybe, there exists another possibility to print the values in the error message like for take (-1) xs, y % 0 The implementors declare the "internal" class ServiceShow where serviceShows :: ... invisible for the user, make *everything* to be the instance of ServiceShow, The problem with this is that there is a performance penalty to be paid for overloading a function in this way. [..] then mytake is now implemented as a function of *three* arguments: the number and the list, as before, but also a `dictionary' [..] In other words, if you implement the above proposal, every invocation of take will be passed an extra argument, which will be only very rarely used. Perhaps this could be turned on with a debugging option, but in general it would be a Very Bad Thing performance-wise. I somehow do not believe in this philosophy: of extra argument slowing down the performance any essentially. Still, let us try example: length2 :: Show a = [a] - Int length2 [x,y] = error $ ("length2 "++) $ shows [x,y] "\n Do not like lists of length 2 ! \n" length2 xs= ln xs 0 where ln [] n = n ln (_:xs) n = ln xs (succ n) main = let xs = [1..999000] :: [Int] n = length2 xs -- compare to length in putStr $ shows n "\n" In the implementation I use, length2 is as fast as Prelude.length. ? -- Sergey Mechveliani [EMAIL PROTECTED]
Re: improving error messages
On Fri, 31 Mar 2000, S.J.Thompson wrote: To help students I have compiled a list of messages and examples of code that provoke them. In many cases a little effort would, I guess, lead to vastly more informative error messages. I'd be interested to hear what you (and the Hugs group) think. The catalogue of errors is at http://www.cs.ukc.ac.uk/people/staff/sjt/craft2e/errors.html To the maintainers of www.haskell.org pages: Would you consider linking to that page? Now that (I am so sorry about it!) wiki-wiki pages are permanently down some alternate mechanism for "howtos" or "faqs" is badly needed. Would you also consider salvaging some material from the wiki-wiki and making them available to public? Jan
improving error messages
Malcolm Wallace [EMAIL PROTECTED] writes And for (head []) there's really no useful info to hand. So I'm stumped. Although you can't show the value (because there isn't one), you can at least show the type of the expression: Printing the type is very desirable in this situation. But I did not know it is possible! class ShowType a where [..] instance ShowType a = ShowType [a] where showType xs = "[" ++ showType x ++ "]" where ~(x:_) = xs [..] !! Indeed, try class ShowType a where showsType :: a - String - String instance ShowType Char where showsType _ = ("Char"++) instance ShowType a = ShowType [a] where showsType xs = ('[':) . showsType x . (']':) where ~(x:_) = xs myhead :: ShowType a = [a] - a myhead xs@[] = error $ ("myhead [], [] :: "++) $ showsType xs "\n" myhead (x:_) = x main = let xss = ["ab","cd"] in putStr $ shows (myhead $ tail $ tail xss) "\n" --- And it says Fail: myhead [], [] :: [[Char]] But this is very good! Thank you. My program exploits certain showsDomOf, similar as your showsType, and could not sensibly display "empty" things, like Vector []. Looks like ~(x:_) gives access to a constant instance operation on the type of an element of xs even when xs is empty. We need to apply op to any element of the type of the elements of xs. op depends really on the type, not on the value inside type. Now, xs occurs empty. Still ~(x:_) finds the needed element to apply op to. Looks like it works. But I do not understand the whole thing, so far. -- Sergey Mechveliani [EMAIL PROTECTED]
Re: ServiceShow class for messages
S.D.Mechveliani ([EMAIL PROTECTED]) wrote: [ error messages printing their aguments ] Printing the argument of a function as part of an error message may lead to infinite error messages. It may even lead to several calls to error which all have to be shown. I don't think a compiler will ever be able to detect such infinite situations and should therefore not be allowed to automatically print arguments because the quality of the messages will be very bad. Also I just looked up the following in the language definition: A call to error terminates execution of the program and returns an appropriate error indication to the operating system. It should also display the string in some system-dependent manner. When undefined is used, the error message is created by the compiler. This suggests that a call to error should result in termination. Perhaps I am missing something. Regards, Marc
Re: improving error messages
On 30-Mar-2000, Simon Peyton-Jones [EMAIL PROTECTED] wrote: | What do you think of improving the error messages like | Prelude.take: negative argument | (for say, take (-1) [(0,'b'),(1,'a')] ) That would be splendid. But I don't see how to do it. take :: Int - [a] - [a] Since take is polymorphic in a, I can't print a member of the list. If you want to define your own take mytake :: Show a = Int - [a] - [a] that's fine, but it's a different function. Well, there's two separate issues here. One issue is what exception is thrown. One this issue, you are absolutely right: there is no way for the exception thrown to expose any information about the value or type of the argument, without breaking some of the nice properties that Haskell possesses. The other issue is what error message the implementation prints out if such an exception is not caught (as is _always_ the case for implementations which don't support ghc's `Exception' module or something equivalent). And on this issue, Haskell semantics don't impose any constraints. The message that the implementation prints out can be as informative as the implementor is capable of. There is no conceptual difficulty with a Haskell implemention printing out a full stack trace, complete with the values of all of the arguments. Of course, modifying an existing implementation to do so may well be by no means trivial, but it's just a matter of programming... If you really don't see how it could be done, I'd be happy to sketch the outline of a possible implementation. -- Fergus Henderson [EMAIL PROTECTED] | "I have always known that the pursuit WWW: http://www.cs.mu.oz.au/~fjh | of excellence is a lethal habit" PGP: finger [EMAIL PROTECTED]| -- the last words of T. S. Garp.
RE: improving error messages
The stack trace in a lazy language is usually unhelpful, since it describes the consumer of (hd []) not its producer. That's why the cost-centre stack idea is likely to help. Simon | -Original Message- | From: Fergus Henderson [mailto:[EMAIL PROTECTED]] | Sent: 01 April 2000 16:53 | To: Simon Peyton-Jones | Cc: '[EMAIL PROTECTED]'; [EMAIL PROTECTED] | Subject: Re: improving error messages | | | On 30-Mar-2000, Simon Peyton-Jones [EMAIL PROTECTED] wrote: | | What do you think of improving the error messages like | | Prelude.take: negative argument | | (for say, take (-1) | [(0,'b'),(1,'a')] ) | | That would be splendid. But I don't see how to do it. | | take :: Int - [a] - [a] | | Since take is polymorphic in a, I can't print a member of the | list. If you want to define your own take | | mytake :: Show a = Int - [a] - [a] | | that's fine, but it's a different function. | | Well, there's two separate issues here. | | One issue is what exception is thrown. One this issue, you | are absolutely | right: there is no way for the exception thrown to expose any | information | about the value or type of the argument, without breaking | some of the nice | properties that Haskell possesses. | | The other issue is what error message the implementation | prints out if such an | exception is not caught (as is _always_ the case for | implementations which | don't support ghc's `Exception' module or something equivalent). | And on this issue, Haskell semantics don't impose any constraints. | The message that the implementation prints out can be as informative | as the implementor is capable of. | | There is no conceptual difficulty with a Haskell implemention | printing out a | full stack trace, complete with the values of all of the | arguments. Of | course, modifying an existing implementation to do so may | well be by no means | trivial, but it's just a matter of programming... | If you really don't see how it could be done, I'd be happy to sketch | the outline of a possible implementation. | | -- | Fergus Henderson [EMAIL PROTECTED] | "I have always known | that the pursuit | WWW: http://www.cs.mu.oz.au/~fjh | of excellence is a | lethal habit" | PGP: finger [EMAIL PROTECTED]| -- the last words | of T. S. Garp. |
Re: improving error messages
Malcom and Sergey write: instance ShowType a = ShowType [a] where showsType xs = ('[':) . showsType x . (']':) where ~(x:_) = xs Perhaps where [x] = [error "not used"] `asTypeOf` xs gives the idea better. --KW 8-) -- : Keith Wansbrough, MSc, BSc(Hons) (Auckland) ---: : PhD Student, Computer Laboratory, University of Cambridge, UK. : : Native of Antipodean Auckland, New Zealand: 174d47'E, 36d55'S. : : http://www.cl.cam.ac.uk/users/kw217/ mailto:[EMAIL PROTECTED] : ::
Re: ServiceShow for error messages
On 31-Mar-2000, Keith Wansbrough [EMAIL PROTECTED] wrote: Sergey writes: [sketch of how to implement better error messages] The problem with this is that there is a performance penalty to be paid for overloading a function in this way. ... Perhaps this could be turned on with a debugging option but in general it would be a Very Bad Thing performance-wise. Certainly in cases where there is a trade-off between performance and good error messages, it is appropriate to use a compiler option to allow the programmer to select what they want. The Mercury compiler, for example, does exactly this: if you compile without debugging enabled, then error messages for uncaught exceptions include only the exception object and its type, whereas if you compile with debugging enabled then you also get a full stack trace, and furthermore if you then run the program under the Mercury debugger, then you can also browse the arguments of any of the calls on the call stack. While laziness does complicate things significantly, the same kind of thing would certainly be possible for Haskell too. -- Fergus Henderson [EMAIL PROTECTED] | "I have always known that the pursuit WWW: http://www.cs.mu.oz.au/~fjh | of excellence is a lethal habit" PGP: finger [EMAIL PROTECTED]| -- the last words of T. S. Garp.
Re: ServiceShow class for messages
On 31-Mar-2000, Marc van Dongen [EMAIL PROTECTED] wrote: S.D.Mechveliani ([EMAIL PROTECTED]) wrote: [ error messages printing their aguments ] Printing the argument of a function as part of an error message may lead to infinite error messages. Well, of course if the argument is large (let alone infinite), you don't want to print it all out, just part of it. And of course you don't want to evaluate the argument any further than it is already evaluated. But this is quite doable. -- Fergus Henderson [EMAIL PROTECTED] | "I have always known that the pursuit WWW: http://www.cs.mu.oz.au/~fjh | of excellence is a lethal habit" PGP: finger [EMAIL PROTECTED]| -- the last words of T. S. Garp.
Re: improving error messages
instance ShowType a = ShowType [a] where showsType xs = ('[':) . showsType x . (']':) where ~(x:_) = xs Looks like ~(x:_) gives access to a constant instance operation on the type of an element of xs even when xs is empty. Looks like it works. But I do not understand the whole thing, so far. The assumption is that for all instances of "ShowType", the argument of the "showsType" function is either: * not used at all (e.g. for Int, Char, etc.); or * used only in a recursive call at a less complex type. Hence, by induction, the argument value is never examined by _any_ runtime call. (And because where/let bindings are lazy, I think probably you don't even need the ~(x:_) lazy pattern; just (x:_) would suffice.) However, the compiler must examine the pattern to determine type information, and thus calculates the correct dictionary to plug in. The same trick extends nicely to sum types as well: instance (ShowType a, ShowType b) = ShowType (Either a b) where showsType x = showString "Either " . showsType a . showChar ' ' showsType b where (Left a) = x (Right b) = x Notice how the argument x is pattern-matched twice, at quite different values! Regards, Malcolm
error messages
To my suggestions on the error messages Marc van Dongen [EMAIL PROTECTED] writes Printing the argument of a function as part of an error message may lead to infinite error messages. [..] A call to error terminates execution of the program and returns an appropriate error indication to the operating system. [..] Thank you for the remark. What really puzzles me here is the termination and the laziness violence. My application program tries sometimes the messages as in example myTake (-1) (x:y:z:xs) = error $ ("myTake (-1) (x:_) \n x = "++) $ shows x ... But it relies on that this x was not defined as, for example, x = 'a':x Now, what should Prelude.take think of Prelude.take (-1) (x:y:z:xs), how could it decide to display x ? The compiler does not know whether show x would lead to the infinite printing. Example: take (-1) (x,"a","b","c") where x = 'a':x Therefore, some other operation, say, restrictedShows, has to apply here, which is defined so that prints some small part of the value. I wonder whether this is possible. But displaying the type expression, it looks safer, does it? -- Sergey Mechveliani [EMAIL PROTECTED]
Re: error messages
On 31-Mar-2000, S.D.Mechveliani [EMAIL PROTECTED] wrote: Now, what should Prelude.take think of Prelude.take (-1) (x:y:z:xs), how could it decide to display x ? The compiler does not know whether show x would lead to the infinite printing. Example: take (-1) (x,"a","b","c") where x = 'a':x That's a bad example, since it is not type-correct. I presume you meant take (-1) [x,"a","b","c"] where x = 'a':x In that case, I would recommend that the implementation display the second argument to take as [a, "a", "b", "c"] where a = 'a':a I wonder whether this is possible. Yes, it is possible. -- Fergus Henderson [EMAIL PROTECTED] | "I have always known that the pursuit WWW: http://www.cs.mu.oz.au/~fjh | of excellence is a lethal habit" PGP: finger [EMAIL PROTECTED]| -- the last words of T. S. Garp.
RE: improving error messages
[EMAIL PROTECTED] writes: ... Although you can't show the value (because there isn't one), you can at least show the type of the expression: class ShowType a where showType :: a - String Or you can do what hbc has done for donkey's years and include 'showType' in Show. I seem to remember (but am unable to test), that 'deriving(Show)' will do the right thing for Show.showType too. --sigbjorn
deBruijn sequence NESL code
I appreciate any insight anyone has to offer on this code. I obviously don't care about losing NESL's parallel computing power. I am more interested in a relatively efficient and readable function (or functions) as the C code I currently have is garbage to read and I don't have the time to spare to re-write it. I'm too much of a tinkerer when it comes to Haskell (still looking for the "right" book). And yes, I have tried to work it into Haskell myself, with rather pointless results. =) I was going to send the 120k PDF document to the appropriate individuals (only!) but I figured that IEEE would lambaste me spreading their information for free. So instead, I post for your "pleasure" the provided NESL source functions. Pardon my idiocy in converting this code (properly) myself. =) function Next-DeBruijn(w, i, k) = let C = xor_iscan(w); apply (inclusive) prefix scan Cbar = {1 - a : a in C}; compute the bit-complement of the sequence part1 = take (C, i - k); take the first i - k bits from C part2 = drop (Cbar, i - 1 + k); drop the first i - 1 + k bits from Cbar part3 = take (Cbar, i - 1 + k); take the first i - 1 + k bits from Cbar part4 = drop (C, i - k); drop the first i - k bits from C in - - part1 ++ part2 ++ part3 ++ part4 concatenate the list for output function Generate-DeBruijn (n, x) = if (n == 2) then [1,1,0,0] else if (n == 3) then if (x [0] == 0) then [1,0,1,1,1,0,0,0] else [1,1,1,0,1,0,0,0] else Next-DeBruijn (Generate-DeBruijn(n-1,x), 2 ^ (n-2) + (-1) ^ (x[n-4]), x[n-3]); Many thanks, Wayne
Haskore on /.
[Regard this as a continuation of the Haskell in tech news thread...] Paul Hudak's Haskore system made it into part three of the ``Making Music with Linux'' series on /. http://slashdot.org/article.pl?sid=00/03/31/2217202mode=thread It is described as a ``super-techy way of handling notation under Linux'' in the second to last paragraph. Manuel