
Effective Programs: 10 Years of Clojure - kimi
https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/EffectivePrograms.md
======
flavio81
Very good slide here:

[https://github.com/matthiasn/talk-
transcripts/raw/master/Hic...](https://github.com/matthiasn/talk-
transcripts/raw/master/Hickey_Rich/EffectivePrograms/00.27.19.png)

Caption: "The problems of programming"

 _And you can call them problems, and I 'm going to call them the problems of
programming. And I've ordered them here -- I hope you can read that. Can you
read it? Yeah, ok. I've ordered them here in terms of severity. And severity
manifests itself in a couple of ways. Most important, cost. What's the cost of
getting this wrong? At the very top you have the domain complexity, about
which you could do nothing. This is just the world. It's as complex as it is.

But the very next level is the where we start programming, right? We look at
the world and say, "I've got an idea about how this is and how it's supposed
to be and how, you know, my program can be effective about addressing it". And
the problem is, if you don't have a good idea about how the world is, or you
can't map that well to a solution, everything downstream from that is going to
fail. There's no surviving this misconception problem. And the cost of dealing
with misconceptions is incredibly high._

I'd suggest to consider the diagram cited above, it is a good representation
of where the real difficulties lie in programming.

~~~
hellofunk
I have some doubts about this one, despite my love and ongoing professional
work with Clojure. For overall productivity, I find the issue of typos more
significant than this slide leads us to believe, especially in a language like
Clojure where the compiler does not catch nearly 90% of my typos. It's very
easy to have a nil running through your program in Clojure because you either
mistyped a keyword or you just picked the wrong one when pulling something out
of a map, for example. But that is just one example, I find that I spend a
fair amount of my work day tracking down silly typos at run time, which
frankly disappoints me tremendously. I really like Clojure but tackling this
problem has been non-trivial.

~~~
raspasov
IntelliJ + Cursive makes keyword typos and most other typos a non-problem (or
very easily spottable problem) for me.

~~~
hellofunk
How does Cursive know if you're pulling out a valid keyword in a map?

~~~
positr0n
I doesn't know if :resource_id is in the map, but that's not a typo if that's
the case.

What OP meant is if you type :resuorce_id it won't autocomplete correctly so
you're more likely to notice.

~~~
hellofunk
Ah, well I get that same behavior in Emacs. Doesn't always help though.

~~~
raspasov
Also if you type resuorce_id when referencing it will tell you that it cannot
resolve the local. Of course if you BOTH destructure resuorce_id AND reference
resuorce_id then you're out of luck :). That happens rarely though. One recent
IntelliJ addition which is sometimes annoying but often very helpful in many
cases like that is notifying you of grammatical typos: as long as you're not
using obscure one off abbreviations, etc it will most likely catch
"resuorce_id", "widht" and similar typos but might also complain about valid
words or abbreviations in some niche domains.

------
wellpast
Rich comes down hard here on statically typed languages, but before the static
typers get too offended, his main attack is on the overuse of ADTs/classes to
build information processing systems (i.e., what a majority of us industry
programmers are doing; he takes pains to define this arena...see the
slides/discussion on what Rich calls "Situated Programs").

So before the static vs dynamic typing debate gets too heated up here, I think
we should focus on this point first[1].

For those of you wary of his point here, I think it's worthwhile to go through
an exercise, if you have the time to explore this. Write a simple information
processing app using two different paradigms:

    
    
       - Write it using a statically typed language and a relational database.
       - Then write the same app using some NoSQL store and avoid using ADTs (prefer using just maps of facts). Ideally do this in a dynamic language so the ergonomics are better for you.
    

And then ask yourself: Which one of these felt safer? More familiar? Which one
of these offered more freedom, choice, and speed?

1\. I do think that once you come to terms with the problems of ADTs, you are
on your way to not needing all the static type verification, but leave that to
later.

~~~
pklausler
But at its best (as in Haskell), static typing just means that the compiler is
enforcing the requirements of your interfaces. Why would you not want to know
about these bugs immediately and fix them early in the development process
when it's cheap to do? Why wouldn't you want the compiler recheck everything
automatically every time you change your interfaces?

