Live data from Hacker News

I tried Haskell for 5 years

metarabbit.wordpress.com

151–160 of 273 posts

Re: I tried Haskell for 5 years

#151
post #41

Haskell: where difficult problems are trivial, and where trivial problems are the subject of ongoing academic research

The Sieve of Eratosthenes is a good example of relatively trivial in imperative code but a research paper in Haskell.

Re: I tried Haskell for 5 years

#152

Earlier quoted context omitted.

All performance issues caused by laziness are memory issues. Something isn't evaluated promptly, so large amounts of memory are consumed storing unevaluated expressions. This causes drag on the garbage collector and excess cache thrashing when it finally is evaluated. But all of that is just because data stays in memory longer than expected. If you ignore that, laziness has a small performance impact, but it's less t…

Both you and cies said that "All performance issues caused by laziness are memory issues." My intuitive sense was more like: You've got a lazy calculation that has several stages. At some point in the pipeline, you're doing something slow, but it's not obvious. When you get to the end and start using the data, the whole calculation is slow. But it's not clear where it's slow, because of the laziness. That may not be…

Laziness can actually make things faster in some scenarios. Take Python2's range() function for instance, which eagerly builds the entire list and returns it. range() is commonly used for for loops, so Python builds this list (an N operation) and returns it, and then the for loop iterates over it (another N operation). But if you use xrange(), you get a generator instead, which can lazily construct values when asked for one. It turns the for loop case into a single N operation. Similarly if you have nested function call chains, if everything is returning an eagerly evaluated list, you have to construct the whole list in memory at each call and pass it to the next stage which will eagerly iterate over the whole thing to generate its list in memory and so forth, eventually the old list can be freed / GC'd when the new list has been made.. but with lazy sequences, you only need memory for the whole list at the very end, if you want it and not just individual values. Python3's range() replaced Python2's with xrange(). (The other option is a numpy-like approach where you eagerly allocate the list and then every stage just mutates that single thing.)

