
Hi all I recently used 2 hours of work looking for a bug that was causing Program error: Prelude.!!: index too large This is not very informative. It did not give me a hint which function was causing this. In C adding a few printf would have helped me, but in haskell I was not sure how to do that. Can anybody point me to some debuggin method everyone uses. After 2 hours I did find the bug eventually. The code can be viewed here. Maybe some reformatting of the code would make finding bugs easier? http://plan9.bell-labs.com/sources/contrib/fernan/escomma/ fernan -- http://www.fernski.com

fernanbolando:
Hi all
I recently used 2 hours of work looking for a bug that was causing
Program error: Prelude.!!: index too large
This is not very informative. It did not give me a hint which function was causing this. In C adding a few printf would have helped me, but in haskell I was not sure how to do that. Can anybody point me to some debuggin method everyone uses.
You could: * use Debug.Trace.trace (equivalent of printf debugging) * use asserts: the 'assert' function * use the GHCi debugger to construct a stack trace * use profiling to construct a stack trace. * use the GHC head branch for first class stack traces, described in, "Finding the needle: Stack Traces for GHC" http://pubs.doc.ic.ac.uk/finding-the-needle/finding-the-needle.pdf -- Don

On Wed, Jul 15, 2009 at 11:13 PM, Don Stewart
fernanbolando:
Hi all
I recently used 2 hours of work looking for a bug that was causing
Program error: Prelude.!!: index too large
This is not very informative. It did not give me a hint which function was causing this. In C adding a few printf would have helped me, but in haskell I was not sure how to do that. Can anybody point me to some debuggin method everyone uses.
You could:
* use Debug.Trace.trace (equivalent of printf debugging) * use asserts: the 'assert' function * use the GHCi debugger to construct a stack trace * use profiling to construct a stack trace. * use the GHC head branch for first class stack traces, described in, "Finding the needle: Stack Traces for GHC" http://pubs.doc.ic.ac.uk/finding-the-needle/finding-the-needle.pdf
Another option would be to use Safe.atMay[1] instead of !!. [1]: http://hackage.haskell.org/packages/archive/safe/0.2/doc/html/Safe.html#v%3A... -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus@therning.org Jabber: magnus@therning.org http://therning.org/magnus identi.ca|twitter: magthe

Of course !! is only one cause for this kind of errror. Another is ghci> head [] *** Exception: Prelude.head: empty list Unfortunately this kind of bug is very hard to debug due to the lazy nature of haskell. You don't have a stack trace as in Java, PHP, .. Example: data D = D String a,b :: [String] a = head [] b = head [] main = do let first = a second = b print first -- both will cause the same error but a different head caused the exception print second One solution is using interlude from hackage. I'm not sure wether it supports !! Also try this haskell-cafe search (you may have to up to page 20 or so) http://search.gmane.org/?query=empty+list+head&author=&group=gmane.comp.lang.haskell.cafe&sort=relevance&DEFAULTOP=and&xP=Zempti%09Zlist&xFILTERS=Gcomp.lang.haskell.cafe---A This reveals this thread for example: http://article.gmane.org/gmane.comp.lang.haskell.cafe/14921/match=empty+list... http://article.gmane.org/gmane.comp.lang.haskell.cafe/6719/match=empty+list+... I recall there was another method. Yeah, I even found it (using ghci and set -fbreak-on-exception) http://donsbot.wordpress.com/2007/11/14/no-more-exceptions-debugging-haskell... HTH Marc Weber

2009/7/16 Marc Weber
I recall there was another method. Yeah, I even found it (using ghci and set -fbreak-on-exception)
http://donsbot.wordpress.com/2007/11/14/no-more-exceptions-debugging-haskell...
Careful, better use -fbreak-on-error rather than -fbreak-on-exception. Some functions, e.g. 'doesFileExist', use exceptions internally and you might end up stopping at an exception that is benign. (Identifying the exception has become a little harder since we got extensible exceptions.) -- Push the envelope. Watch it bend.

Fernan Bolando wrote:
Program error: Prelude.!!: index too large
This is not very informative. It did not give me a hint which function was causing this.
In addition to the debugging methods that have been mentioned, the "Safe" library provides a way to write the code more robustly and/or informatively: http://hackage.haskell.org/package/safe http://community.haskell.org/~ndm/safe/ Among other things, it provides replacements for the (!!) operator which would have likely have helped in this case. Anton

Fernan Bolando
Hi all
I recently used 2 hours of work looking for a bug that was causing
Program error: Prelude.!!: index too large
This is not very informative. It did not give me a hint which function was causing this. In C adding a few printf would have helped me, but in haskell I was not sure how to do that. Can anybody point me to some debuggin method everyone uses.
After 2 hours I did find the bug eventually. The code can be viewed here. Maybe some reformatting of the code would make finding bugs easier? http://plan9.bell-labs.com/sources/contrib/fernan/escomma/
I wonder if your code has to use !! at all? I took a look at a random module from the above link, and (without making much attempt at understanding it), I'd guess that using accumArray and friends would be more appropriate. Mostly you don't want to be doing indexing on lists. -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk

On Thu, Jul 16, 2009 at 4:10 PM, Jon
Fairbairn
I wonder if your code has to use !! at all? I took a look at a random module from the above link, and (without making much attempt at understanding it), I'd guess that using accumArray and friends would be more appropriate. Mostly you don't want to be doing indexing on lists.
-- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk
Thanks for everyone's suggestion. Don Stewarts tools seems to be most appropriate for me. Most of the !! are used to access a list of parameters similar to accessing structures in C. I am not particularly sure how to apply accumArray for something like that? I will go through the accumArray documentation and see how I might apply them. thanks again. fernan -- http://www.fernski.com

