4 ms·
Just an anecdote, but once introduced an infinite loop in a golang program by forgetting to decrement a value inside some retry logic. The effects were only vi
by jose_zap 6y ago
Just an anecdote, but once introduced an infinite loop in a golang program by forgetting to decrement a value inside some retry logic.
The effects were only visible in production, as it was the only environment where the error condition happened. It caused thousands and thousands of messages to be queued in vain.
It took me, and another person 3 days to review the code line by line to understand where the problem was.
As you said, any execution of the code would show that there is a problem. Just that un this case no one new where it was executing from.
I think you should drop the argument that performance with a lazy language is difficult to reason in terms of time. It is well studied that asymptotically, strict and non-strict languages are the same.
It is a different story, and a valid argument for Memory consumption, though. It seems to me that you read the “impossible to reason about” meme and formed your own opinion of why that would be so. But this is not the actual reason.
- lmm 6y agoIf you have an error-handling path that you don't test, that has the potential to cause a major production bug in virtually any language, Haskell included. Is there any reason to believe you wouldn't have had exactly the same problem in Haskell? Laziness can mean a pure compute loop isn't a problem, sure, but if you had a loop that was queuing messages that sounds like something that would be in an IO that got sequenced. If you write the same code in a strict language or a lazy language, the asymptotic performance will be the same, sure. But that ignores the fact that people don't. Lazy languages use different idioms (there would be little point in laziness as a language feature if people didn't write code that relied on it), which is what results in code whose performance is impossible to reason about.
- jose_zap 6y agoNo, that was my point exactly. It is the same in both a strict and non-strict language. Not because the language is strict, it makes infinite loops or infinite data structures more obvious to debug or understand. In Haskell it would have been the same exact infinite loop.
- lmm 6y agoAh, I misunderstood the argument you were making. There's a lot I don't like about Go, and plenty of things to be cautious about in message-queue-based systems; laziness is by no means the only thing I worry about. "decrementing a counter" suggests the kind of imperative control flow I would be very cautious about; I favour iterating/recursing over data structures, which is inherently safe against infinite loops (but only in strict languages with immutable datastructures!). I can't remember the last time I decremented a counter that was being used for a loop termination condition in the code itself; I've occasionally written functions like "run this block n times", but the most trivial test of such functions tells you whether they're infinite loops or not. Of course this is only really practical in a language powerful enough to write recursion-schemes style constructions.