Why Lazy Functional Programming Languages Rule
Da Massive writes "Techworld has an in-depth chat with Simon Peyton-Jones about the development of Haskell and his philosophy of do one thing, and do it well. Peyton-Jones describes his interest in lazy functional programming languages, and chats about their increasing relevance in a world with rapidly increasing multi-core CPUs and clusters. 'I think Haskell is increasingly well placed for this multi-core stuff, as I think people are increasingly going to look to languages like Haskell and say 'oh, that's where we can get some good ideas at least', whether or not it's the actual language or concrete syntax that they adopt.'"
But I was too lazy to click on 13 pageviews.
Hascal, and other functional languages may be good for multi-core development. However not to many programmers program in them... Plus I find they do not scale well for larger application. Its good for true computing problem solving. But today most developopment is for larger application which doesn't necessarly solve problems per-say but create a tool that people can use.
If something is so important that you feel the need to post it on the internet... It probably isn't that important.
A separate, but related problem is that the community doesn't seem interested in practical use of it - there aren't lots of bindings to libraries to make easy things easy. Heck, even doing i/o at all isn't really supported very well. Functional programming is very good for the pure computer science part of programming, but unfortunately that's going to make up less than half of any given program. You also need to be able to interface.
So I think the quote in the summary is right: people won't be adopting Haskell or similar pure-functional languages any time soon. What will happen is the next generation of dynamic languages will adopt the best features from functional programming; we've seen that happen already in python and ruby, and it'll happen again. And people will start using them there.
I am trolling
The picture in the linked article is missing a beard.
If you can read this, I forgot to post anonymously.
I haven't really been able to figure out how to do anything significant in Haskell. But I suspect that one day a language more like haskell and less like C will end up being the most popular. Monads and all that kind of confuses me.
I think it helps if you have a strong math background and are comfortable with Lambda calculus. I'm just an old C hacker and haven't used any real math in like 10 years, so I'm not that effective in Haskell :(
“Common sense is not so common.” — Voltaire
They're "lazy" because they don't do any work until necessary. For example, a function can return an infinitely long list, but only the elements you request will actually be calculated. Or, to compare them to Python, it's like having everything function like an iterator.
Ita erat quando hic adveni.
We can see this philosophy in C where, except where huge data structures are involved, it is best to make a copy of data rather than work to work on someone else's copy. Likewise functions do one thing, do it well, and, again except for huge data structures, return a copy. Memory is manually allocated, and deallocated, possibly from the functions local heap.
It is interesting to me how it all comes back to just best practices. Make sure you know how much memory you need. Make sure you are only doing what needs to be done right now. Make sure the interfaces are clear. If data is ready, then it should be ok to work on it. To me functional programming is what happens after data models, or objects, are defined. Once the data structure is defined, you can treat it as stateless immutable input. Output is a another structure. Again, the only limitation is if the object is so large that duplicating become a cost performance issue.
"She's a scientist and a lesbian. She's not going to let it slide." Orphan Black
What's the difference between a functional language like Lisp and a lazy functional language?
Just asking.
Could this be the year of Haskell in the developer's tool box?
Copyright infringement is "piracy" in the same way DRM is "consumer rape"
One thing in Haskell that always intrigued me was the idea of combinatorial parsers - a parser that accepts a string and yields not a single parse tree, but all possible parse trees based on the language rules... Simple implementations of those can be implemented in Haskell pretty straightforwardly. Combinatorial parsers for individual rules are stuck together - and while rules may generate a bunch of possible parse trees these are culled by successive rules...
I don't know too much about the practical efficiency of these - but in terms of how they're expressed I think they're great...
Bow-ties are cool.
...is the one with the newspaper over its face, snoring in the corner, cans of soda piled up on the desk. The functional language is the one that has finished psychotherapy, is fully alert and active, and has a far higher risk of suffering a heart attack from overwork.
It's a small world and it smells funny; I'd buy another if it wasn't for the money; Take back what I paid (SoM)
I haven't really been able to figure out how to do anything significant in Haskell. But I suspect that one day a language more like haskell and less like C will end up being the most popular. Monads and all that kind of confuses me.I think it helps if you have a strong math background and are comfortable with Lambda calculus.
Monads, lambda, calculs...arrr, matey, now I know why Haskell's such a bloody mess - Neal Stephenson wrote it! That be why it seems good at first and falls apart at the end.
Well Haskell isn't "smart" in the sense that it goes out and arbitrarily caches things it thinks may be helpful (that way leads to madness).
It does cache computations it's made if you store them in a variable or part of a data structure, so if you plan things right, you can get the behaviour you want.
Basically, here's one advanced way of calculating fibs in Haskell:
(From Haskell for C Programmers).
This takes a bit of thinking to work out, but basically it declares fibs as a list of ints, which is infinitely long, the first two elements are 0 and 1, and each subsequent element is the sum of the previous two.
But there's a catch - unlike C where declaring an infinite data structure would be absurd, Haskell stores it this way:
[0, 1, <some vague concept of the remaining computation>] - a finite data structure of in fact just three elements.
Now you request the 100th fibonacci number, like this: (fibs !! 99). Haskell doesn't know the value of elements 2 through 99, so it unrolls it, performing the computation as much as possible - that's the laziness. Now it stores:
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ... , 218922995834555169026, <some vague concept of the remaining computation>]
And it returns you the value 218922995834555169026 which is the last *known* element of the list. Note however that the computed list so far remains.
Now you request the 200th fibonacci number, like this: (fibs !! 199). And Haskell figures it has to do some more computation, but it already knows the first 100. So it just unrolls the next 100 elements, and gives you the 200th fib. You could subsequently request (fibs !! 37) and it would look it up without recomputing.
Note that this is a bit of a bad example, as Haskell uses linked lists, the lookup itself is linear, which is the same as the computation time. But other more expensive computations could be done using this technique.
Also note that my definition is a lot smaller and closer to the mathematical definition of Fibonacci sequence than your C code. Functional programming is (or at least tries to be) about defining what you want to compute, not how you want to compute it. Having said that, it does often mess with my head and I tend to use imperative languages for this reason ;)
How is that better than doing (or basically the same in Java/C/perl/ruby/etc.):
I hate to say "you're missing the point" because I feel that's unreasonably dismissive - though I kind of feel you are...
IMO the point isn't necessarily that one method is "better" than another - it's that this idea represents an important and useful way of approaching programming problems. If you understand the style you can appropriate it - it becomes a useful concept for expressing problems and their solutions.
So for instance - while you may not use recursion in C for general problem solving (due to the lack of tail-recursion optimizations which turn the thing into a loop) - understanding the recursive expression of a problem is useful for structuring your solutions, understanding what assertions must be made with respect to the state of the data at what points in the code, etc. - even if you structure your solution as a loop rather than a recursion.
And it should be noted that you can implement infinite sequences in C++, etc. - generally the way to do this is with iterators, and the use case would be for feeding those iterators to algorithms that expect iterators... What Haskell brings to the table is that it encourages you to think of problems and solutions in those terms - learn the method and what you can do with it, how it affects the expression of your code - if you find it a useful idea it's easy enough to implement in most object-oriented languages...
Bow-ties are cool.
The same way they should measure the productivity of any team of programmers: are they able to solve the problem they're given within time and budget constraints. "Lines of code" is not a good measure of productivity in any language.
Thoughts on Haskell, from a Haskell programmer.
Haskell has a very nice software transactional memory library, which makes a lot of otherwise-difficult concurrency problems much easier. It's statically safe, too, unlike similar libraries for imperative/OO languages.
Certain other language features are very nice. Monads are also extremely powerful once you wrap your head around them, and the type-class system and standard libraries make a lot of math programming problems much easier.
The language also has downsides. The laziness makes it possible to build up an arbitrarily long chain of suspended computations, which amounts to a hidden memory leak. Laziness also complicates the semantics for "unchecked" exceptions, most notably division by zero. The combination of laziness and purity can make the language very difficult to debug and optimize. While the compiler has very powerful optimization capabilities, sometimes code needs to be just so to use them (like flagging things "const" or "restrict" in C), and this can make it hard to write clean code that runs fast.
The other problem is that most programs need some amount of imperative code somewhere to do the I/O. This code has a tendency to be verbose, nasty and slow in Haskell.
There are also some problems that would be relatively easy to solve in a very nice way within the semantics of the language (give or take), but are not solved well in the standard libraries. These include exception handling, global mutable state, strings and regular expressions, certain I/O operations, arrays and references. It would be very nice if the ST and IO monads were unified, and if references and arrays had nice syntax; this would reduce the ugliness needed to write those occasional bits of imperative code.
I hereby place the above post in the public domain.
Hackage is well known to haskell programmers. It is linked to directly from the front page of haskell.org, it is mentioned frequently on the haskell-cafe mailing list, and that's where hundreds of haskell projects are hosted. If you're an average passer-by and not an active haskell developer, it's not necessarily going to jump out and say "boo!", but it isn't hiding under a rock, either.
Note: hackage is not the standard libraries. Those are documented elsewhere.