
The Evolution of a Haskell Programmer (2001) - teriiehina
http://www.willamette.edu/~fruehr/haskell/evolution.html
======
Gratsby
Phase 1: There are no bugs because strong typing, no side effects, functional
nature.

Phase 2: OK, but those bugs are my own programmer errors.

Phase 3: I admit it, I have no idea what I'm doing.

Phase 4: OK, I can't even figure out what the Haskell I did two years ago was
even trying to do. I was smarter then.

~~~
hellofunk
As Rich Hickey says often, there are two truths that are true about all bugs:

1) They passed unit tests. 2) They passed a type checker.

~~~
lmm
Well no, a lot of bugs didn't pass a type checker because a lot of languages
don't have them. And some projects don't have unit tests.

~~~
GFK_of_xmaspast
> And some projects don't have unit tests.

If a bug did not cause a unit test to fail, then it passed the unit test
suite. (Less cryptically, an empty set is still a set)

~~~
recursive
If we're getting that pedantic, the quote was "they passed unit tests". If the
bug passed a 0-size set of unit tests, then it didn't actually pass any unit
tests.

~~~
eru
They didn't pass any, but they passed all.

In any case, Rich Hickey probably had more context for his words.

~~~
zachrose
Still though, 0% test coverage.

~~~
eru
Division by zero..

~~~
lmm
How so?

10 (say) lines of code, 0 lines covered by tests, test coverage is 0/10\. No
division by zero, nothing undefined happening.

------
infinity0
Apparently this

    
    
      s f g x = f x (g x)
      k x y   = x
      b f g x = f (g x)
      c f g x = f x g
      y f     = f (y f)
      cond p f g x = if p x then f x else g x
      fac  = y (b (cond ((==) 0) (k 1)) (b (s (*)) (c b pred)))
    

is faster than this

    
    
      facAcc a 0 = a
      facAcc a n = facAcc (n*a) (n-1)
      fac = facAcc 1
    

and these are the first and second fastest.

> Interestingly, this is the fastest of all of the implementations, perhaps
> reflecting the underlying graph reduction mechanisms used in the
> implementation.

Could anyone elaborate on this a bit more?

~~~
protomyth
Can someone explain to the non-Haskell folks how that first example works?

~~~
harveywi
The author had (too much) fun using a combination of the SKI combinator
calculus [1] and the "B, C, K, W" system [2].

[1]
[https://en.wikipedia.org/wiki/SKI_combinator_calculus](https://en.wikipedia.org/wiki/SKI_combinator_calculus)
[2]
[https://en.wikipedia.org/wiki/B,_C,_K,_W_system](https://en.wikipedia.org/wiki/B,_C,_K,_W_system)

~~~
maweki
Isn't Haskell internally using a variant of the SKI combinator calculus to
represent that all functions are data? This would mean less reduction for an
already reduced program.

~~~
lelf
That would be true for a toy Haskell compiler. “The standard” Haskell
compiler, GHC, can do a whole lot of optimisations and produces really good
machine code nowadays.

------
LesZedCB
Every time I see this a get further down the list of examples that I
understand. Unfortunately, I still don't make it very far before I'm lost.

------
tromp
Church of the No Fixed Point programmer:

    
    
        succChurch n f = n f . f
    
        facChurch n f = n g (const f) id where
                g f n = n (f (succChurch n))
    
        toChurch 0 = const id
        toChurch k = succChurch (toChurch (k-1))
    
        fromChurch n = n succ 0
    
        fac = fromChurch . facChurch . toChurch

------
LifeQuestioner
Are there actually any use-cases where haskell would be recommended over other
languages? There shear level of thinking and multiple different ways to do
what seems like trivial tasks is mind bending...perhaps I never did it enough
to a level this would not be the case.

~~~
tdeck
Every year since I've started to read about programming (maybe 10 years),
Haskell (and pure functional programming in general) has been the Next Big
Thing. I don't have anything in particular against Haskell, but its failure to
"arrive" makes me think the answer to your question is no.

~~~
jfoutz
Evolution is slow. Java imho brought garbage collection to the mainstream.
lisp had been doing that for 20 years or so.

I don't think Haskell itself will ever be the language of choice, it'll
probably fall into (remain in?) a smalltalk like life.

That said, functional idioms seem to be creeping into lots of mainstream
languages, so it's not like _never_. Rust seems pretty heavily influenced by
ml, and somewhat by haskell.

~~~
tdeck
Only on Hacker News is Rust considered a mainstream language, but I see your
point :).

~~~
jfoutz
Ha! Totally agree. I do think rust has a lot of potential to take a big bite
out of c/c++'s current share. But that's 10 years away, because evolution is
slow.

------
begriffs
Haskell is a nice language and you can build regular stuff with it. I wish
people shared more prosaic Haskell rather than shock-value postdoc thesis
material. I know this article is a joke, but it plays into that stereotype.

There's this helpful site that suggests libraries for various things:
[http://haskelliseasy.com](http://haskelliseasy.com) Someone should make a
companion site listing snippets of code for common tasks showing plain ways of
doing things.

------
unfamiliar
Another post convincing me that writing versions of the factorial function is
the primary focus of Haskell. I keep hearing about Haskell in production, I
would like to see examples of the language actually doing something useful.

~~~
MaxGabriel
Here's a screencast of me making a blog application with the Yesod web
framework: [https://www.youtube.com/watch?v=SadfV-
qbVg8](https://www.youtube.com/watch?v=SadfV-qbVg8)

While I would also like more production Haskell examples, I wouldn't read much
into this webpage—it's basically just a 15 year old joke.

------
marvel_boy
Won't product [1..n] lead to a space leak?

~~~
bbcbasic
[1..n] is not an array but a lazy-generated linked list. So you'd get a space
leak only if it loaded the entire list in memory, or it kept all of the
intermediate calculations (called thunks) in memory. The question is does it
do that, or can it use tail-call optimisation, which would effectively compile
to a loop with an accumulating variable, discarding the thunks

I admit now I am stuck looking at
[http://hackage.haskell.org/package/base-4.8.2.0/docs/src/Dat...](http://hackage.haskell.org/package/base-4.8.2.0/docs/src/Data.Foldable.html#product)
as it uses foldMap which I am not used to. According to
[https://wiki.haskell.org/Fold](https://wiki.haskell.org/Fold) foldl can make
use of TCO. When I get some time I will see if I can produce the thunks as I
am very interested i this!

~~~
platz
there are various ways to view exactly what ghc produces (i have one in my
comment below)

------
agumonkey
Any updates since ? with FTP.

------
dschiptsov
The last 5 or 6 examples clearly captures what is wrong with programming in
J^Hgeneral.

Tendency to pile up useless crap^Wabstractions is the cause of suffering.

Imagine that your doctor and financial adviser are doing this. Hey, wait a
minute...

