[Haskell-cafe] Tutorial: Haskell for the Evil Genius

Andrew Pennebaker andrew.pennebaker at gmail.com
Fri Sep 14 23:18:24 CEST 2012

A summary of the changes I've included so far:

> Under Declarative, you aren't creating a "named expression, 2 + 2", really.
> You are redefining (+).
Noted and reflected in the new version.

> Under Lazy, your example of binding fib 30 is not a good example of
> memoization. With memoization you typically call the underlying computation
> the first time, and memoize it for repeated retrieval later, not hardwire
> in
> values at compile time. Here you never ever call the real fib at all. On
> top
> of everything else, it'd be too easy to introduce a typo into one of your
> hardwired constant values.
Noted and reflected in the new version. After several comments to this
effect, I do not want to misrepresent memoization in the tutorial.
Sometimes it is useful to be slightly inaccurate in a tutorial in order to
help bridge the gap between someone with no experience in a something vs
the wealth of knowledge and complexity in the thing itself. This is not one
of those times, and fortunately, fixing the misrepresentation in my
tutorial is as easy as removing the hardcoded call.

One thing I want to double check is that Haskell does, in fact,
automatically memoize all pure function calls. Is this true?

I would still like to provide a performance comparison of the Fibonacci
code with and without memoization, for readers who enjoy numerical
evidence, using the Unix "time" command, but I don't know how to turn
memoization off. I guess I would have to reimplement the algorithm in a way
that can't make use of memoization. Any suggestions?

Under Infinite, you should use "sieve (n:ns)" pattern matching instead of
> calling head.

Thank you! I try to make use of Haskell pattern matching wherever I can.
Since I needed to refer to the whole list, as well as the head and tail, I
originally used "head" instead of pattern matching. Noted and reflected in
the new version.

> Under Type-Safe
> Subtle distinction, but returning () is not the same as returning nothing
> at all.

True. Noted and reflected in the new version. What's the Haskell name for
() again? I fear explaining the exact type information of IO () may be too
much for a brief introduction to Haskell to cover.

> s/ommitted/omitted/

Noted and reflected in the new version.

> You've got an unusual indentation scheme. Consider adopting a more standard
> one for your tutorial.

I'm in the camp of hard tabs rather than soft tabs, and that preference is
probably responsible for much of the difference in indentation scheme.
Unfortunately, HTML is terrible at representing hard tabs in <PRE> code
with a custom width preference; they all come out looking like some idiot
pressed space bar eight times. I could use JavaScript to remedy this, but
for now, I like to directly copy and paste my working code from .HS files
into <PRE> tags just in case.

If tabs are *not* the issue, then maybe I'm not indenting far enough to the
right for some tastes? Or maybe it's my tendency to put "where" on its own
line, something a Perl obfuscater would detest. I dunno. If someone would
suggest a more idiomatic indentation scheme for my code so that I know
exactly what is different, I can take a look.

> In general, monotonically decreasing is not sufficient to prove you will
> hit
> a base case. For example, decreasing by 5 would still be monotonically
> decreasing, and could jump right over your base cases.
> (Not arguing that the code is incorrect, but rather than your explanation
> is
> a little misleading/incomplete.)

Understood. Noted and reflected in the new version.

Incidentally, when will Nat be available in Haskell? The Fibonacci
algorithm is designed to work only over natural numbers, and the best way
to express this in the type system is with Nat. But this type doesn't seem
available out-of-the-box for Haskell users. Unless I'm using my Haskell
Platform (GHC 7.0.3) is slightly outdated. Eh?

> Again, further confusion about what memoization really is.
> Under Records
> "Functions are already defined by their data structures; they are already
> semantically bundled..." doesn't seem to make sense.

Noted and reflected... I'm trying to convey to an audience largely composed
of Java and C++ fanatics how Haskell records are much better than OOP, how
GADTs are more intuitive, robust, ... OOP doesn't even compare! That's what
I'm trying to get across in that bit. And it's hard to do this in just a
few sentences, especially when the reader isn't even familiar with GADTs in
the first place.

"... acts on the specific constructor, blasting fools, murdering crowds..."
> makes it sound like fireOn actually has side effects.

A truly fair point. Would you like to contribute a monad for blowing up the

Another comment:

> "As a declarative language, Haskell manipulates expressions, eventually
> reducing expressions to values."

> Huh? In what sense do declarative languages manipulate expressions? Sounds
> like a classic syntax/semantics confusion, especially when interpreters
> and/or lazy evaluation (implementation issues, not language properties) are
> in the mix.

Noted and reflected in the new version.

I'm trying to introduce the concept of declarative programming as opposed
to imperative programming. Declarative programming according to

is a programming paradigm that expresses the logic of a computation without
> describing its control flow.

I believe this is done in Haskell and other declarative languages by
treating code as manipulable, reducible expressions, where imperative
languages would use machine instructions.


Now, besides the code and the description of the code, I know we're not
English majors, but what do you think of the overall tone, pacing, etc.? Is
it entertaining? Is it humorous? Is it boring? Is it offensive? Is it too
brief or too laborious?

Thanks all for your suggestions.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20120914/1b26dbc6/attachment.htm>

More information about the Haskell-Cafe mailing list