Fernan Bolando
On Thu, Jul 16, 2009 at 4:10 PM, Jon Fairbairn
wrote: I wonder if your code has to use !! at all? I took a look at a random module from the above link, and (without making much attempt at understanding it), I'd guess that using accumArray and friends would be more appropriate. Mostly you don't want to be doing indexing on lists.
Most of the !! are used to access a list of parameters similar to accessing structures in C.
Ah. I wondered why so many of them were x!!0. list!!constant is almost always something that could be done better.
I am not particularly sure how to apply accumArray for something like that?
You [probably] don't. My apologies for not looking more carefully (I really did just glance at it), but the remark about not using !! still stands. I've been trying to look at your source again, but the link doesn't respond to requests at the moment, so I can't be much help. Haskell has much richer mechanisms for doing structure-like things than C. Tuples and data types being the most obvious. -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk

On Thu, 16 Jul 2009, Fernan Bolando wrote:
Hi all
I recently used 2 hours of work looking for a bug that was causing
Program error: Prelude.!!: index too large
A good way to avoid such problems is to avoid partial functions at all. (!!) is also inefficient. Is it possible to define the function in terms of foldl?

Henning Thielemann
On Thu, 16 Jul 2009, Fernan Bolando wrote:
Hi all
I recently used 2 hours of work looking for a bug that was causing
Program error: Prelude.!!: index too large
A good way to avoid such problems is to avoid partial functions at all. (!!) is also inefficient. Is it possible to define the function in terms of foldl?
I've looked at the code a bit more, and, with apologies to the original poster, it doesn't look much like Haskell. For example, in http://plan9.bell-labs.com/sources/contrib/fernan/escomma/Circuit.hs there's stuff beginning with tADM :: Int tADM = 1 tVSRC :: Int tVSRC = 2 tISRC :: Int tISRC = 3 ... that I think probably should be data Something = ADM | VSRC | ISRC ... deriving (Enum, ...) though when I get to "(((fst z0)!!pMSET)!!pMTYPE) == mOP" I'm at a loss to determine quite what the intention is. Maybe it should be an array indexed by enum types, maybe a function, maybe something that can be pattern matched on? I don't know. -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk

On Sat, Jul 18, 2009 at 4:57 PM, Jon
Fairbairn
Henning Thielemann
writes: On Thu, 16 Jul 2009, Fernan Bolando wrote:
Hi all
I recently used 2 hours of work looking for a bug that was causing
Program error: Prelude.!!: index too large
A good way to avoid such problems is to avoid partial functions at all. (!!) is also inefficient. Is it possible to define the function in terms of foldl?
I've looked at the code a bit more, and, with apologies to the original poster, it doesn't look much like Haskell. For example, in http://plan9.bell-labs.com/sources/contrib/fernan/escomma/Circuit.hs there's stuff beginning with
tADM :: Int tADM = 1
tVSRC :: Int tVSRC = 2
tISRC :: Int tISRC = 3
...
that I think probably should be
data Something = ADM | VSRC | ISRC ... deriving (Enum, ...)
though when I get to "(((fst z0)!!pMSET)!!pMTYPE) == mOP" I'm at a loss to determine quite what the intention is. Maybe it should be an array indexed by enum types, maybe a function, maybe something that can be pattern matched on? I don't know.
The intention is z0 is a system parameter and database, it contains a set of info needed to define a particular simulation it looks like ( [n,m...], [m,o,p]) n is is a list info settings for the circuit analysis m is a list of statistics for the circuits that is need in sub-sequent calculation m is a list of circuit settings like temperature etc. o is a list of matrix solution for non-linear newton raphson p is a list of matrix solution for time dependent calculations the bug was in o this is a variable length [Double] whose length depends on the size of matrix bieng solved. so. (((fst z0)!!pMSET)!!pMTYPE) == mOP is checking if we are doing mOP type calculations. If this was C this would be a structure of settings and buffer data. fernan -- http://www.fernski.com

Fernan Bolando wrote:
The intention is z0 is a system parameter and database, it contains a set of info needed to define a particular simulation
it looks like ( [n,m...], [m,o,p])
n is is a list info settings for the circuit analysis m is a list of statistics for the circuits that is need in sub-sequent calculation m is a list of circuit settings like temperature etc. o is a list of matrix solution for non-linear newton raphson p is a list of matrix solution for time dependent calculations
This would be better as, data SystemParameterDatabase = SystemParameterDatabase { infoSettings :: InfoSettings , statistics :: Statistics , settings :: Settings , nlnr :: [Matrix Double] , timeDependent :: [Matrix Double] } data InfoSettings = InfoSettings { pMSET :: MSET , aSetting :: A , bSetting :: B ... } data Statistics = Statistics { aStatistic :: A , anotherStatistic :: A , bStatistic :: B ... } data Settings = Settings { temperature :: Kelvin , etc :: Etc } ... A single-constructor ADT, especially with the labeled-fields syntax, is pretty close to C structs; no need to reinvent them and give yourself headaches. Really, the only thing you should be using lists for is a variable-length sequence of elements drawn from the same type and distinguished only by their position in the sequence. Whenever the length is fixed or the (semantic) type of elements can be distinguished from one another (or altered by pushing/popping the list), then a list is not what you want to be using because it doesn't capture the intention of the type (and therefore allows unintelligible values of the type, and inappropriate transformations on the type). -- Live well, ~wren
participants (10)
-
Anton van Straaten
-
Don Stewart
-
Fernan Bolando
-
Henning Thielemann
-
Jon Fairbairn
-
Magnus Therning
-
Marc Weber
-
Matthias Görgens
-
Thomas Schilling
-
wren ng thornton