Live data from Hacker News

Is Haskell the Cure?

mathias-biilmann.net

71–80 of 93 posts

Re: Is Haskell the Cure?

#71

Earlier quoted context omitted.

Not to be to contrarian but until I see proof to the contrary I think Norvig put said it best: In terms of programming-in-the-large, at Google and elsewhere, I think that language choice is not as important as all the other choices: if you have the right overall architecture, the right team of programmers, the right development process that allows for rapid development with continuous improvement, then many languages…

the right development process that allows for rapid development , well rapid development is the reason people write webapps in python/ruby/node and not C++. We have to stop pretending that language choice is immaterial, hadn't it for C we would still be typing in our single and double mouse clicks into an OS written in assembly.

Have you ever seen a project succeed or fail where anyone involved said "You know, if we had used a better programming language it would have all worked out"? I have seen projects succeed or fail based on those three things Norvig calls out, I have never once seen a project succeed or fail because of the language used. Is it important that we have moved beyond hand coded assembly? Unequivocally, yes it is. Are you going to fail because of your language selection? Maybe if you pick Assembly, beyond that language selection isn't even a rounding error on probability of success.

You can certainly develop rapidly in C++ if you have the right process and people. In fact that is where that quote came from, Norvig noting that devs at google where not hampered by their choice of Java and C++.

Re: Is Haskell the Cure?

#72
post #8

I love Haskell; I do a lot of work with it. That said, I use Python for the web. As nice as Snap is, Haskell just doesn't have the vast array of quality libraries for web development that Python does. Lately, this means that I do web development in Flask, and heavy lifting in Haskell.

Check out http://www.yesodweb.com/

Re: Is Haskell the Cure?

#73

I gave haskell a shot as some of my earlier github repos indicate: https://github.com/substack . I even wrote my blog in haskell with happstack, since snap hadn't gotten popular yet. Haskell is very hard, but even after 3 years of pretty intensive use, I never really felt productive with haskell in the same way that I've felt in other languages. Anything I did in haskell required a lot of thinking up-front and tinker…

I've also never been productive with Haskell. It's cute, it raises interesting problems if you enjoy wrangling with mathy problem for the sake of it, but when it comes to getting stuff done in a deeply imperative, eager world, the impedance mismatch is simply overwhelming.

Moreover, I was very proficient in OCaml before I discovered Haskell, and it just spoiled be. It has all of Haskell's qualities which matter (type inference, algebraic data structures, a naturally functional mindset) without the parts you regularly have to fight (mandatory monads and monad transformers, algorithmic complexity in a lazy context, tedious interfacing to the underlying OS).

If you felt like Haskell had many amazing qualities, spoiled by a couple of unacceptable flaws, especially when it comes to acknowledging how the real world works, I'd suggest that you give a try to OCaml. You should be proficient with it within a couple of days.

Re: Is Haskell the Cure?

#74
post #37

Please stop with the toy benchmarks and pretty one-liners that show how awesome Haskell is. There is growing list of smart programmers who get all enchanted with Haskell, jump into it wholeheartedly, and end up frustrated (see bottom of message). GHC makes the typical C++ compiler seem fast. Once code grows past the homework problem size, all hope of understanding memory usage is lost. I don't think people really get…

That post is from 2005. The situation is entirely different today w/respect to speed (both the compiler and the addition of ByteString and Text libraries), and productive libraries, particularly for web development. Likewise, it is a rare case that you would run into memory consumption issues. I do agree that there is entirely too much enthusiastic toying around in Haskell and not enough real world users and honesty…

To me, there's a dichotomy between the "if it compiles, it usually works" aspect of Haskell (and how this is often touted as superior to the dynamic typing, test-driven approach) and that you can't get a picture of memory usage until you run and profile the code. In my experience, hard to understand memory consumption issues are common and take effort to solve.

Reference: http://blog.ezyang.com/2011/06/pinpointing-space-leaks-in-bi...

Re: Is Haskell the Cure?

#75
post #31

Earlier quoted context omitted.

Yeah, but the syntax and the verbosity hides your aim. In the obscure years previous to c++11, meta-programming in c++ would have required a language lawyer. In haskell, the syntax is so nice that is easily readable, and it doesn't get in your way.

In haskell, the syntax is so nice that is easily readable, and it doesn't get in your way. Unless you want if-then-else in the do notation (yes, I know that there is a GHC extension for this), disagree with its whitespace rules, or like record syntax (which subsequently pollutes your namespace). Also, point-free style is nice, but it is easily and often abused, leading to unreadable code. Yeah, but the syntax and the…

> Also, point-free style is nice, but it is easily and often abused, leading to unreadable code.

That's why it's called point-less style. It's too seductive.

> Many people would argue the same of Haskell. So much semantics are encoded in the particular operators, monads, functors, monad transformers, arrows being used, that they are hidden from plain sight.