Everybody's always fixing bugs. Static typing makes it more likely that the
bugs you're working on are closer to the problem domain, instead of being crap
work that should have been caught at compilation time with better languages
and compilers.

~~~
wellpast
> Why would you not want to know about these bugs immediately and fix them
> early in the development process?

That's a good question. But enforcing your codebase to be a Rubix cube you
have to twist and turn until the static type checker says Yes is not trivial.
Its a tax.

The real question is whether that tax is worth it when your goal is purely
business delivery and not something else (eg, intellectual stimulation). Is
it?

Writing unit tests and code review are other means to root out bugs. But they
also come with a tax. When are they worth the tax and when are they not worth
the tax?

In some cases we judge they are. In other cases not.

A statically typed language typically asks us to turn off our brain and apply
type verification _everywhere_. In this way, statically typed languages wield
type verification more like a religion than a tool.

~~~
raiflip
Honestly I've never understood this argument that choosing types is too
complicated. Most often I've seen it come from people without much experience
in statically typed languages and imagine that having to determine the type
will be difficult.

After becoming familiar with the code base or library, particularly with
modern IDE's it's rarely taken more than 10 seconds to choose a type. When
reading another person's code, it does take some time to map out the
relationship between the classes, but unless your code is in one giant
file/function/object you're going to have to figure that out anyway.

~~~
wellpast
From Rich's talk: "Now at this point I was an expert C++ user and really loved
C++, for some value of love."

Rich has had many years of experience in statically typed language.

~~~
pklausler
Please don't use C++ as an exemplar of static typing. There are much more
powerful and congenial alternatives.

It would be just as unfair if one were to claim that dynamic typing is bad
because assembly language tends to be buggy and expensive to maintain.

------
lunchladydoris
I would recommend taking the time to actually watch the talk [0]. It's well
worth it.

