4 ms·
I don’t think that’s right. In a lazy language that function will also take the sum of f + g times. If anything, in a lazy language it may take less time, but
by jose_zap 6y ago
I don’t think that’s right. In a lazy language that function will also take the sum of f + g times.
If anything, in a lazy language it may take less time, but never more than the sum of both.
How is it that you cannot reason about the performance of each separate function?
- lmm 6y agoImagine f returns an infinite lazy list (common in Haskell). How do you reason about its performance? Fully evaluating it would take infinite time.
- jose_zap 6y agoHmm, wouldn't this be the same as an infinite loop in any programming language? How do you solve an infinite loop in python for instance? How would you solve an iterator in java producing infinite values? If anything, the performance of a lazy language would be better than a strict one in the presence of an infinite sequence, as it gives you the opportunity to stop sooner and not enter in an infinite loop. Example in haskell: main = do let a = [1..] -- infinite list print (a !! 0) -- only prints the first element and exits Example in python: def f(): a = [] b = 0 for True: a.append(b++) return a def g(): print f()[0] # Takes infinite time
- lmm 6y ago> Hmm, wouldn't this be the same as an infinite loop in any programming language? How do you solve an infinite loop in python for instance? In practice an infinite loop in Python is often an immediate error (stack overflow) at the point where it's declared. In cases like you showed it's a little fiddlier, but any execution of that code will immediately show that there's an infinite loop (e.g. any unit test of it will time out) and a stack dump taken while the program is "stuck" will show exactly where the infinite loop is (which is therefore where the error is, because an infinite loop is always an error in these languages). Which is still not an ideal situation, mind; I'm very much in favour of an Idris-style language where function termination is actually checked by the type system and there's a type-level distinction between data and codata. > How would you solve an iterator in java producing infinite values? I'd avoid ever passing around a bare iterator, ideally with a lint rule. The point isn't that it's impossible to have lazy values in other languages. It's that it's practical and idiomatic to avoid them, or at least limit them to cases where you absolutely need them.
- jose_zap 6y agoJust 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.