
Dijkstra on Haskell and Java (2001) - karshan
http://chrisdone.com/posts/dijkstra-haskell-java
======
jfaucett
I don't see why they don't just teach C, x86, and Haskell everywhere. If you
know the concepts behind these, you can quickly grok any other programming
language. Also I never got the whole hype behind OOP. IMHO its self
explanatory, nothing you need an entire course on to be effective and
understand OOP programs. Memory layout and management, advanced pointer
concepts and monads are a slightly different matter.

If I had to teach someone OOP I'd say, OOP is like the real world if it were
made of puppets and every puppet could pull another puppets strings, pull a
string and a dog barks and wags its tail causing a cat to meow, the key is
just not tangling up your strings.

~~~
dkersten
_and monads_

I really don't understand why people have such issues with monads. I don't
have a haskell background and originally built up most of my functional
programming skill in Python (going somewhat against the grain) and I find
monads to be a fancy scary term for an extremely simple concept. I think if
they were named something friendlier perhaps people's eyes wouldn't
immediately glaze over and they could realise that, actually, monads are just
a simple strategy for controlling how things are executed/computed.
Computational or execution strategies, if you will. Lets just call them
strategies and see if they are less confusing and scary?

~~~
nbouscal
I really don't understand why people think monad is a "fancy scary term". It's
a five-letter easily-pronounceable word. What makes it fancy or scary? I think
people assume that they're scary, and then confirmation bias themselves into
making them hard to learn, despite them being a reasonably simple concept
overall.

As for calling them strategies… if we called them that it would make learning
and understanding the intermediate and advanced concepts _significantly_ less
accessible and more difficult. We should call things what they _are_.

~~~
jfaucett
hmm, if we called them what they are we'd call them "type wrapper functions"
and talk about "type wrapper function chains", monads carries zero
metaphorical/associative meaning. I think thats the problem with the name and
a large reason people find them so unapproachable, most other terms in
computer science carry significant associative meaning that helps in learning
them, pointers have to do with pointing at things, functions carry the
mathematical meaning of a set of inputs mapping to a set of outputs, etc.

~~~
nbouscal
You're demonstrating that you don't know what monads are. "Type wrapper
function" could mean any number of things (lack of specificity is a bad trait
in naming), but it couldn't mean a monad: monads consist of three things,
whereas "type wrapper function" implies one thing.

Names don't need to be metaphorical. The purpose of a name is not to teach you
what the thing is. For that, you should have a proper explanation from someone
who knows. Names have a different, very important purpose: uniquely specifying
the thing being named. "Monad" does that very effectively.

