
In Praise of Haskell - tel
http://www.drdobbs.com/architecture-and-design/in-praise-of-haskell/240163246/#1
======
skwirl
This is yet another shallow puff piece on Haskell. Reading it, you would think
that the author has only ever used Ruby and Haskell, as he gives the
impression Haskell is the only language that supports functional/declarative
style programming.

In actuality the author is trying to sell Haskell because he sells Haskell
IDEs.

I'm not knocking Haskell, but let's not pretend that this is a useful piece of
journalism.

~~~
cia_plant
Yeah, definitely just more propaganda from "Big Haskell IDE".

~~~
skwirl
The author is the CEO of a company that sells the first (and only?) commercial
Haskell IDE. I point this out because the author (from his background) clearly
knows about the subject matter, while reading the content of the article would
lead you to believe the author was a novice to software development and
computer science.

The shallowness of the article combined with the background of the author can
be reconciled if you understand the article as an advertisement.

------
DanielBMarkham
One important thing in the article that was a bit obfuscated: modern OOP
languages introduce a staggering amount of dependency and complexity. Things
like TDD are then layered on top to try to ensure solid code is being built.

In a pure functional environment, you don't have those dependency issues. Your
problems boil down to types -- do you have the correct fields and definitions
in your inputs? -- and transforms -- are your symbolic transformations what is
desired?

In practice, pure FP is the closest I've seen to stuff that "just works".
While FP can be a huge pain in the ass mentally, it beats the heck out of the
spaghetti dependency issues in OOP. [insert long discussion here about whether
pure FP can actually scale in a large organization]

~~~
taeric
Is it irony that the post right below this is complaining about Cabal and
"dependency hell?"

~~~
nightski
No because that dependency hell is up front (Haskell ecosystem likes being
explicit). Whereas in dynamic languages you just install it all and hope it
doesn't crash (and your unit test coverage is sufficient).

~~~
taeric
Firstly, I think this is somewhat unfair to dynamic solutions. I could just as
easily reword it as "you try and pull in a library and hope it doesn't break
your compilation." Simply put, it could be the up front hell that probably
puts a lot of people off of a solution.

Not to mention adding a new piece to a highly type based solution could
involve modifying a lot of the existing types to make room for the
modification. Whereas with many dynamic solutions, this is not the case.

~~~
nightski
It is more of a contract. The library author is stating this package was
developed against these dependencies and versions. It is known to work well in
these cases.

This does not mean it will not compile. In fact often the fix is simply for
the author or developer to relax the version bounds and everything will be
fine.

Lastly, many of these issues arise not because of a direct dependency but an
indirect one. The problem is that GHC will not allow you to depend on two
packages which themselves depend on different versions of the same package.
Once this is fixed, along with sandboxing, will eliminate the vast majority of
the cabal hell problem.

~~~
taeric
I still feel you are being a touch unfair to the dynamic world. Many times,
bringing in a dependency just works.

The analogy I have in my mind is a digital computer for a bike. The general
"contract" is simply that you will somehow get a pulse to the computer for
each rotation of a tire with a known size. The details of how the bike is
constructed are ultimately irrelevant.

Further, because this is such a general contract, it doesn't actually matter
if you hook it to the wheel or not. You can, in fact, use such a computer in a
non bike device with success.

~~~
tel
There's work to provide this "module by contract" notion you're talking about
exactly ([http://www.mpi-sws.org/~skilpat/backpack/](http://www.mpi-
sws.org/~skilpat/backpack/)) but it's very new and far from implementation.
OCaml does a good job of this and is usually the poster child for parametric
modules done right.

That said, dynamic languages allow this kind of contractual module imputation
by the virtue of allowing absolutely anything to be considered a module and
hashed out at runtime. At the least this means carrying around a lot of
tagging/runtime typing information so you can call up runtime errors. At the
most, it means that your whole system is held together by an increasingly wide
set of unchecked and uncheckable assumptions.

Cabal hell is annoying but at least it's checking.

------
seliopou
I have and will continue to maintain that it's Haskell's operational
challenges that are holding it back from wide adoption, at least on the web.
In a lazy language, your cost model is all out of whack. When your program
consumes resources, you can't unambiguously identify the line of code that
caused your program to consume those resources. That's because a function
application itself does nothing. Needing the result of the application is what
causes work to be done. And that function application could be floating
through your program as a thunk for who knows how long until its result
(probably a partial result at that) is forced. So who's to blame for the work?
The function application or the code that forced its result? Who knows.

