
I've already posted this mail on haskell-cafe, but apparently the subject suggested a too simple question, so I try it here again. I am picking up a discussion with the same topic from haskell-users on 8th November. Thunks with reference on themselves was mentioned as main reason for <<loop>>.
A safe recursive definition would be let x = Foo (x+1) However, if you leave out the constructor, let x = x + 1 you get a <<loop>> (or a deadlock).
Are there any other reasons? I am trying to debug monadic code which stores state information in a record maintaining several Data.Maps, but in vain so far. A state is modified/changed in several steps by a compound function i.e. changeA $ changeB $ changeC state Could this also lead to a deadlock? If so, can I prevent this using CPS? If the state transformation is the main purpose/computation of the monad at all, is it better to use CPS? Is code using mtl, records or Data.Map more prone to <<loop>> or does this not matter at all. How can I identify self-referencing thunks more easily? Is there any rule of thumb to prevent <<loop>>? Are there any less obvious newbie mistakes causing <<loop> then the one above? Sorry, a lot of questions at once, but I am kind of helpless because I can't find any reason of my <<loop>>, so any comments, experience, and tips are highly appreciated. Thanks, Martin

Martin Hofmann wrote:
I've already posted this mail on haskell-cafe, but apparently the subject suggested a too simple question, so I try it here again. I am picking up a discussion with the same topic from haskell-users on 8th November.
Note that you have been sending to haskell-cafe again. Your recipient name says haskell-beginners, but the address is haskell-cafe. Anyway, <<loop>> really means a loop in evalutation order, not some statebased deadlock (see below).
Thunks with reference on themselves was mentioned as main reason for <<loop>>.
A safe recursive definition would be let x = Foo (x+1) However, if you leave out the constructor, let x = x + 1 you get a <<loop>> (or a deadlock).
Are there any other reasons?
I am trying to debug monadic code which stores state information in a record maintaining several Data.Maps, but in vain so far. A state is modified/changed in several steps by a compound function i.e.
changeA $ changeB $ changeC state
Could this also lead to a deadlock?
I don't think so. At least not in a way that leads to <<loop>>. If you get <<loop>> then you really have some infinite recursion in your program. Maybe you can track it down with Debug.Trace.trace. If so, can I prevent this using CPS? -- Dr. Janis Voigtlaender http://wwwtcs.inf.tu-dresden.de/~voigt/ mailto:voigt@tcs.inf.tu-dresden.de

Janis Voigtlaender wrote:
Martin Hofmann wrote:
I've already posted this mail on haskell-cafe, but apparently the subject suggested a too simple question, so I try it here again. I am picking up a discussion with the same topic from haskell-users on 8th November.
Note that you have been sending to haskell-cafe again. Your recipient name says haskell-beginners, but the address is haskell-cafe.
Anyway, <<loop>> really means a loop in evalutation order, not some statebased deadlock (see below).
Thunks with reference on themselves was mentioned as main reason for <<loop>>.
A safe recursive definition would be let x = Foo (x+1) However, if you leave out the constructor, let x = x + 1 you get a <<loop>> (or a deadlock).
Are there any other reasons? I am trying to debug monadic code which stores state information in a record maintaining several Data.Maps, but in vain so far. A state is modified/changed in several steps by a compound function i.e.
changeA $ changeB $ changeC state
Could this also lead to a deadlock?
I don't think so. At least not in a way that leads to <<loop>>. If you get <<loop>> then you really have some infinite recursion in your program. Maybe you can track it down with Debug.Trace.trace. If so, can I prevent this using CPS?
Oh, that last question was from the original mail, not from my answer. In any case, I don't think that CPS will help in finding the looping error in your program. -- Dr. Janis Voigtlaender http://wwwtcs.inf.tu-dresden.de/~voigt/ mailto:voigt@tcs.inf.tu-dresden.de

Martin Hofmann wrote:
Thunks with reference on themselves was mentioned as main reason for <<loop>>.
A safe recursive definition would be let x = Foo (x+1) However, if you leave out the constructor, let x = x + 1 you get a <<loop>> (or a deadlock).
Are there any other reasons?
A program that exits with <<loop>> is basically a program that runs forever. Examples of programs that run forever are let x = x + 1 in x let f x = f x in f 1 In special cases, the run-time system is able to detect that the program would run forever, and exits with <<loop>> if that happens.
Sorry, a lot of questions at once, but I am kind of helpless because I can't find any reason of my <<loop>>, so any comments, experience, and tips are highly appreciated.
Sometimes, a simple cause is accidentally using the same variable name, i.e. writing let (c,s) = foobar s in ... while you meant let (c,s') = foobar s in ... At other times, non-termination is caused by not using enough irrefutable patterns. But this usually only happens when writing algorithms that heavily exploit recursion and laziness, which probably doesn't apply to your case. You may want to try the new GHCi debugger, maybe it helps finding the loop. Regards, H. Apfelmus
participants (3)
-
Apfelmus, Heinrich
-
Janis Voigtlaender
-
Martin Hofmann