[Haskell-cafe] Tutorial on Haskell
Juan Carlos Arevalo Baeza
jcab.lists at jcabs-rumblings.com
Wed Apr 18 15:29:34 EDT 2007
I still love Haskell, but...
"since the language doesn't do batshit insane things behind your back"
- Hmmm... I'd contend that the Haskell language is the one language that
does the most "batshit insane things behind your back", for instance list
fusion. This is probably because there are many more "batshit insane
things" that can be done without playing russian-roulette games with your
I believe that the problem is with the semantics: if all the relevant
semantics of your program are clear to you, then you understand it.
Otherwise, you don't. Regardless of language. C++ semantics are hard to
understand due to the existence of side effects, which explode the
dependencies between parts of the code to nuclear proportions. The
optional semantic notation "const" is the only tool available to help
diminish the problem. Haskell semantics are typically hard to understand
wherever strictness matters, which can also be very hard to figure out.
Optional strictness annotations are the tool there. Polymorphism problems
also come to mind, in which case type signatures are the tool. And
performance I always find hard to reason about in Haskell, and there is no
tool available besides the strictness annotations (or inline pragmas and
such). If it performs very well, because fusion happened or whatever, then
great. Otherwise, IO-izing is the only tool I know to apply to your code
to make it tractable for performance (so you can lay out your data in a
performant manner and such).
So Haskell semantics, in my experience, are sometimes just as obscure
and hard to understand as those of C++. Fortunately, that's a situation
that maybe changes to the language, or maybe more literature, can improve.
One example of a polymorphism semantic problem I encountered recently:
Nice article. Relevant and informative. My first thought was... how
silly. He's pairing up a type class with an abstract datatype (Language
and SafeString). That's a waste. He could have just used a type class
everywhere, and that would have worked fine. I hope you see that. Wherever
he uses SafeString he must, by necessity, add the Language context to its
parameter. So.. you can make SafeString a type class, with members
"empty", "frag"="litfrag", "text"="littext", "render"="natrep" and
"lang"="language", and the basic code turns much, much more concise. Users
of the library need to define "empty", whereas they didn't need to
previously, but that's a relatively small price to pay.
I tried that.
Then, when I saw the compiler errors, it downed on me.
The whole thing was done in this manner just so that he can instance
"Show (SafeString l)". Instancing "Show l" is not an option due to the way
class instantiation contexts are not part of the instance itself. Also, so
that he could define "showsPrec".
Therefore, with the new and improved SafeString I was trying to make,
there's more of a burden on the individual implementations of safe strings.
And all that was kinda hidden in the semantics, undocumented, and there
was no way for a strong novice like myself to figure it out without trying
the alternative, even though it is a small and simple example.
Maybe someone should properly document the class-record combo pattern
or something. Or maybe it is documented and I haven't seen it. :-)
On Wed, 18 Apr 2007 10:50:04 -0700, Sebastian Sylvan
<sebastian.sylvan at gmail.com> wrote:
> I think the emphasis when mentioning "reasoning" really shouldn't be "you
> can reason formally about your programs and prove that they don't go
> nor "when it has gone wrong, you can reason about the program to figure
> why", it should be "since the language doesn't do batshit insane things
> behind your back, your programs will mostly work the first time".
> The "reasoning" isn't an active task that you schedule time for, at least
> for a casual user like me, it's part of the actual programming. You do
> "reasoning" when writing in C++ as well, but you often get it wrong
> the language is, shall we say, unreasonable?) and that causes bugs.
More information about the Haskell-Cafe