[0]
[https://www.youtube.com/watch?v=2V1FtfBDsLU](https://www.youtube.com/watch?v=2V1FtfBDsLU)

~~~
hyeomans
Thanks for this.

------
jcadam
> _So fundamentally, what is Clojure about? Can we make programs out of
> simpler stuff? I mean, that 's the problem after 18 years of using, like,
> C++ and Java, you're exhausted. How many people have been programming for 18
> years? Ok. How many for more than 20 years? More than 25? Ok? Fewer than 5?
> Right (?), so that's really interesting to me. It may be an inditement (?)
> of Clojure as a beginner's language or may be that Clojure is the language
> for cranky, tired, old programmers._

That's about right :) Yes, I'm tired, cranky, and old.

~~~
pklausler
I've been coding for forty years and I'm not going to go anywhere near a
dynamically typed language ever again for any job bigger than a ten-line bash
script.

~~~
jernfrost
Which dynamic language did you use? Like statically typed languages there is a
huge variety. I don't group languages whether I like them based on whether
they are static or dynamic.

I hate JavaScript, PHP and Perl which are all dynamic. While I like Python,
Lua and Julia. But I also like static languages such as Swift and Go. I have a
certain fascination for Haskell, but I can't be bothered to invest the time to
get any good at it. Which kind of suggest to me that Haskell is a dead end. If
programming language geeks like me can't invest the time, why would the
average developer ever bother.

My work language is C++, which I actively hate, but I can stomach it because
we work on interesting software.

------
carljv
I love this talk, but it does throw out a lot of complicated ideas somewhat
loosely, so I get why reactions and interpretations are all over the place.

I think a good companion to understanding this better is Rich's talk on "The
Language of the System"
([https://www.youtube.com/watch?v=ROor6_NGIWU&t=2810s](https://www.youtube.com/watch?v=ROor6_NGIWU&t=2810s)).

I interpret his overarching thesis as this:

Most "situated" programs are in the business of processing information
according to complex and changing rules, in cooperation with other programs
(i.e., a system). Many languages, though, are overly-concerned with how they
represent data internally: classes, algebraic types, etc. This "parochialism",
he calls it and "concretion" about how data aggregates should work, make them
hard to adapt when the rules, data, or other parts of the system change, and
make it hard for their programs to work in systems. At some point your Java
class or Haskell ADT has to communicate its data to other programs that have
no notion of these things. So you end up w/ a ton of surface area in your code
with mappers and marshallers totally unrelated to the content of the data and
purpose of the program.

The idea behind Clojure is to provide easy access to simple, safe, and
relatively universal structures for holding data, and a library of functions
to manipulate those structures. Its "big picture" design bits are about
providing semantics for multiple "programs" (from threads to services) in a
system to operate on data robustly and reasonably (concurrency semantics, time
and identity models, pervasive unadorned data, etc.) At some point you're
going to be sending this program's data over a wire to another program, and
things like "a map of strings and numbers" is pretty straightforward to
transport, while a sum type implementing functor with a record data
constructor that contains a Maybe SSN is not. It overly couples the underlying
data to the language's representation.

The plus side of doing this is that the language can check internal
consistency for you. The downside is that you're carrying a lot of baggage
that you can't take with you over the wire anyway. Communication in systems is
also why Rich thinks making "names" for data first class is important.
Existing strongly typed languages can sort of accommodate this, but don't
really privilege names.

So I think a lot of strong typing advocates are upset because they think Rich
is saying types don't have value within programs. I don't think that's right.
I think he's saying they have very limited value in _open_ systems, which
makes their costs often overwhelm their benefits in the individual programs
within those systems.

In general, I feel like the debate has been about examining Rich's claims in
the context of programs (is Maybe String good or bad, etc.), whereas he's
really interested in what works in systems. I think that's indicated by his
focus on the term "parochialism" which I have not seen a lot of folks address.

~~~
dragonwriter
> Most "situated" programs are in the business of processing information
> according to complex and changing rules, in cooperation with other programs
> (i.e., a system). Many languages, though, are overly-concerned with how they
> represent data internally: classes, algebraic types, etc. This
> "parochialism", he calls it and "concretion" about how data aggregates
> should work, make them hard to adapt when processing rules change, and make
> it hard for their programs to work in systems.

It doesn't if the systems are well-designed sytems, comprised of loosely-
coupled components, something like you'd get if you used 1970s structured
analysis and then actually modeled the implementation closely on the DFD with
communication over a message bus with a fairly neutral messaging format.

When you start tightly coupling components (e.g., by using a messaging format
tightly bound to an internal representation), using ad-hoc component-to-
component integration rather than a common message bus that is abstracted from
the individual components, and generally do the _system engineering_ badly,
then you have a whole pile of problems, some of which are exacerbated (but not
caused) by static typing, sure.

By static typing is not the problem here.

~~~
wellpast
> It doesn't if the systems are well-designed sytems, comprised of loosely-
> coupled components

I've been going down a similar line of thought. But I went the other
direction. That perhaps in "poorly designed" systems where there is lots of
coupling, static typing at least gives you the "maintenance" benefit that is
one of the bigger justifications that the static type apologist tends to give.
You actually hear this a lot: "in large systems, static typing is a must..."

So it's interesting to me that you're going the _other_ way and saying that
actually in big, messy systems that static types may hurt you. That's not a
common position.

When I walk through some of the big problems in "poorly designed" systems it
almost always comes down to coupling: I can't touch one part of the system
without having an effect on other parts of the system.

Interestingly, Rich Hickey criticizes the common static typer's idioms (like
pattern matching and ADTs) as coupling. And he's right. What always surprises
me though is that the static typer doesn't disagree -- they look at this
coupling as a feature! They usually say something along the lines of "I choose
static typing because if I change my Person class, then the compiler reminds
me of all the places in my code that I need to go fix." What's remarkable
about this is that it's not a reminder...it's an _obligation_ that your
choices _plus_ the compiler are burdening you with: you _must_ go update all
those places in the code. This is the very definition of coupling.

There _is_ a way to architect code such that you don't have to revisit 100
places in your architecture when some new data model decision is
made/discovered. There is a way to build systems wherein you only have to
touch _one_ place in your code when some new feature or data information is
needed.

~~~
benfle
I don't see the difference between sending a Person instance and sending a map
of keywords about a person. The coupling is the same.

~~~
wellpast
If my function only needs to know the "age", then why am I having to fill out
my Person class with all the other stuff? Why, if I have facts about a Cat in
hand, must I coerce it to a Person? These are hoops you're typically jumping
through when you're dealing in ADTs.

~~~
tome
That doesn't seem to describe any hoops I've ever had to jump through when
using Haskell. Can you give concrete examples?

~~~
wellpast
I just did. Having a Person vs. Cat taxonomy. The claim is about ADTs, not
Haskell. When a "name" property will do, why do we need to introduce an ADT?
Why do we need to taxonomize?

~~~
tome
Then you can use a "HasName" typeclass. Admittedly that adds a bit of
boilerplate (in one single place).

~~~
carljv
I think the constant replies of "Oh there's a way to deal with that." Miss the
point. You should keep asking yourself, "Am I fixing a problem that didn't
need to be there?" Sometimes, the answer is: No, I do want this structure, and
it's worth it overall to write interfaces, etc. to add some polymorphism or
dynamism to it where needed. In lots of cases, though, you're just writing
stuff to accommodate the language. In lots of languages I feel like I'm
fighting an internal battle between static-ness and dynamism. Start with
static types or classes, then add interfaces or typeclasses, oh and overload
these functions. Now make sure these other things things implement this new
interface so they can participate, etc.

Sometimes it feels like a real burden for not much gain over just passing
around the basic data (a name, an age) I wanted to deal with to start with.
Clojure's proposition is that in many many cases, not getting fancy with the
data or over-engineering your problem representation will lead to simpler
programs that are easier to maintain, giving you an alternative route to
safety and maintenance instead of type-checking.

------
systems
I didn't really understand his talk I think he was too abstract

It is possible I am missing a lot of the background information to understand
it, but still .. the talk wasnt that technical, just too abstract

I think he could have shown examples, code examples .. to make a more concrete
statement

~~~
hellofunk
> I didn't really understand his talk I think he was too abstract

Then you better stay away from another talk at the same conference, by Guy
Steele [0] !

[0]
[https://www.youtube.com/watch?v=dCuZkaaou0Q](https://www.youtube.com/watch?v=dCuZkaaou0Q)

~~~
systems
I did watch half of it ... i left when i realized, that he will not move to
another topic, he is just truly talking about notations, and comparing them,
and telling stories about how they evolved

I watched in anticipation, that he will use this, to make a point about
clojure or programming models or techniques, but he wasnt gonna ..

It was truly just a speech about notations, and i dont really care about that

------
zeveb
> That was not written in C++, that was around the time I discovered Common
> Lisp, which was about 8 years into that 15 years. And there was no way the
> consumer of this would use Common Lisp, so I wrote a Common Lisp program
> that wrote all the yield management algorithms again out as SQL stored
> procedures and gave them this database, which was a program.

> Eventually I got back to scheduling and again wrote a new kind of scheduling
> system in Common Lisp, which again they did not want to run in production.
> And then I rewrote it in C++. Now at this point I was an expert C++ user and
> really loved C++, for some value of love

> [Audience laughter]

> that involves no satisfaction at all.

> [Audience laughter]

> But as we'll see later I love the puzzle of C++. So I had to rewrite it in
> C++ and it took, you know, four times as long to rewrite it as it took to
> write it in the first place, it yielded five times as much code and it was
> no faster. And that's when I knew I was doing it wrong.

Seems like a pretty good argument for Common Lisp here.

> So, when I discovered Common Lisp, having used C++, I said that, "I'm pretty
> sure to the answer to this question is, 'yeah, absolutely'". And can we do
> that with a lower cognitive load? I also think, "yes, absolutely". And then
> the question is, "can I make a Lisp I can use instead of Java or C#?". Cuz
> you just heard my story, and I used Common Lisp a (?) couple of times, every
> time it got kicked out of production, or just ruled out of production,
> really not kicked out, it didn't get a chance. So I knew I had to target a
> runtime that people would accept.

Pity he hadn't heard of Armed Bear Common Lisp
([http://abcl.org/](http://abcl.org/)), which runs on the JVM.

> And the old Perlis, you know, quip about, you know, "any sufficiently large
> C or C++ program, you know, has a poorly implemented Common Lisp", is so
> true.

That's actually Philip Greenspun:
[https://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule](https://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule)

I (unsurprisingly) don't think his list of problems with Lisp are convincing.
I don't mind mutable state, since the real world is not functional: real
programs are all about side effects. I don't mind that not everything is a
list: as he notes, lists aren't the perfect data structure. I think the
package system is very clean & understandable.

~~~
Sinidir
>Pity he hadn't heard of Armed Bear Common Lisp
([http://abcl.org/](http://abcl.org/)), which runs on the JVM.

First public release of ABCL seems to be after first release of clojure.

~~~
zeveb
Was it? Ward's Wiki indicates someone was using it in 2004:
[http://wiki.c2.com/?ArmedBearCommonLisp](http://wiki.c2.com/?ArmedBearCommonLisp)
(as an aside: why is JavaScript required now?), while Clojure dates back to
2007.

~~~
endgame
> (as an aside: why is JavaScript required now?)

Because it was "improved" (rebuilt) recently.

------
systems
was it really about static typing vs dynamic typing

or more about C++ vs Lisp/Clojure

~~~
lucozade
Not sure it was really about either.

It's really about what experiences led him to make the decisions he made both
in deciding a new language was needed and what attributes the language should
have.

Clearly the decisions were coloured by his experiences of C++, Java and Common
Lisp. But they do appeared much more affected by his views on information
structure, flow and evolution.

------
Tehnix
I found the discussion on /r/haskell to be much pleasant and a good take on
the points Hickey make
[https://www.reddit.com/r/haskell/comments/792nl4/clojure_vs_...](https://www.reddit.com/r/haskell/comments/792nl4/clojure_vs_the_static_typing_world_haskell_in/)
(it's actually a discussion on a piece discussing his talk).

I honestly don't find Hickeys arguments to be very valid, and his take on type
systems honestly make him sound like he never touched something like Haskell
(maybe OCaml) with much more powerful type systems and type inference. He does
not sound like someone that invented a language, and more sounds like a blind
evangelist for dynamic typing.

> static type systems yield much more heavily coupled systems. And that a big
> part of that time aspect of the final diagram of what problem we're trying
> to solve, is dominated by coupling when you're trying to do maintenance,
> right? Flowing type information is a major source of coupling in programs.
> Having a de-, you know, pattern matching of a structural representation in a
> hundred places in your program is coupling, right?

His arguments about coupling seems silly to me, especially since in FP you
usually like generalisations and abstractions that allow you to delay
specialising to a specific type until quite late. Take all the different
typeclasses that exist in Haskell and things like Monads, Applicatives etc
that allow such general abstraction.

> Names dominate semantics, a to a, list of a to list of a [talking about
> `foobar :: [a] -> [a]`], it means nothing, it tells you nothing

It tells so much! It tells us that it takes in a list of any element and the
only operations it can perform are something that alters the structure of the
list (replicate elements, drop elements etc) and no operations on the elements
themselves!

> How many people like UML? How many people have ever used a UML diagramming
> tool? Right? It's not fun, right? It's like, "no, you can't connect that to
> that", "oh no, you have to use that kind of arrow", "no, you can't do this",
> "no, you can't...", it's terrible. OmniGraffle is much better, draw whatever
> you want. What are you thinking about? Draw that. What's important? Write
> that down. That's how it should work, right?

I chuckled a bit here, since Hickey just talked about Simon Peyton Jones in
the previous slide, I'm assuming he at least Haskell in mind somewhat. If
Hickey is seriously comparing Haskell's type system with UML, he needs to go
back and take another serious look at Haskell.

> Yes, IntelliSense is much helped by static types and performance
> optimization, which he didn't list, but I think is one of the biggest
> benefits. We loved that in C++. And maintenance, I think it's not true. I
> think that they've created problems that they now use types to solve. Oh, I
> pattern-matched this thing 500 places and I want to add another thing in the
> middle. Well thank goodness I have types to find those 500 places. But the
> fact was that thing I added, nobody should have cared about except the new
> code that consumed it and if I did that a different way I wouldn't have had
> to change anything except the producer and the consumer, not everybody else
> who couldn't possibly know about it, right? It's new.

Honestly this just comes off incredibly stupid and Hickey quite clearly shows
he's never programmed in a language with a type system more powerful than C++
or the likes. One of THE BIGGEST advantages of a powerful system is exactly
maintenance. He makes the straw man that you have to pattern match every place
you lead a type through in your code base, and that you can't "not care" about
certain parts of the constructor, but that is just so incorrect. He was half
onto the point of, with the compiler telling you all the places you'd have to
refactor thought. And that IntelliSense is the only thing he seems to come up
with as valid arguments for types...I think that says more about his
understanding of types than anything.

I'm gonna leave the rest of the comments up to the discussion I posted in the
top, else I would just be rehashing it.

~~~
carljv
As someone who really likes Haskell, I've found the response to the talk from
Haskellers, like in that thread, really disappointing. The common refrains
indicating that Rich doesn't understand Haskell, types, etc. are patronizing
and likely incorrect. (I realize he's trying to hit a few targets, from C++ to
Java to Haskell in one go, so it's not always clear which he's complaining
about.)

The other response I see is that if he were only aware of feature X (mostly
row polymorphism), then that solves his issue. Often feature X is some
immature Haskell extension, or exists in research or still niche languages. I
don't think switching to Purescript is going to solve more than one of his
issues, if even that. And the last thing I've seen is a bunch of folks trying
to torture the crap out of Map to prove him wrong (not really) about some
offhand point or another.

By and large I've seen a lot of (pedantic) sniping at specific phrasings
without much attempt to grapple with the larger points.

The casual dismissiveness of users of dynamic languages (programmers use them
because "dynamic types are easy" says one commenter -- about a talk from a guy
who has famously thoroughly dissected the notion of "easy.") along with the
inability to actually engage with the broader ideas has kinda turned me off
the Haskell community.

Lastly, it seemed clear to me from the video and transcript that he was saying
performance optimization, not (just) Intellisense, is a clear win for static
over dynamic types. And "Intellisense" is kinda just a shorthand for static
analysis generally. Again, the point is not that types don't have benefits,
its that those benefits come with costs. I think Haskellers often underplay
the costs associated w/ dealing with the type system, underestimate how little
reach the type system has in an open system where data's flying around
arbitrary services, and overstate how much preventing internal inconsistency
bugs solves all problems.

I like Haskell, OCaml, F#, etc. I think they make a lot of hard things simpler
and help me reason about certain programs better. But they're not panaceas.

~~~
Tehnix
> As someone who really likes Haskell, I've found the response to the talk
> from Haskellers, like in that thread, really disappointing. The common
> refrains indicating that Rich doesn't understand Haskell, types, etc. are
> patronizing and likely incorrect. (I realize he's trying to hit a few
> targets, from C++ to Java to Haskell in one go, so it's not always clear
> which he's complaining about.)

I can see why you would feel that, if you hadn't seen Hickey's talk, being
having seen it he was honestly quite patronising himself towards static
typing, so no wonder he would risk getting some of the same tone back. That
said, I don't think it is far off to say he doesn't understand Haskell, either
that or he deliberately ignores the solutions that Haskell offer to the
problems he's complaining about. Also, one commenter from the thread
mentioned,

    
    
        I do know from interviews that he's done (MS Channel9, i think it was) that he has at least a passing familiarity with Haskell as of 5-10 years ago, but that's a completely different beast to what exists now
    

Including he himself mainly focusing on having been a C++ programmer.

> underestimate how little reach the type system has in an open system where
> data's flying around arbitrary services

There are certainly times when dynamic programming is nice and all, but I feel
your statement is quite disproven with e.g. something like Haxl and Facebooks
spam filter, which is an incredibly large scale open system, unless we have
some different definition of that.

Finally, I agree Haskell and the like are not panaceas, but when a person goes
out with incorrect/invalid points talking down about the effectiveness of a
system, when in fact the users of it would agree it is highly effective, I
feel like it does no benefit to the community to simply let it stand just
because the person speaking is someone kinda famous.

~~~
carljv
> I feel like it does no benefit to the community to simply let it stand just
> because the person speaking is someone kinda famous.

That's not really what's happening. As I explained in my comment, I've found
the technical rebuttals by Haskellers to be lacking.

Yes, of course Haskell can be and has been used to make large, high quality
systems. I can say the same for C++. That doesn't mean there aren't costs
associated with those languages, and good reasons why someone might want to
make different decisions about how to design a language. This is literally
what the talk was about: why Clojure was designed the way it was. Not why
Haskell is a bad language (it's a great language), but why Clojure was
designed differently. Pretending like the type system has no costs and only
benefits is not serving the Haskell community well.

> I can see why you would feel that, if you hadn't seen Hickey's talk

Not sure what this comment is. I've clearly seen the talk. This pattern of
assuming someone who disagrees with you must have less information is off-
putting.

What I'm taking away from Haskeller rebuttals is: Haskell has solutions to all
your problems, if only you're smarter than Rich Hickey. This is not, to me, a
compelling sales pitch.

~~~
tome
> What I'm taking away from Haskeller rebuttals is: Haskell has solutions to
> all your problems, if only you're smarter than Rich Hickey. This is not, to
> me, a compelling sales pitch.

As one of the Haskell rebutters, let me give my point of view.

Firstly, "Haskell has solutions to all your problems" is a perfectly good
overstatement of the case. No need to bring Rich Hickey's intelligence into
it.

Secondly, Haskell gets you at least _quite far_ towards Hickey's goals.
Haskell _does_ have solutions, or at least partial solutions, to all of the
problems Hickey raises. Where the Haskell support is particularly weak, for
example with row types, we've admitted that. Yet neither he nor his proponents
here have shown any understanding of the Haskell (partial) solutions. If he or
they had said "I know about all this great stuff, parametric polymorphism,
generics, Dynamic, -fdefertypeerrors, ... but it still doesn't get you close
to Clojure because of <specific reasons>" then he would be presenting a useful
argument. As it is all we can do is disabuse Clojurists of their basic
misunderstandings of how Haskell works.

Am I being hypocritical? After all, I do not know the intricacies of Clojure.
But I'm not the one up on stage being filmed making claims about a language I
don't seem to be familiar with.

~~~
carljv
I get why the tone of the talk is ruffling feathers. If I were a serious
Haskeller, I think I'd be a little miffed too. But I think it misses the
forest for the trees, and I think, as I commented before, it's hard to
understand the context of his issues without understanding his interest in
systems. So I get why a lot of rebuttals have been focused on his somewhat
glib representation of certain features, but it's still a little frustrating,
because I don't think it's a particularly interesting debate.

I also don't think he referred to Haskell specifically at any point, and
really just spoke about algebraic type systems generally. It wasn't in the
scope of the talk, and I don't think it'd be a very interesting talk, to
compare Clojure and Haskell features. I bet he thinks Haskell is a great
language. Clojure takes a lot of inspiration from Haskell: default
immutability, core seq functions that look like Data.List; STM, etc. There
probably wouldn't be Clojure without Haskell. His whole point is that types,
like any other design feature, come with costs. They can be quite heavy and
constraining compared to their benefits in certain contexts, and that may not
be worth it.

That being said, I don't think it's a compelling rebuttal to say: "If you use
Dynamic and fdefertypeerror, Haskell addresses his issues." You'd be run out
of town writing Haskell code like that.

Re. parametric polymorphism, he explicitly talks about parametricity, and his
take seems to be that he doesn't find parametric types that useful for
conveying information or guaranteeing interesting things (to him) about your
program. I think he's exaggerating, but I get that it's a response to a lot of
breathless advocacy about how informative type signatures are.

Again, regarding his tone in the talk, I get it. But I think this should
provide Haskellers a good opportunity to examine how casually dismissive they
are of other languages, especially dynamic ones. IME, statically typed FP
proponents are much more dismissive of dynamic languages than dynamic language
proponents are of types. It's often "Your language is unsound garbage for lazy
programmers" vs. "Sometimes the type system becomes an overly-complex
constraint on my problem."

As someone who does like types, I'm nonetheless glad that there are folks
designing sound dynamic languages and arguing for their usefulness.

~~~
danwilsonthomas
Part of the reason why I personally was so upset by the talk was that it felt
as if there was no room for discussion or debate on the points raised. In
addition there was what felt like a lot of sniping towards features of
statically typed languages that felt designed just to get a reaction from the
crowd. The fact that there was an entire slide designated to tearing down a
series of videos by SPJ felt not only irrelevant, but also disrespectful.
There seemed to be a lack of willingness to meet halfway and concede there was
_anything_ useful from the other side.

Perhaps most frustratingly, I know that RH is capable of much better, much
more informative presentations. There might have been something worthwhile in
here, but the tone, style, and majority of the content didn't make it worth
digging out in my opinion.

Regarding Haskellers' attitudes, I'll add that I haven't seen anything like
what you describe at least on the Haskell subreddit. It could be happening in
other forums but by and large it's been a welcoming community even to those
that come in skeptical.

~~~
carljv
It's a keynote talk, not a panel discussion. Most keynotes are expressions of
strong opinions.

> The fact that there was an entire slide designated to tearing down a series
> of videos by SPJ felt not only irrelevant, but also disrespectful.

From the transcript:

"Simon Peyton Jones, in an excellent series of talks, listed these advantages
of types." ... "And I really disagree just a lot of this. It's not been my
experience."

How is that tearing down or disrespectful? I get there were a lot of glib bits
in the talk, but as you point out, he's talked about these issues with more
nuance at other times. It's a shame that hyper-focus on a couple of thrown off
jabs at the costs associated with types is distracting folks from the very
useful larger point he's discussion about levels of problems in programming,
contexts of programs, and how languages that impose strong opinions about how
to aggregate information can be counterproductive.

I think the Haskell community is, overall, very good and welcoming, but
smugness does creep in a lot, IME. But if you want to talk about meeting
halfway, I find that it's much less common to see static FP folks concede any
benefits of dynamic languages (besides that they're "easier" in a kind of
condescending way).

------
flavio81
> _I mean, why was I unhappy as a programmer after 18 years and said, "if I
> can't switch to something like Common Lisp, I'm going to switch careers".
> Why am I saying that? I'm saying it because I'm frustrated with a bunch of
> limitations in what I was using._

> _So, when I discovered Common Lisp, having used C++, I said that, "I'm
> pretty sure to the answer to this question is, 'yeah, absolutely'". And can
> we do that with a lower cognitive load? I also think, "yes, absolutely". And
> then the question is, "can I make a Lisp I can use instead of Java or C#?".
> Cuz you just heard my story, and I used Common Lisp a (?) couple of times,
> every time it got kicked out of production, or just ruled out of production,
> really not kicked out, it didn't get a chance. So I knew I had to target a
> runtime that people would accept._

Poor Rich Hickey, he wanted to escape C++, Java and C# and rather use Common
Lisp, but his employeers wouldn't accept it. Thus he invented Clojure, and now
he can't escape Java, because, sadly, Clojure itself and its libraries are
very coupled to the Java libraries and the JVM. Clojure makes really easy to
invoke Java classes and methods; thus, rather than creating a comprehensive
Clojure standard library, the choice was to mostly just use the Java
libraries. Thus, migration to another VM (like the CLR runtime) means that a
big amount of the Clojure code that runs under the JVM does not work anymore.

Clojure is very coupled to the JVM even in it's choice of keywords, for
example an "atom" in Lisp has a very different (and traditional, established)
meaning than an "atom" in Clojure, which is _directly_ tied to the
java.util.concurrent.atomic class.

Mind you, i am glad Clojure exists; next time a customer wants a project that
should (or needs) to be heavily integrated with existing Java/JVM code, it
would be my first choice; in fact, I pitch Clojure as a #1 alternative to
Java. But the coupling to the Java and JVM is a problem.

~~~
james-mcelwain
I'm not a fan of Java, but the JVM is an incredible piece of software that
centuries of man hours have been spent optimizing. And while Java might not be
a pleasurable language, the enterprise masochists have written millions of
lines of battle tested code in libraries. The deployment and monitoring model
for the JVM is very well understood, which means Clojure is uniquely
positioned to be introduced into large organizations.

~~~
flavio81
I agree with you (and i'm surprised at people downvoting my post). Thus, i
repeat: Clojure is an excellent (and for me, preferred) alternative to Java on
the JVM. However i would have liked to see it progressing into a language
where you could have the same code run without changes on many platforms -- at
least the JVM, CLR, LLVM, and if possible the javascript engines.

------
nu-world-odor
Every time I try to start with Clojure I find the syntax jarring and go back
to LISP. Clojure is Not about me though, is it? ;)