The 'memory stays around indefinitely' problem is caused by not cleaning up references to generators. You can make your own xrange() clone in Python easily, and start consuming values, but if you stop before consuming all of them (assuming it's not an infinite generator), that xrange() generator object still lives and has to keep around whatever references it needs to generate the next value if you ask it for one. When your whole language is based around laziness, you might have a lot of these and it may not be clear what references are still around that keep the GC from cleaning them up.

I wouldn't say reasoning about performance is necessarily more difficult, and profiling will light up a slow part of a lazy pipeline just as well as an eager one. My own struggles with laziness in Clojure were all around my own confusions about "I thought this sequence was going to be evaluated, but it wasn't!" which may have led to unnecessary calls to (doall), which forcibly walks a sequence and puts the whole thing in memory.

Re: I tried Haskell for 5 years

#153
post #142

Earlier quoted context omitted.

but it's not that different than what you'd get with other programming languages. Until you have to solve a (maddeningly common) space leak issue. That's a problem unique to lazily evaluated languages (basically Haskell) and is godawful to debug. It reminds me of solving git problems... you suddenly find yourself having to tear back the abstraction layer that is the language and compiler and start thinking about thun…

here is a method that can help debug space leaks: http://neilmitchell.blogspot.com/2015/09/detecting-space-lea...

I wish the problem was simply detecting and isolating space leaks.

My experience is that actually fixing them can be incredibly difficult, hence my comment about needing to understand the gory details about how the runtime evaluates lazy expressions.

Heck, that post even uses the phrase "Attempt to fix the space leak" as it's often not an obvious slam dunk. Sometimes it even devolves to peppering !'s around until the problem goes away.

Re: I tried Haskell for 5 years

#154
post #127
post #107

Earlier quoted context omitted.

Maybe something like: class Foldable myFoldable where foldl :: (summary -> element -> summary) -> summary -> myFoldable element -> summary This is the translation I do in my head when I read that type signature, at least.

Really? I find the single-letter version far easier to read.

The single letter version is far easier since I already know what foldable does. Not so much when I'm learning a new library.

Re: I tried Haskell for 5 years

#155
post #41

Haskell: where difficult problems are trivial, and where trivial problems are the subject of ongoing academic research

> and where trivial problems are the subject of ongoing academic research Like what?

Working with graphs is super painful. Building a graph where you can say `parent ( firstChild node ) == node` is really difficult. There are ways to define it all in one go, or ways to build as you go, but I'm not aware of any ways to do it without serious tradeoffs.

See e.g. https://wiki.haskell.org/Tying_the_Knot

Re: I tried Haskell for 5 years

#156

I will never, ever use Haskell in production because of its default evaluation strategy, the wrongness of which was tacitly conceded not long ago with the addition of the strictness pragma (which only works per-module) to GHC. I think it's especially telling that its community skews so heavily towards this blogger/monad tutorial writer dilettante demographic rather than the D. Richard Hipp/Walter Bright 'actually get…

Would you also feel that a strict-by-default language which adds support for lazyness is a tacit admission that strict-by-default is wrong?

How would you feel if Common Lisps suddenly started sporting infix operator notation?

Haskel's alien, counter-intuitive evaluation strategy was actually marketed (circa 2010) as a powerful performance-enhancer that facilitated optimizations that were difficult if not impossible to do in a strict language like C. Instead, it ironically tends to cause more performance problems than it solves, with hard-to-debug spaceleaks capable of taking down production systems.

The entire Miranda branch of the PL tree is likely going to prove to be an evolutionary dead end, and Haskell will eventually lose out to Idris or some other strict language. And I don't think it's a coincidence that the strictness pragma (which does not even give you a strict program) was added soon after Idris and the rest started getting traction.

Re: I tried Haskell for 5 years

#157
post #50

> 1. There is a learning curve. Time and experience can cover up anything. So this does not say much about Haskell other than it is all negative without time and experience. > 2. Haskell has some very nice libraries So does NodeJS and (on an abstract level) Microsoft Word. Libraries are infrastructures and investments that (like time and experience) can cover up any shortcomings. > 3. Haskell libraries are sometimes…

> The line that if it compiles, it’s probably correct is often true. That is the meat of why Haskell is so great. I've never so reckless refactored code as much as I do in Haskell, I just wait for the compiler to tell me what I missed and go back and fix it up. I'd never do that in C, C++, Java, etc; it'd be suicide. And while that's still not a great fleshed out explanation, it's a great oversimplification of the sy…

"That is the meat of why Haskell is so great. I've never so reckless refactored code as much as I do in Haskell, I just wait for the compiler to tell me what I missed and go back and fix it up. I'd never do that in C, C++, Java, etc; it'd be suicide."

That's interesting. I am pretty aggressive with C++ refactoring because the compiler will tell me what's wrong. Especially compared to JavaScript for example. In what way does the Haskell compiler provide better error checking?

Re: I tried Haskell for 5 years

#158

Earlier quoted context omitted.

haskell is objectively expressive. (where expressive means amount of logic per character) there are multiple reasons for this, kind've tied together. Whitespace is function application (no parenthesis to keep track of like lisp, or even e.g. c, java, or javascript, when programming in a functional style). Immutability forces you to compartmentalize and compose everything. when everything is a function, function and v…

By objective, you mean succinctness (which can be simply measured by program character counts)? In this regard, APL must be the most objectively expressive language. What if we run deflation over APL? It happens that I measure expressiveness by the amount of the time the author takes to express an idea and/or the amount of the time the reviewer takes to comprehend an idea. That, unfortunately, is very subjective. APL…

Well I can't argue with the contention that there's a level of subjectivity here. However your definition of expressiveness is most likely positively correlated with the one I provided; furthermore, while you may be able to more quickly "express an idea" in a dynamically typed language, your ability to precisely enumerate the idea will be less than a statically typed one.

I've been writing haskell for only several months, yet I would say I'm already more expressive with it than other languages I have more experience with, like javascript or python, outside of domain specific languages like sql.

Re: I tried Haskell for 5 years

#159

Earlier quoted context omitted.

Would you also feel that a strict-by-default language which adds support for lazyness is a tacit admission that strict-by-default is wrong?

How would you feel if Common Lisps suddenly started sporting infix operator notation? Haskel's alien, counter-intuitive evaluation strategy was actually marketed (circa 2010) as a powerful performance-enhancer that facilitated optimizations that were difficult if not impossible to do in a strict language like C. Instead, it ironically tends to cause more performance problems than it solves, with hard-to-debug spacele…

> How would you feel if Common Lisps suddenly started sporting infix operator notation?

You mean like this? (I linked it the other day.) https://github.com/rigetticomputing/cmu-infix But one might argue that the prefix notation + macros being able to support such a library is just further testament to their use as default...

Re: I tried Haskell for 5 years

#160

Earlier quoted context omitted.

> (#1) Time and experience can cover up anything. This is simply not true. Time and experience can never cover up for lack of expressiveness, and expressiveness is one of the biggest selling points of Haskell. In fact, experience can only cover for complexity, and lack of discoverability or intuitiveness. Haskell has all those three flaws, so you see, experience is really needed. > (#2) So does NodeJS and (on an abst…

> Time and experience can never cover up for lack of expressiveness Expressiveness is subjective. Experience can alter one's perception. In fact, time and experience alter the basis of comparisons, from objective comparisons to subjective comparisons. > No, they don't. Javascript and macro Basic do not even have enough expressiveness for supporting the kind of library you'll find in Haskell. You mean you can express…

Expressiveness is a objective term, although it's multidimensional. It's the number of different concepts you can express in a language without writing an interpreter¹. Anyway, the dimensionality isn't much of a problem on that comparison since Haskell has the upper hand in an overwhelming number of dimensions.

Keep in mind that Javascript required a multi-year process in what a committee reached an agreement and all interpreters had to be changed so that JS programmers could use continuation monads. And they are still restricted to continuation, and a way too verbose syntax.

> Another meaningless subjective word (sheer).

That "The easy is hard, the hard is easy" assessment is inherently subjective, but "subjective" is not the same as "meaningless", even less when nearly everybody that experienced it has the same assessment. (Are you also going to complain about my "overwhelming" above?)

1 - I'd give you a point on subjectivity if you were talking about the difference between a library and an interpreter. But those languages (that is, JS and Basic) are just not expressive enough for this to become a problem.

Post reply on HN