The typical solution to this problem in production Haskell systems, by the
way, is to run the application with profiling turned on.

~~~
carterschonwald
There Is some preliminary work to add a "Strict language" mode that can be
selectively enabled per module. Johan Tibbel has some experimental support
worked out, and hopefully it can be polished enough to make it Ito ghc 7.10 in
the next year.

------
clux

      What's not to like?
    

Cabal, which unsurprisingly is not mentioned. Dependency hell makes it
stupidly difficult to rely on other people's code on a large scale. I'd rather
write uglier code in JavaScript if it means having access to other people's
packages immediately and without complications.

~~~
otikik
Also, after a week I still didn't understand its type system completely.

It may be that I am simply too dumb, or that I didn't find the right
resources, but 'easy to learn' this language is not.

~~~
thinkpad20
Haskell is really not much more strongly typed than Java, or even C++
(although it's much less liberal with letting you cast than either of those
languages). Just like those languages, if a function has been declared to use
types a, b and c, then you'd better supply types a, b, and c as arguments.
This is the same. The only real extension that I can see is the ability to
create functions which accept or return arbitrary types, like `foo :: a ->
[a]`, which isn't an option in Java or C++ without some hackery. Of course
there are type classes and algebraic data types and other things as well, but
I don't think they really make the language "more strongly typed," just more
expressive in their types.

What makes Haskell a little challenging in the beginning is its currying,
which means you don't need to call a function with all of its stated
arguments, and the fact that function application associates to the left; i.e.
that `f x y` is the same as `(f x) y`, NOT `f (x y)`, which is closer to how
it would be in, say, Ruby or CoffeeScript. There are very good reasons for
this, but it does take some getting used to. Currying and associativity rules
are responsible for a lot of seemingly incomprehensible type errors. You get
better at avoiding them as time goes on. I feel that the weirdness of reading
Haskell DSLs, like Parsec, which often make heavy use of customized operators,
or do-notation, is an extension of these issues, since most of the difficulty
comes from trying to figure out how the types propagate through what amounts
to be long, complicated chains of function applications.

------
iamdev
The example provided is too contrived. By that logic, here's a way to "match"
haskell with php:

$a = range(2,100,2); $b = array_slice($a, 5);

~~~
freyrs3
Haskell's version is type safe. PHP, not so much.

~~~
iamdev
Thanks for pointing that out. The author didn't emphasize that point, and it
makes sense now.

Is it me, or was it a bad example for where Haskell "really shines"? I don't
like the "use Haskell cause it has these really cool functions" approach.
Feels so superficial.

~~~
nahiluhmot
It wasn't so much a bad example so much as it was a trivial one. Perhaps a
more powerful one (that displays the advantages of lazy evaluation and higher-
order functions) would be the function to generate an infinite list of
Fibonacci numbers.

    
    
        fibs :: [Integer]
        fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
    

Even still, it's difficult to get the feel of actually using the language from
one function taken from a freshman year CS class.

~~~
cgh
How about demonstrating the power of laziness by generating the power set of a
set? (Taken from Learn You a Haskell).

    
    
      powerset :: [a] -> [[a]]  
      powerset xs = filterM (\x -> [True, False]) xs  
    
      ghci> powerset [1,2,3]  
      [[1,2,3],[1,2],[1,3],[1],[2,3],[2],[3],[]]
    

Edit: I read LYaH some time ago but this example stuck with me because it's
both wonderful and mind-blowing.

~~~
platz
Here's a recursive definition which is less cool but less 'magic'

    
    
        powerset        :: [a] -> [[a]]
        powerset     [] =  [[]]
        powerset (x:xs) =  yss ++ map (x:) yss
                           where yss = powerset xs
    
        > powerset [1,2,3]
     
        [[],[3],[2],[2,3],[1],[1,3],[1,2],[1,2,3]]

------
thinkpad20
Unless someone had literally never seen anything on Haskell before, this kind
of article adds absolutely nothing new to the discussion. It's all been said
before, and more often than not it's been said by FP Complete. It reads like
an infomercial, and it's frankly embarrassing reading it.

