Hacker News new | ask | show | jobs
by jjaredsimpson 4607 days ago
> but I think that the problem with the way it manages side effects is that it does so through lazy evaluation.

This is not so.

> and lazy evaluation is hard to wrap your head around.

technically haskell is non-strict, not lazy. (a + (b * c)) evaluates + then * instead of * then +. Also strictness annotations can change this behavior.

> They require programmers to think and program solely within Haskell's lambda calculus and lazy evaluation framework, which is neither the way people think nor the way computers do

This is not supportable. You might be more familiar with strict evaluation, but don't pretend its a feature of humanity. All runtimes come with assumptions.

2 comments

This is another problem with Haskell: comments like this. But in order to be helpful, let me explain why.

> technically Haskell is non-strict, not lazy.

Now, see, I don't care. Neither does anyone really other than PL researchers. I mean, I can care in my spare time if I like spending it on PL research, but when I write a 2 MLOC software for a large customer, I couldn't care less whether "technically" it's "non-strict" or "lazy". As far as I, the programmer, is concerned, it's lazy. If one must be this familiar with PL jargon in order to program Haskell, then this is a problem.

> but don't pretend its a feature of humanity. All runtimes come with assumptions.

Again, I'm not trying to make a provable statement (how does that joke go? you can tell if someone is a mathematician if everything they tell you is all true and all irrelevant). We're talking software engineering, right? So what percentage of production code anywhere in the world is written in an eager (strict, whatever) language? If you tell me it's less than 99.999%, then you're being dishonest. 99.999% is a "feature of humanity". If your point is that education can change people's habit and way of thinking, I say, you're absolutely right. Go for it, and we'll talk again in 15 years.

> All runtimes come with assumptions.

Again, true but irrelevant. Some assumptions are more familiar and therefore feel more "natural",and some are less so.

I wasn't dissing Haskell. It's a very impressive and elegant language. I was only pointing out that while it has some advantages from a software engineering perspective, it also has some disadvantage.

Laziness is an implementation detail that permits equational reasoning and a declarative programming model; the only reasons it's even useful to be aware of haskell's evaluation strategy are 1) to know that it isn't strict (if you're already a programmer), and 2) to solve and anticipate space leaks in production code (if you're using it for Real Work).

Anyway, you seem pretty [sure](http://www.idlewords.com/2005/04/dabblers_and_blowhards.htm) of your opinion so it's probably not worth further discussion.

I don't think I've expressed an opinion because I don't think I have one (I have strong opinions on Scala, but they don't apply to Haskell). I'm just pointing out what seem to be major obstacles to Haskell adoption in the industry. I'm not saying it's not worth the effort because I really don't know. I'm just saying it's not obviously worth the effort. Clearly, the data isn't there yet because there is very little use of Haskell in the industry. This may be unfortunate – or not – but we just don't have enough information to tell yet.

Haskell's roots in academia often steer the discussion towards theoretical PL, which seriously hurts Haskell adoption. I actually like tikhonj's comment because it focused on practicality rather than jargon, so in response I merely pointed out that Haskell is not 100% pure gain in practical terms. That does not mean we shouldn't all adopt it, it just means that the jury is still out.

The laziness-vs-non-strictness part pretty much nailed one problem beginners may have with the Haskell community.

On the other hand, I don't think your 99.something are a feature of humanity, they are the result of the last decades of mainstream programming development. It took me less than a year of on-and-off Haskell hobby fiddling to find functional and non-strict less awkward to think in than imperative and strict.

I think his point is that from an adoption perspective, whether or not it's actually a genetic feature of humanity or merely might as well be is basically irrelevant. Either way, it's a giant hurdle from a practical perspective, especially a commercial one.
> So what percentage of production code anywhere in the world is written in an eager (strict, whatever) language?

How is this relevant?

> If you tell me it's less than 99.999%, then you're being dishonest. 99.999% is a "feature of humanity".

Make all && and || strict in all C, C++, Java, C# code, and chaos will reign.

&& and || are evaluated by first looking at the left operand, then at the right. That seems pretty strict to me. You're thinking of their short-circuit nature, that the right operand is not always evaluated; I believe that that is a different issue than strict vs. lazy.
Consider '||' as a normal function. Consider ||(f(x),g(x)). If this were strictly evaluated, we would compute f(x) and g(x), then pass them as arguments to ||. Instead, we compute f(x) pass it to ||, and compute g(x) only if it is needed. This is lazy evaluation.
Well, the Boolean operators in C-like languages are NOT normal functions, which is the point. Furthermore, what is strict about them is the order in which their operands are evaluated, which is a different aspect than the one you mention: whether all arguments are evaluated before considering the function. Consider e.g., notUnderAttack() || enableDoomsdayDevice(). A lazy language is free to decide that it's more optimal to evaluate the second operand first.
I don't think a lazy language can necessarily make that decision. Consider the simple implementation of ||:

  ||(f,g){
    if (eval(f)) then return true
    if (eval(g)) then return true
    return false
  }
A lazy language will not evaluate a function until it knows it needs it. In this implementation, there is no way of knowing that g will be needed until after computing f, so f will be computed first. Having said that, it is possible for an optimizing compiler to realize that the order doesn't matter and make a decision on which one to check first, however that is an optimization that the compiler would need to prove does not change the results.

This seems like a good example of why purity seems to be really beneficial to lazy evaluation.

> Well, the Boolean operators in C-like languages are NOT normal functions, which is the point.

"Not normal", because the language is strict, and there is no way to make a lazy function on your own, even when it is so tremediously useful.

In other words, the C standard comittee decides which functions may be lazy. As a Haskell programmer, you decide.

> technically haskell is non-strict, not lazy.

What do you mean by that?

> (a + (b * c)) evaluates + then * instead of * then +.

AIUI,

    head 2 [1, 2, (digit_of_pi 1000000000) ]
is forbidden from calculating the billionth digit of pi. That's a pretty strict (play on words intended) kind of laziness, even if not the theoretically maximal definition.