In a sense. But at least Haskell is parseable. And overloading is only done in a very systematic manner. So if something fishy's going on, you at least see strange symbols you haven't seen before.

Re: Is Haskell the Cure?

#76
post #25

Earlier quoted context omitted.

Not to be to contrarian but until I see proof to the contrary I think Norvig put said it best: In terms of programming-in-the-large, at Google and elsewhere, I think that language choice is not as important as all the other choices: if you have the right overall architecture, the right team of programmers, the right development process that allows for rapid development with continuous improvement, then many languages…

Architecture heavily depends on the language. You have to make different choices for C++ than for Java, not mentioning Haskell. Also, I think that comma before "the right" in Norvig statements means logical AND. If we rewrite that statement it will look like that: if you have the right overall architecture AND the right team of programmers AND the right development process that allows for rapid development with conti…

As much as I loath Java and co, I have to give them that their mature development tools make up a bit for their weakness.

I.e. in Haskell you make a change to a type and propagate it, until the compiler stops complaining. In Java you click some `refactor' button in your IDE, and your changes will propagate through the code base automatically.

That's less of a comment on the languages, since Haskell will probably grow better tools some day, but more a comment on the relative stages of maturity.

Re: Is Haskell the Cure?

#77

Earlier quoted context omitted.

Did you perhaps jump into the water too quickly? I'm currently learning a couple of functional languages (including Haskell) and using it in production environments but my current use is restricted to "I have an input that will always produce a certain output. There are no database or environmental dependencies, this is straight computation. I want to never have to worry about this function ever again". And so far, k…

Haskell is beautiful, I love it, but I can easily see his points. There are a few traps one can easily fall in: - Reach a point in a complex application where it becomes hard to reason what laziness will do to performance. - End up in type-hell. E.g. some libraries extensively use existential quantification of type variables. Before you know it, you are chasing "type variable x would escape its scope"-type or error m…

I would say that after a little more experience, space leaks are the only thing that really worries me in Haskell. It's one of those things that I have to think about a little too much to really feel "safe" about. (The other worry is expressions that evaluate to ⊥ at runtime, but it's been shown that static analysis can solve that problem. I don't actually use those tools, though, so I guess I'm a tiny bit afraid of those cases. Like with other languages, write tests.)

Your other concerns don't seem too worrisome to me. Type hell doesn't happen very much, though there are some libraries that really like their typeclass-based APIs (hello, Text.Regex.Base) which can be nearly impossible to decipher without some documentation with respect to what the author was thinking (``I wanted to be able to write let (foo, bar) = "foobar" =~ "(foo)(bar)" in ...'').

The data type stuff can be confusing for people used to other languages, where the standard library is "good enough" for most everything people want. A good example is Perl, which uses "scalar" for numbers, strings, unicode strings, byte vectors, and so on. This approach simply doesn't work for Haskell, because Haskell programmers want speed and compile-time correctness checks. That means that ByteString and Text and String are three different concepts: ByteString supports efficient immutable byte vectors, Lazy Bytestrings add fast appends, Text adds support for Unicode, and String is a lazy list of Haskell characters.

All of those types have their use cases; for a web application, data is read from the network in terms of ByteStrings (since traditional BSD-style networking stacks only know about bytes) and is then converted to Text, if the data is in fact text and not binary. Your text-processing application then works in terms of Text. At the end of the request cycle, you have some text that you want to write to the network. In order to do that, you need to convert the Unicode character stream to a stream of octets for the network, and you do that with character encoding. The type system makes this explicit, unlike in other languages where you are allowed to write internal strings to the network. (It usually works since whatever's on the other end of the network auto-detects your program's internal representation and displays it correctly. This is why I've argued for representing Unicode as inverse-UTF-8 in-memory; when you dump that to a terminal or browser, it will look like the garbage it is. But I digress.)

I understand that people don't want to think about character encoding issues (since most applications I use are never Unicode-clean), but what's nice about this is that Haskell can force you to do it right. You may not understand character sets and character encodings, but when the compiler says "Expected Data.ByteString, not Data.Text", you find that ByteString -> Text function called "encodeUTF8" and it all works! You have a correct program!

With respect to purity; purity is a guarantee that the compiler tries to make for you. When you load a random C function from a shared library, GHC can't make any assumptions about what it does. As a result, it puts it in IO and then treats those computations as "must not be optimized with respect to evaluation order", because that's the only safe thing it can do. When you are writing an FFI binding, though, you may be able to prove that a certain operation is pure. In that case, you annotate the operation as such ("unsafePerformIO"), and then the compiler and you are back on the same page. Ultimately, our computers are a big block of RAM with an instruction pointer, and the lower you go, the more the computer looks like that. In order to bridge the gap between stuff-that-haskell-knows-about and stuff-that-haskell-deson't-know-about, you have to think logically and teach the runtime as much about that thing as you know. It's hard, but the idea is that libraries should be hard to write if they'll make applications easier to write. If everyone was afraid to make purity annotations, then everything you ever did would be in IO, and all Haskell would be is a very nice C frontend.

For a lot of code you end up using monads plus 'do' notation, making your programs look practically imperative, but an oddball variation of it.

That's really just an opinion, rather than any objective fact about the language. I find that do-notation saves typing from time to time, so I use it. Sometimes it clouds what's going on, so I don't use it. That's what programming is; using the available language constructs to generate a program that's easy for both computers and humans to understand. Haskell isn't going to save you from having to do that.

Using functions with worse time or space complexity, to maintain purity.

ST can largely save you from this. A good example is Data.Vector. Sometimes you want an immutable vector somewhere in your application (for purity), but you can't easily build the vector functionally with good performance. So, you do a ST computation where the vector is mutable inside the ST monad and immutable outside. ST guarantees that all your mutable operations are done before anything that expects an immutable vector sees it, and thus that your program is pure. Purity is important on a big-scale level, but it's not as important in a "one-lexical-scope" level. Haskell let's you be mostly-pure without much effort; other languages punt on this by saying "nothing can ever be pure, so fuck you". I think it's a good compromise.

I/O looks simple, but for predictable and safe I/O you'd usually end up using a library for enumerators. Writing enumerators, enumeratees, and iteratees is unintuitive and weird, especially compared to (less powerful) iterators/generators in other languages.

IO is hard in any language. Consider a construct like Python's "with":

    with open('file') as file:
        return file
That construct is meaningless, since the file is closed before the caller ever sees the descriptor object. But Python lets you write it, and guaranteeing correctness is up to you. In Haskell, that's not acceptable, and so IO works a little differently. Ultimately, some things in Haskell are a compromise before simplicity of concepts and safety guarantees at compile time. You can write lazy-list-based IO in Haskell, but you can run out of file descriptors very quickly. Or, you can use a library like iteratees, and have guarantees about the composability of IO operations and how long file descriptors are used for. It's up to you; you can do it the easy way and not have to learn anything, or you can do some learning and get a safer program. And that's the same as any other programming language.

Re: Is Haskell the Cure?

#78

Earlier quoted context omitted.

> Artificially pure packages. There are some packages that link to C libraries, but (forcefully) provide a pure interface. (Or in other words: purity is just convention) Explain? What would the alternative be? > Using functions with worse time or space complexity, to maintain purity. This seems like the opposite of your previous complaint. > For a lot of code you end up using monads plus 'do' notation, making your pr…

Explain? What would the alternative be? Box the value that is the result of evaluation an expression that calls impure code in IO? This is what I'd expect for calling impure code in third-party libraries.

If the library developer can prove that a C operation is pure, why shouldn't he tell Haskell about that?

Re: Is Haskell the Cure?

#79
post #70
post #53

Earlier quoted context omitted.

I don't think anyone has been advocating any programming language as the "next silver bullet". Even a small productivity gain (say 5%) over a long period of time can make a very large difference, and is worth spending weeks to learn. Additionally, Haskell isn't a new little "fad" language. It is a pretty old research effort that accumulated many novel and useful ideas that are worth learning. I understand someone who…

Learning about novel/different languages is totally different from learning new languages, which I thought the original remark was about. The former can often be done in a few hours and will pay itself back fairly soon; the latter takes weeks, and after that, you will still be at risk of, months into a project, having to discover that there is no good library to do X yet, or that library Y wasn't the best choice afte…

The reason I mentioned learning about Haskell is because it allows you to realize that you should also learn to use Haskell :-)

One cannot be expected to learn the thousands of languages out there. But learning a bit about many of them is possible -- and then learning to use the most interesting ones is most probably worthy.

Re: Is Haskell the Cure?

#80

Earlier quoted context omitted.

Yes, reasoning about laziness and difficulties using types are library issues. I disagree, if the language were strict by default, this was not an issue. It is a language problem that is forced on libraries. However, for most Ruby web applications that I have worked on I have had to spend time re-writing slow parts of the application because Ruby was truly the bottleneck, My point was that Haskell is often a lot slow…

The biggest reason why there are Haskell packages wrapping C libraries is not for performance, but to reuse good C libraries, and because Haskell has an excellent interface for C libraries. Many people prefer to write Haskell for computationally intensive tasks than C/C++. Depending on the problem it is possible to get within 2x the raw speed of C and you much nicer code to maintain and much easier concurrency/parall…

In case anybody is wondering: both Erlang and Haskell have very lightweight user-space threads built in, which are mapped onto a small pool of OS threads to take advantage of however many cores you have. It's very slick and fast, and probably the Right Thing.
Post reply on HN