------
tormeh
There's a link on the page to this essay by Dijkstra:
[http://www.cs.utexas.edu/~EWD/transcriptions/EWD10xx/EWD1012...](http://www.cs.utexas.edu/~EWD/transcriptions/EWD10xx/EWD1012.html)

It's overall badly (at least foggily) written, but I find this quote really on
point:

>The moral of the story is clear: real programmers don't reason about their
programs, for reasoning isn't macho. They rather get their substitute for
intellectual satisfaction from not quite understanding what they are doing in
their daring irresponsibility and from the subsequent excitement of chasing
the bugs they should not have introduced in the first place.

And that, ladies and gentlemen, is why I think people think C/C++ is an
acceptable tool for anything besides drivers and kernels, for which they're
only acceptable because there's no better alternative. Sure, pointer-pointers
is a magnificent idea! I'll totally keep that under control!

~~~
sbov
You could actually argue the opposite.

People who can use C++ need to reason about their programs because otherwise
they're going to shoot their foot off. You can be irresponsible in a language
like python and get away with it because you're not going to cause the issues
you would in C++.

I think that, to some extent, this is true. If you don't know what you're
doing I find it's easier to code yourself into a corner in C++ than something
like python.

(Disclaimer: I haven't used C++ in a decade)

------
Osmium
I've never formally studied CS, but I can definitely see the benefit. I can
divide my own (amateur) programming experience into pre-Haskell and post-
Haskell. Before I started learning Haskell, I thought I knew how to use a good
half a dozen or more programming languages. After I started learning Haskell,
I realised I'd really only known how to use one all along, and that they were
all fundamentally the same. I wish I'd had the experience sooner (plus,
learning Haskell is just plain fun).

~~~
Verdex
If you liked the "I'd really only known how to use one" type of experience,
then I encourage you to keep learning languages after you are happy with where
you are with Haskell. My experience is that languages stop feeling like
cohesive entities and start feeling like a collection of features.

The nontraditional categories I've encountered are something like:

The macro facilities in lisp, scheme, forth (or factor), template haskell, and
C++ templates.

Array languages like APL, K, or R.

Prototype inheritance with smalltalk or Lua.

Avoiding side effects with Haskell, Ocaml, or C#'s linq.

The "we're serious about type theory" languages like Haskell, coq, agda, and
idris.

------
navait
As much as I love Haskell, one problem with the intro to CS courses is that
many of the students are not CS majors, but students from other disciplines
that need to learn a little bit of programming. It makes sense here to teach
Java and Python, as imperative languages are more useful to real world
programming than functional languages.

Perhaps it would be better to create a separate intro course for CS majors. On
the other hand, most curriculum in CS demand that students learn about
languages like prolog and Haskell, so it's not like students will never be
exposed to it.

~~~
cafebeen
To followup with a note from the article: "A very practical reason for
preferring functional programming in a freshman course is that most students
already have a certain familiarity with imperative programming. Facing them
with the novelty of functional programming immediately drives home the message
that there is more to programming than they thought."

It's no surprise that this attitude can discourage students without
programming experience... A parallel intro track seems like a nice solution
that has worked in a number of schools.

~~~
navait
That actually did bother me in the letter.

He states:

-Most students taking CS courses are already familiar with an imperative laguage.

-we are all shaped by the tools we train ourselves to use, and in this respect programming languages have a devious influence: they shape our thinking habits.

This would imply that most CS students already come pre-ruined. At that point
then, does it matter what language is picked?

Another alternative would be to start functional languages with data
structures and algorithm courses(Generally taken sophomore year, and one of
the first CS specific classes taken), and use that to fix broken habits. idk
if the professors though want to take time to teach a new language if students
already know one.

~~~
TheOtherHobbes
This is the same guy who said

"It is practically impossible to teach good programming to students that have
had a prior exposure to BASIC: as potential programmers they are mentally
mutilated beyond hope of regeneration."

and

"The use of COBOL cripples the mind; its teaching should, therefore, be
regarded as a criminal offense."

and

"FORTRAN, 'the infantile disorder', by now nearly 20 years old, is hopelessly
inadequate for whatever computer application you have in mind today: it is now
too clumsy, too risky, and too expensive to use."

Basically he's a mathematician who codes, and who wants code to be math.

Unfortunately in the real world code is also politics, business, history,
sociology, and psychology. The math part is important, but it's not the whole
story.

He's often funny, in a dry way, but it's useful to understand that _he 's
actually not very insightful about the psychology of effective programming._

He praises mathematical intuition, and he wants to develop it, but he doesn't
seem to have considered the possibility that simply throwing Haskell at
people, or asking them to work through formal methods, may not be the best way
to do that.

There's almost no useful research I know of that examines what mathematical
intuition is, and even less about whether it's teachable. So Haskell and
formal methods may help some people some of the time. But it's not _in any
way_ a given that they're the best of all possible teaching methods.

He also misses an entire class of UI/UX bugs where the code works exactly as
it's designed to, and is provably formally correct, but an application is
useless because the UI is incomprehensible and/or misleading and/or actively
distracting to the task at hand.

Ironically, it's exactly that interface between fuzzy human expectations and
implicit modelling tendencies and the rigidity of code that causes the most
issues for practical projects.

This doesn't just apply to applications - it also applies to languages,
operating systems, and development environments, some of which add unnecessary
cognitive loads which make programmer mistakes more likely.

His solution - formal rigour - only works if you can formulate a problem
precisely in the first place.

The set of problems where it's possible to do that doesn't come close to
covering all the problem spaces touched by computing.

------
brianchu
FWIW, UC Berkeley's intro CS course sequence goes through the following
languages in order: [Scratch (in an optional gentle-intro CS course)], Python
(with an emphasis on using it for functional programming), a tiny bit of
Scheme, a tiny bit of SQL (before they used a toy logic programming language),
Java, C, MIPS assembly. I think this walks down the ladder of abstraction very
nicely.

~~~
cheepin
Odd to use Python as your intro to functional programming, since it lacks many
functional programming features besides lambdas which the language creator
doesn't even like
([http://www.artima.com/weblogs/viewpost.jsp?thread=98196](http://www.artima.com/weblogs/viewpost.jsp?thread=98196))

~~~
TazeTSchnitzel
Python is more object-oriented than anything else. It's not terribly
functional. Most tasks that can be accomplished with functional programming in
Python aren't.

------
megaman821
I was attending UT during this time period, but luckily it took until my
senior year before the Java-fication of nearly every class was complete.

My intro class used Dr. Scheme, and I think it worked very well for
introducing new concepts. Following classes were mostly C++ with some C and
assembly mixed in. When they finally introduced Java it took students a couple
days learn it since they all had decent C++ backgrounds from previous classes.
I don't think that would work in reverse, a Java background is not going to
let you pick up C++ in a couple days. That is what the department did not
understand, not knowing Java isn't that much of a determent to getting an
entry level Java job. With a solid foundation, a junior programmer can pick up
Java quite fast.

------
acallan
Indeed, my first CS class in 1999 at UT was in Haskell. Wow! What a change it
was from high school AP Computer Science in Texas, which was (in those days)
C++.

Seeing QuickSort in just one line was what hit it home.

I remember thinking at the time that this was really incredible, but that
Haskell had no future. This was at the time of Hugs 98, although I remember
hearing about GHC. I'm glad to be wrong about this.

~~~
SilasX
Hold on: does Haskell allow "the" QuickSort on one line, or just _a_ sort?
Because from what I've read, if you want to make Haskell do all the efficient
stuff in a QS, you have to tell it a lot more, bloating the program.

Edit: this is what I had in mind:
[http://augustss.blogspot.com/2007/08/quicksort-in-haskell-
qu...](http://augustss.blogspot.com/2007/08/quicksort-in-haskell-quicksort-
is.html)

Btw, I took AP Compsci with C++ in Austin around that time, so we might know
each other.

~~~
acallan
Like a lot of UT Computer Science, the implementation is a detail left for the
reader. The semantics of the language make the one-liner n*log(n)--that's the
takeaway.

~~~
SilasX
But the one liner _was_ the implementation, and doesn't do a QuickSort...

~~~
acallan
In tests and homework, we would implement the one-liner quicksort with paper
and pencil, much like a math test. In a pencil implementation of that Haskell,
it is n log(n). Each line on the paper represented one level of recursion.

Implementing it on silicon requires the trade-offs you mention. But silicon is
just an implementation left to the reader...

EDIT: I guess where I'm coming from, Haskell was used in the context of the
Theory of Computation, not real-world implementation details and the like.

~~~
SilasX
I'm not disputing the scaling properties of the Haskell one-liner, but it
doesn't give you the benefits of the true QuickSort as your comment suggests,
e.g. it doesn't guarantee in-place sorting or efficient use of when access be
locked.

The point is, I find it questionable to praise Haskell for how you can
implement a one-line QuickSort that isn't really a QuickSort.

~~~
acallan
Each list comprehension is O(n). O(n)+O(n)=O(n). Each iteration will roughly
bisect the list, resulting in roughly log(n) iterations. Thus the one-liner is
O(n*log(n)).

Haskell says nothing about how lists are implemented, so with respect to
"true"ness (I'm not really sure what this means), we can cannot generalize. A
sufficiently optimized Haskell compiler implemented in silicon would have the
liberty of using the memory in-place.

~~~
SilasX
>Each list comprehension is O(n). O(n)+O(n)=O(n). Each iteration will roughly
bisect the list, resulting in roughly log(n) iterations. Thus the one-liner is
O(n*log(n)).

"I'm not disputing the scaling properties of that sort" = this proof does not
convince me of anything I didn't already agree with. Was I unclear about what
I was objecting to?

> Haskell says nothing about how lists are implemented, so with respect to
> "true"ness (I'm not really sure what this means), we can cannot generalize.
> A sufficiently optimized Haskell compiler implemented in silicon would have
> the liberty of using the memory in-place.

"Trueness" means "doing the real QuickSort". The one you posted doesn't. You
can get the real QuickSort, but not with one line. A better compiler might
identify useful invariants; you were not using such a compiler.

But if you had such a compiler, you wouldn't need to write I that way; you
could just specify what conditions the final sort would obey, and that would
be enough. You wouldn't need to tell it to filter explicitly.

~~~
acallan
What do you mean by the "real QuickSort"? The professor who taught me Haskell
at UT used to work on Burroughs LISP machines and wasn't too concerned with
caches, memory, or the like. Again, Haskell can be viewed as a language for
computation. From this perspective, the one-liner is pure beauty.

------
klutometis
Dijkstra's advocating a Sapir–Whorf[1] of programming languages, which I long
suspected to be true; but haven't been able to rigorously prove or disprove.

[1]
[http://en.wikipedia.org/wiki/Linguistic_relativity](http://en.wikipedia.org/wiki/Linguistic_relativity)

------
fishnchips
My main problem with teaching CS courses in Java was that it produces folks
who have no clue about pointers or memory management in general. This however
applies to Python and Haskell as well. I personally had a strange mix of Java,
x86 assembly and Ruby in my curriculum.

~~~
zak_mc_kracken
That's like saying "The problem with teaching people how to drive cars is that
at the end, they don't know how to ride motorcycles".

There are plenty of other classes at the grad and undergrad level that teach
you about lower level concepts such as pointers and memory (system, C, OS,
...). The Java classes teach different concepts.

~~~
fishnchips
I never got C or C++. The OS course, sure, but it was awfully theoretical and
we didn't get to code all that much. Depending on the rest of the curriculum
you should probably decide what to use to teach introductory CS.

------
Gyonka
I agree with him in the sense that these are CS courses, and in in such a way
Haskell ties together well with the math that one learns in a CS program.
Keeping that in mind it makes sense to only have taught Java in courses
specifically designed for developing software.

~~~
mathetic
I am looking forward to the day the notion that functional languages are not
suitable for developing software will die.

It is not only that functional languages are more succinct, easier to reason
about and are more readable, they also often come with significantly better
type systems. Some have type systems sophisticated enough to specify nearly
all the legal states and guarantee these are the only states the program can
stay in at compile time. One can look at languages with dependent types for
that.

On the more practical front, Erlang proved itself over three decades to be one
of the best choices when it comes to fault-tolerant, highly concurrent
systems. Jane Street is using OCaml for all of their trading software, Morgan
Stanley has moved to Scala, and so on and so forth.

~~~
CJefferson
That day will come, for many of us, when a large AAA game, web browser, or
usable OS is written in a FP language.

And I realise that is an unfair target, but there is very little user facing
FP software. The only one I can think of I have used is xmonad, which is both
hard to use and fairly buggy

~~~
pjmlp
You mean like Crash Bandicoot, Abuse, Jak and Daxter?

Or maybe Genera.

Or maybe Remote Agent software used by Nasa Deep Space 1?

Or eventually the train control systems running on software from Siscog?

~~~
alayne
You can do functional programming in Lisp, but even the wiki page for GOAL
says "GOAL encourages an imperative programming style". Not to mention most
Lisp data structures being mutable if we're talking purely functional.

~~~
pjmlp
I have a problem with modern notions of purely functional.

My first functional programming language was Caml Light, back in 1996.
Followed by Prolog and eventually Lisp.

All alongside traditional lambda calculus and logic proofs, with ocasional
references to a programming language called Mirada.

So for me, Lisp is functional programming and I don't buy into this modern
notion that only Haskell is the poster child of FP.

~~~
Retra
I looks like alayne is using 'purely functional' to mean Pure + Functional,
but you are using it to mean Everything is an Expression / First-class
functions, etc.. The functional paradigm.

Lisp is definitely a functional language. It's just not as pure as Haskell,
which is the poster child for Maximally Pure FP, if not for the functional
style.

~~~
pjmlp
Hence why I made the reference to Miranda.

We were already doing functional programming while Haskell was still using
diapers.

~~~
Retra
Well, yes. Haskell is heavily inspired by Miranda. Haskell was just managed in
a way that allowed it to become very popular.

------
LukeHoersten
My favorite quote:

"A fundamental reason for the preference is that functional programs are much
more readily appreciated as mathematical objects than imperative ones, so that
you can teach what rigorous reasoning about programs amounts to. The
additional advantage of functional programming with “lazy evaluation” is that
it provides an environment that discourages operational reasoning."

------
MrQuincle
Although I didn't do CS, but electrical engineering, I would have loved to get
some more exposure to functional programming. We got Scheme which everybody
hated because of the cumbersome bracket counting.

And of course we got C, Java, Matlab, and VHDL, besides a bunch of assembly.
VHDL or Verilog would maybe also a nice eye opener for CS students. It's again
another mindset.

~~~
codygman
Think about how that would have changed if they had a simple text editor with
parenthesis highlighting.

~~~
MrQuincle
Absolutely. Or parenthesis coloring, that would be even better.

------
peterashford
While I wouldn't start with Java (it's not the simplest language about - I'd
probably use C or Python) Dijkstra's anti-Java rant is over the top. It's
still a huge language and that's NOT because of any corporate advertising
campaign. Something that succeeds as well as Java has to have some actual
value.

~~~
wyager
>Something that succeeds as well as Java has to have some actual value

Well yes, it has _some_ value. However, just because a lot of people
like/believe something doesn't make it good/true.

It's not like corporations have some vast conspiracy in place to encourage the
use of Java; it's simply that Java, for a number of reasons, is attractive to
middle-management types, even though it's not the best language to make _good_
software. That's not necessarily a criticism of Java; from many perspectives,
making good software is not the primary goal.

Dijkstra's big thing was prioritizing good software over cheap software. This
may not be a realistic goal, but it certainly explains why he preferred
Haskell to Java.

He wrote some really good essays on why you need languages like Haskell to
raise the overall quality of software floating about. The more you can shift
the burden of guaranteeing correctness away from humans and towards infallible
mechanical systems (like Haskell's relatively powerful type system), the more
likely you are to end up with good/correct software.

