
Clojure/Conj 2017 – Opening Keynote by Rich Hickey [video] - kasbah
https://www.youtube.com/watch?v=2V1FtfBDsLU
======
hellofunk
No one in this thread is yet talking about the content of this talk, which I
think is interesting. Rich is doubling down on dynamic typing. As the world is
gradually moving to more statically-typed languages (Rust, Swift, Go, Elm,
Purescript, Typescript are all popular tools that come to mind), Clojure
remains in the embrace of dynamic typing, and this talk is an interesting look
at the perspective of why that is, and adds perhaps a little bit to the debate
between static and dynamic typing.

I admire Rich a lot, but I also admire John Carmack, and it is apropos that
yesterday another comment was shared on another post here [0] about _his_
opinions on static typing, and how in just a few years (his talk was in 2013),
the industry as a whole has made considerable changes in its opinions of
static typing; according to his talk, in 2013 most of the industry was still
not convinced of the benefits of static typing.

[0]
[https://news.ycombinator.com/item?id=15460604](https://news.ycombinator.com/item?id=15460604)

~~~
kenshi
I think its a mistake to directly compare the experiences (and conclusions) of
these two exceptional programmers.

Rich Hickey explains at the start of his talk where he is coming from, what
the context of his development work, and he calls it "Situated Software". His
background and the context for his development is building information systems
in organisations where the rules are messy and no doubt change often. One of
the things he calls out explicitly in his talk is the messiness of dealing
with the "Two for Tuesday" rule in one of the systems he worked on. He also
spoke about how different working in that domain was, to doing compiler
development.

John Carmack's experience and domain expertise is building high performance
game engines. I'd argue this is closer to compiler writing in the sense that
it is a much more rigid problem than say having to serve the needs of an
organisation whose requirements may change often and in seemingly arbitrary
ways, and usually on a tight deadline.

I am not trying to elevate one domain over the other. They are different kinds
of problems, and have different kinds of limitations and constraints applied
to them. As such I don't think its any surprise that the priorities for each
of these developers is different.

Choosing between more dynamic or more static approaches without considering
the context in which you are working in, is a mistake.

~~~
mightybyte
This is an outstanding point. When watching this talk, I got the distinct
impression that Rich has simply worked on a very different class of problems
than the ones I have worked on. As we all are wont to do, we extrapolate our
experience to the whole universe. But that's not always the right thing to do.

I would say that for the most part, a statically typed language can do the
same things a dynamic language can do, but not the other way around. Another
commenter mentions the Any type, but I don't think that's it. It's maps. Rich
wants to be able to combine maps with a union operation, take subsets of keys,
etc. And that is exactly what maps afford. I'd rather work in a language like
Haskell where I can use strong types when I need them and drop down to untyped
maps when I need them than a language like Clojure where all I ever have is
the maps.

Another thing static types do for you is that they make things in your
application more discoverable. Instead of tracing through to figure out which
data is available and operations something supports, the compiler tells you.
I'd rather work in a language where my compiler can help me this way than in
one where it can't.

~~~
weavejester
_" a statically typed language can do the same things a dynamic language can
do, but not the other way around"_

It's interesting you'd say that, as I'd consider the opposite to be true.
There are functions that are trivial to write in a dynamically typed language,
but are hard to statically type. For instance, the `assoc-in` function in
Clojure.

 _" Another thing static types do for you is that they make things in your
application more discoverable. Instead of tracing through to figure out which
data is available and operations something supports, the compiler tells you."_

You don't necessarily need static typing to give functions some form of type
signature or specification.

~~~
flavio81
I also find the opposite to be true, as you do.

The human mind and human problems, operate more like a dynamic language. To
put it in a simple, silly example: When i tell you to "cut something with a
scissor", the scissor doesn't specifically cut paper; there are many things
that can get cut by a scissor. Or when you take a pot, put it over the stove
and boil water, you do it and the pot is not specifically designed to boil
water, the pot can heat anything; so you can say that many operations (verbs)
in real life do not get performed in a "static typing" way, but in a "dynamic
typing" or at least "duck typing" way.

~~~
bbatha
Both of those examples are trivially modeled with typeclasses (java style
interfaces will also cut the mustard here too).

Your paper example I would have a “Cutter” and “Cuttable” type classes to
describe things that cut and can be cut. In languages like Haskell this only
involves a couple extra lines of ceremony over writing a “cut” method on each
type.

The pot example is even cleaner with types and show the power of them. I’d
have a Pot typeclass that can heat things. I’d have a liquid class for all
liquids that water implements and finally a boil free function that takes a
pot and a liquid. Exactly as expressive but now with compile time checking.

~~~
dragandj
All this is covered in Rich's talk. Your Cutter and Cuttable are different
from my Knife and Cuttablito. When your program needs to talk to outside
world, it all becomes messy.

------
platz
> "SPJ in an excellent series of talks lists these advantages of types... the
> biggest thing left out of clojure..."

> "The biggest merit he says is in software maintenence, and i really disagree
> with just a lot of this. it's not been my experience; the biggest errors are
> not caught by these type systems; you need extensive testing to do real-
> world effectiveness checking."

I think Rich is dead wrong on types not providing good tools for _software
_maintenance__.

He is attempting to discredit types because they do not catch _all_ errors, or
the toughest errors; that's fine, I don't agree with people that would say
types do that for you.

I think dynamism is great for speed of development and flexibility; but my
impression about trying to debug and maintain clojure code is that one has to
spend time tracing back the source of errors and shape of maps (pre-spec).

Those issues are somewhat mitigated by having a good type system, and what you
loose on the flexibility going with types, is a trade that I think returns
much more that what you give up.

~~~
flavio81
> _" The biggest merit he says is in software maintenence, and i really
> disagree with just a lot of this. it's not been my experience; the biggest
> errors are not caught by these type systems; you need extensive testing to
> do real-world effectiveness checking."_

I think I fully agree with Rick Hickey on this, and I have mentioned the same
before here in HN. The biggest and most serious errors are not caught by the
(statically checked) type systems.

I agree that simple type errors that, on a dynamic system without compile-time
checks are not caught, will be then caught at runtime and you will say "oh, i
need to get back and correct this, damn it". But this is a minor annoyance,
that takes small time compared to the bugs i'm mentioning in the previous
paragraph; bugs that can take days to be resolved.

~~~
runT1ME
What kind of errrors do you think are not caught with static typing? Usually
people who say this aren't familiar with languages that have type classes...

~~~
flavio81
> _What kind of errrors do you think are not caught with static typing?_

Citing awj's post above:

 _" Some of the biggest errors are subtle failures in the implementation of
business logic."_

Other examples:

\- bumping into unkonwn bugs of a library you are calling \- implementation of
an external (library) function behaving differently than the documentation \-
various memory leak problems \- locking issues \- race conditions

etc

~~~
runT1ME
>"Some of the biggest errors are subtle failures in the implementation of
business logic

Static typing can prevent errors in business logic.

>various memory leak problems - locking issues - race conditions

All are bugs that static typing has had tremendous success in preventing. Have
you any experience in a HM like type system?

~~~
flavio81
> _All are bugs that static typing has had tremendous success in preventing._

Please do elaborate, it could be a great post.

But If you mean to say that locking issues can be prevented because you can
apply STM (software transactional memory) by using suitable Monads, then,
well, i can also have STM in a dynamic language, even applying it by wrapping
code in an "atomic" context (i.e. see the STMX library for Common Lisp) so the
statements contained within are performed atomically (and thus guaranteed to
work or either roll-back.)

As for memory leaks, Haskell (if that's the HM language you had in mind)
automatically manages memory, so I would guess this isn't a problem at all.
However, automatic management memory management is orthogonal to "static vs
dynamically typed".

Thus, i'm curious, and yes, i don't have enough experience with HM-type
languages, which should be the way to go if one wants to use static typing...

~~~
tome
> i can also have STM in a dynamic language

How can you roll back failed transactions without explicitly typed effects?

~~~
platz
Clojure tracks and rollbacks the STM-bound variables according the STM rules;
it is not intended to prevent you from doing other effects inside those
transactions; you are supposed to have an understanding not to do that in the
transaction blocks.

It helps a bit that most clojure datastructures are immutable/persistant by
default.

~~~
tome
In other words Haskell's STM prevents bugs that Clojure's merely supposes the
programmer not to have written.

------
kasbah
I submitted this link before I had watched the whole thing. As someone who has
only dabbled in Clojure I think there are a lot of interesting ideas in there
but found the type-system bashing pretty off-putting.

I am now watching his "Simple Made Easy" talk [1] after I have heard it
recommended on a few functional programming related podcasts. Again really
interesting stuff but I encountered another cheap shot at typed functional
programming ("You can't use monads for that! Hurr hurr hurr").

Given how well received these talks seem to be by people that enjoy
programming with advanced type systems I would have have really expected a
more balanced discussion and some acknowledgement of the trade-offs between
dynamic and statically typed functional programming.

[1]: [https://www.infoq.com/presentations/Simple-Made-
Easy](https://www.infoq.com/presentations/Simple-Made-Easy)

~~~
hellofunk
The new Conj talk is certainly an interesting look at one man's (or one
community's) look at static typing. However, as much as I admire Rich, some of
the points he made don't resonate with me, particularly the one about how
compile-time checks to catch minor bugs in syntax are not a particularly
useful feature of static typing. I certainly disagree. As someone who writes
Clojure all day long right now for a living, I am constantly dealing with
runtime errors that are due to minor typos in my code that I have to track
down, and this time would be greatly saved by having a compiler tell me "on
line 23 you looked for :foo keyword in a map but you meant to type :foobar, so
that's why that was nil" and many other similar woes.

I love Clojure but I really miss static type checks.

The other item in his talk I do not agree with, he says (slightly
paraphrasing) "in static typing, you can pattern match on something 500 times
but if you add a case, you have to update those 500 matches to handle the new
case, when really they don't care about this new case, only the new logic
needs to consume this special case, it's better for the producer to speak
directly to the consumer". Well, in languages like OCaml, Swift, Haskell, it
is a feature that pattern matches much be exhaustive. This prevents bugs. In
most cases, I'd expect that if I add a case to an enum, the chances are good
my existing logic in pattern matches should know about that. Maybe not all,
but a lot of them will. It's nice to have the compiler guide you to those
places.

I certainly like how fast I can write programs in Clojure, and I like the
minimal amount of code that makes refactoring and rewriting fairly
straightforward since there is not a lot of time investment in the existing
number of lines, and I like the incredible elegance of Clojure's approach to
functional programming.

But I do miss having much greater compiler assitance with typos, mis-typed
argument order to functions, mis-typed keyword names, etc. Would really save a
lot of time.

~~~
keymone
> As someone who writes Clojure all day long right now for a living, I am
> constantly dealing with runtime errors that are due to minor typos in my
> code that I have to track down, and this time would be greatly saved by
> having a compiler tell me "on line 23 you looked for :foo keyword in a map
> but you meant to type :foobar, so that's why that was nil" and many other
> similar woes.

i wonder if this is because it really takes a quantum leap in one's
development style between <insert your previous programming language> and
clojure/<insert your favourite lisp>? as long as your environment allows for
effortless evaluation of code you're writing, you'd be getting this feedback
no slower than the edit/save/compile/retry cycle.

~~~
hellofunk
If your typos are triggered by UI events, then you often won't see these
problems until interacting with your UI (I work mainly in Clojurescript).
Further, these typos may not get noticed at all for a long time if a code path
is never taken. Of course, that's what unit tests are for. But writing tests
takes time also. I'm not sure it's worth the trade off to spend the time
writing those tests that I could spend writing in a more statically-typed
language that would catch some things that tests wouldn't be needed for.
(Besides, writing tests for UI stuff is pretty hard).

I am griping, really, because I cannot stress enough how nice it feels most of
the time to write Clojurescript. But in complex projects, there is not doubt
that a lot of time gets spent on things that wouldn't need to be spent if the
language had even a very basic type system to back up the syntax for some
things.

~~~
christophilus
My team recently settled on TypeScript instead of ClojureScript, as TS is the
safer bet, more familiar, more consistent with the existing project's tooling,
etc. But man... I've taken a handful of files and written them in both TS and
CLJS. CLJS is just so much shorter and elegant. I sometimes think we made the
wrong decision.

~~~
athousandcounts
ClojureScript is great with Reagent or re-frame... If you write Angular use
TypeScript. If you use React, ClojureScript! It's a match made in heaven.

~~~
christophilus
Yeah. I've built toy apps with re-frame, and really liked the way the code
looked. But my team is pretty Jr other than me, and I wasn't sure if
ClojureScript would work well for us as a team. VS Code is our editor of
choice, and it is just really a good environment when paired with TypeScript.

Also, my experience with Rails really has me fearful of doing any serious, big
work, in a dynamic language.

------
whalesalad
Rich is always a great speaker. Sometimes he gets a little esoteric and you
hear all the monad loving neck beards giggle in the audience. Then again, he
invented a lisp that runs on the JVM. Usually though he is very pragmatic and
real-world. I love how often he says things like “the type checker in my
compiler doesn’t matter to the users of my program” or, “the perfect, most
beautiful search algorithm doesn’t matter if it can’t fit into a web page and
work when your user hits enter”

So... even if you don’t care about Clojure or functional programming I’d
certainly suggest listening to some of Rich’s talks. He’s a very sharp guy but
his format is very friendly.

------
amrrs
I have been to a local Clojure conference once. Most of the guys who started
practising Clojure was inspired by Rich Hickey's functional programming talks.
I'm wondering how many such BDFL inspire users to adopt something new just
with talks!

~~~
iLemming
I didn't even know about Rich Hickey talks and "Simple made easy" when I
decided to start learning Clojure. I came to conclusion that I needed to learn
a Lisp after learning Emacs and dubbing in writing small elisp functions. I
had no idea and was really surprised when I found out how awesome Lisp can be,
so I looked at the current state of Lisp at the time. And then after learning
a bit of Clojure and Clojurescript and seeing things people were building with
it, I quit my job. I really wanted to use Clojure full-time. Never in my life
I ever before have had this urge to learn a language and build things with it.

------
keymone
are people without a degree in type systems even allowed to express their
opinion on dynamic vs static? because if their opinion is automatically viewed
as inferior whenever a person with a degree chimes into a discussion, isn't
dynamic typing stuck in the limbo of not having competent defenders and the
only path for a defender to become competent is to spend years of their lives
learning the opposite thing?

i think (as a person without a degree in type systems) that relative success
of Erlang and Clojure are a testament that pragmatic approach works, and that
is not in any way evidence that static typing is inherently bad or can't work.

~~~
cutler
Relative success? In what sense? As far as the jobs market is concerned
Erlang/Elixir and Clojure have failed to make an impression. Ok, Wallmart,
Bleacher Report etc. but search Indeed.com by job title and you'll get what I
mean.

~~~
keymone
that's why it's called "relative", isn't it?

Erlang and Clojure are undoubtedly a success for me in terms of productivity.

Erlang is undoubtedly a success in a telekom industry since 90s, where extreme
reliability is a basic requirement. isn't static typing promoted as a path to
achieve reliability "once it's compiled"? go figure.

imo, that majority of developers are being indoctrinated into false-OOP
paradigm is rather unfortunate historical curiosity than a success indicator.

------
yawaramin
I understand that Rich Hickey is a fantastic developer, a productivity
multiplier, and an industry leader, but I have a few issues with his portrayal
of types.

In this talk he has repeatedly cherry-picked the most negative examples from
every type system, while ignoring the more positive, simple, and elegant type
system features. E.g., he talks about languages which represent product types
as `int * int * string * string * ...`, i.e. as nameless clumps of data, while
ignoring that those same languages usually support much richer record types
which are of course product types with field labels.

Then he talks about Java types being non-composable while ignoring generics
and row polymorphism in other languages. He talks about Clojure maps being
powerful while ignoring the same maps with the same power in static languages.
He talks about type system complexity while ignoring the mental burden of
keeping the types in your head in a totally dynamic system like Clojure.
Ironically, he even talks about how you can handle five to seven arguments
mentally before getting lost, while ignoring that in a dynamically-typed
system you're left to your own devices handling much higher cognitive loads.

Another beef I have here is he repeatedly talks about pattern-matching in 500
different places, and having to go and update them, while ignoring the fact
that _no one does that,_ we actually do write modular code with data
structures as abstract as possible and try to provide powerful, general-
purpose functions which manipulate them instead of exposing all the variant
cases for raw pattern-matching. PM is great, but it's still important to limit
its use for scalability reasons.

I don't know to what extent he has explored the type systems of ML-family
languages. But he certainly does not present them accurately here. I would
love to see him just do a debate-style talk with someone really well-versed in
type theory as well as practical systems, say, Yaron Minsky of Jane Street.

~~~
platz
Rich would probably do very well in a debate-style talk. The art of
argumentation is very subtle. If you think there'd be a blowout that entirely
discredits the dynamic typing camp—that would rather be like expecting a
debate that completely invalidates one side of republican/democrat debate.
There are simply core values each side has that are very hard to persuade
someone out of. mostly, what people do is "talk to their base/tribe", and then
snipe the other side with cheap shots.

~~~
yawaramin
I'm not even looking for a winner-take-all argument. I just want someone to be
able to immediately correct Rich when he says something wacky about static
typing. E.g.,

'You don't have labelled arguments!'

'You have labelled arguments since Standard ML i.e. _at least_ the '80s, e.g.:

    
    
        $ poly
        Poly/ML 5.7 Release
        > fun add { num1, num2 } = num1 + num2;
        val add = fn: {num1: int, num2: int} -> int
        > add { num1 = 1, num2 = 0 };
        val it = 1: int

~~~
christophilus
Yeah. He's aware of that. I think he's generally talking to Java crowds, so
the static typing experience of the general programmer is pretty bad.

That said, I liked this talk and agreed with much of it.

~~~
yawaramin
There are options on the JVM outside of Java, from Kotlin to Scala to Whiley
to Eta, or even OCamlJava which might be nearing a release. An alternative to
dismissing static typing entirely based on Java, is looking at other languages
which have less verbose, more elegant type systems on the JVM. RH is ignoring
that aspect completely. Understandable, based on his worldview and experience,
but not very accurate.

------
crispyambulance
Can we please get this man a Wikipedia page now?

[https://news.ycombinator.com/item?id=5619680](https://news.ycombinator.com/item?id=5619680)

~~~
sooheon
Wow that man Artem Karibov quoted in the link has some problems.

------
kimi
Any transcripts yet?

------
grabcocque
I always enjoy Rich's and Cognitect's increasingly futile attempts to bait and
switch the Clojure community into using his expensive proprietary database,
Datomic.

I love Clojure, it's a beautiful language, but its march has stalled, perhaps
even reversed, and I lay the blame of that squarely at the anti-community
practices of Cognitect, especially surrounding Datomic.

~~~
keymone
is anybody forcing you to use datomic? no.

is cognitect doing something to clojure that is beneficial exclusively for
datomic? no.

has cognitect banned you from making pull requests that improve clojure? no.

has cognitect banned you from forking clojure and fixing whatever you think
they've done with some evil intent? no.

so wtf are you on about?

~~~
geofft
> _has cognitect banned you from forking clojure and fixing whatever you think
> they 've done with some evil intent? no._

I don't understand this objection. The value in a free software project, and
especially of a programming language, is primarily in its community and the
expectation of a future around the project, not in the existence of some code
somewhere. It's extraordinarily hard to build a community around a fork, and
if you need to fork to do reasonable things, that's a legitimate criticism of
the people running the original community.

(That said, if you only need to fork to do unreasonable things, that's good
community management. I don't pay nearly enough attention to Clojure to know
what's actually happening - but I have seen both of these cases in other free
software communities.)

~~~
keymone
> It's extraordinarily hard to build a community around a fork

it follows quite naturally, that reasoning to fork doesn't have enough
community support, which only means one thing - you're wrong about clojure
community's opinion on state of things around clojure.

~~~
krisdol
Adding to that, there are a few forks of popular projects that were quite
successful: io.js, libreoffice, mariadb.

~~~
evilduck
Blink, Ubuntu, neovim, LibreSSL, Plex, XOrg, etc, etc.

If you're dedicated to it and correct about your choices, forking doesn't seem
to hamper anything.

