
Clojure and the technology adoption curve - Ernestas
http://blog.juxt.pro/posts/clojure-curve.html
======
nickbauman
It is a myth that you have to be a genius programmer to pick up Lisp dialects
like Clojure. I think it's the opposite: the cognitive load of more complex
languages that are "easier to learn" than Clojure (like Scala or even Java
itself, for instance), a complexity I consider accidental and not essential to
whatever problem you are solving, is more difficult.

The hard part of Clojure really boils down to one thing: _you do not have an
assignment operator._ If you realize you must now program without that, how
would you do that? Answering that question in concrete cases is your only real
problem.

Other things, like the parens, well, you stop even noticing them after your
first few hours. When you first start, just move the paren _one word to the
left_ from where you're used to and you're good to go. The syntax after that
is so simple, you will find it liberating.

~~~
falcolas
The tradeoff for anything "simple" is that you are then left to pick up the
pieces (with libraries or your own code) if you want to do anything "complex".

As an example: C doesn't have the complication to the language of having
"built in" types for hashes or lists. This makes the language easier, since
you don't have to learn the extra syntax and grow the mental model of how they
were implemented. On the other hand, if you need a hash or list - you need to
create your own (or adopt someone else's implementation via a library).

C is a simple and powerful language, but there's so much you have to do
yourself, that it's easy to get something wrong.

Clojure (and lisps in general) hide their complexity in macros. This level of
abstraction can be great, until you have to dive into the macro and see
exactly how it's manipulating your code. Or write your own and troubleshoot
the resulting dynamic code.

~~~
nickbauman
The tradeoff you're referring to is summarized "Powerful but doesn't provide
much." JavaScript comes to mind. This is not the case with Clojure. Most
macros are basic and straightforward. Their power is, of course, unparalleled
in other languages feature sets. With great power comes great responsibility,
eh? And you don't have to use macros. Not that much is implemented in macros.
I think you have some valid insights but you may be overstating your case.

~~~
falcolas
> This is not the case with Clojure.

Well, it actually is the case, it's just that they've built out the core
library with a ton of functionality; intermingling the actual Clojure keywords
(there's only ~17 of them) with the convenience macros and functions built up
from those two primitives. Someone wrote all of those functions and macros.
Hundreds of functions and macros were built by the language creators to give
the functionality of a complex language.

> Not that much is implemented in macros.

74 of the functions exposed in the core api alone are macros. Perhaps the most
often used one is "defn" (and somewhat ironically "defmacro").

~~~
astine

        intermingling the actual Clojure keywords (there's only ~17 of them) with the convenience macros and functions built up from those two primitives.
    

It sounds like you are drawing a distinction between the core Clojure language
and the macros and functions in the core Clojure namespace. This is not really
a valid distinction. That's the thing about Lisps, that much of the language
is implemented in the language itself. Macros make the language easier to
extend by both the language designer and random developers and users in
appropriate cases. You can keep special forms to a minimum. Those those
functions and macros are considered part of the core language even if they
aren't special forms.

------
evgen
Probably worth noting that a lot of the companies with an interest in Clojure
cited as Early Majority are simply non-Clojure companies that picked up an
Early Adopter startup as an acquisition and need to continue development and
does not necessarily represent greenfield Clojure development at that company
(I know this for a fact regarding one of the companies cited on the list,
suspect the same for a few of the others.)

While Clojure foundered a bit after its start in the race to become Java.next
I think that what has ended up saving it, or at least given it new life that
it really needed, is a particular combination that is not even mentioned
anywhere in the article: Clojurescript and React wrappers like Om and Reagent.
I know more people considering Clojure(script) as a path to a combined web app
and mobile app (via React-native) than I do people looking at Clojure to power
the back-end.

~~~
pjmlp
Here in Germany I only see Clojure ads in relation to big data startups[0].

Very seldom do classic companies ask for anything other than JavaScript on the
browser or Java on the JVM.

[0] Same applies to other FP languages on the JVM.

~~~
talloaktrees
It's same same in the US outside of SF and NYC

------
mark_l_watson
A long while ago I wrote a Java book [1] (my usual cookbook style) and decided
to also support Scala and Clojure. It was so very much easier writing Clojure
wrappers than Scala wrappers.

Java and Clojure mix very well in projects: set up a separate Java source path
and let lein build everything.

[1] you can grab a free copy at
[http://markwatson.com/opencontent_data/book_java.pdf](http://markwatson.com/opencontent_data/book_java.pdf)
\- it is my Java Semantic Web book.

------
PaulHoule
In my mind you are not leaving OO behind when you get into Clojure, but the
big conceptual challenges revolve around doing things in an immutable way. It
is obvious how to do some things and not to do others.

~~~
pjmlp
One cannot leave OO behind in a language that by definition, supports OO via
protocols and multi-methods.

~~~
ddellacosta
How are protocols and multi-methods OO?

~~~
pjmlp
Multi-methods are how Lisp based languages have done OO since the early days.

LOOPS in Interlisp-D, here for a time travel to Xerox PARC.

[http://www.softwarepreservation.org/projects/LISP/interlisp_...](http://www.softwarepreservation.org/projects/LISP/interlisp_family/)

Check the "LOOPS, A Friendly Prime" book.

Meta-methods are at the core of CLOS, Common Lisp Object System, made famous
with the "The Art of Metaobject Protocol" book.

[http://www.amazon.de/The-Metaobject-Protocol-Gregor-
Kiczales...](http://www.amazon.de/The-Metaobject-Protocol-Gregor-
Kiczales/dp/0262610744)

They are also used by Dylan, the Lisp with Algol like syntax developed by
Apple,

Protocols provide the same type of polymorphism offered by Objective-C
protocols, Java/C# interfaces, Go interfaces, ...

Many mainstream developers might only know one way of doing OO, but back in
the day we could choose between Smalltalk, Lisp, Beta, Eiffel, Sather, C++,
Modula-3, Oberon, Component Pascal, SELF, .....

Each had their own view how encapsulation, polymorphism, message dispatch,
type extensions should take place.

So it is kind of funny to have some in FP languages bashing OO, while
successful FP languages are actually hybrid. At the same time having people in
teh OO side bashing FP, while their languages keep absorbing FP concepts.

Eventually we will get back to Smalltalk and Lisp, which already provided both
ways in the late 70's.

~~~
hellofunk
But protocols and mulitmethods are different from OO in the sense that the
functions are decoupled from the state. You don't store state in a protocol,
you just define an interface. That's pretty different from the way most people
think about OO in c++, java, swift, objective-c, etc. In Clojure, you have
Records and maps, which hold your "state" or your values, and you have
protocols which define your functions, and the two are isolated from each
other and not attached in any way. That's quite different from OO in general,
don't you think?

~~~
pjmlp
No, because there isn't one way of doing OO.

Just go read the Xerox PARC papers on how to do OO in Lisp, for example.

Back when OO was new there were multiple ways of how to do OO.

Some languages used the Smalltalk approach.

Others took the Simula approach where objects were an evolution of modules
that could be extend and manipulated.

And there were lots of other options scattered around OOPSLA papers.

What happens is that there are now a couple of generations of new developers
that didn't live through the procedural to object oriented programming
revolution, nor were doing their CS degree in those days, so many understand
OO as C++, Java et al do it and think no other way is possible.

The way Lisp does it, is quite common in the OO languages that offer multi-
dispatch in method binding.

Since all method arguments types are used in the method resolution, it doesn't
make sense to bind the methods to a specific object.

LOOPS and CLOS books/papers are pretty clear that they are doing OOP.

------
simula67
I am having a lot of trouble trying to understand the hype behind functional
programming. I have read McCarthy's paper on LISP, completed Odersky's course
on Scala etc. No revelation so far ( yes, maybe I am stupid, but I won't admit
it ). Is it only useful for study as a model that inspired modern programming
languages ? For example :

"obvious power of code becoming data."

Many languages have eval() where data can be treated as code.

~~~
dmichulke
Traverse a <String, Int> hashmap, remove all strings with an even key string
size and sort it by the last character in the string, then add the string size
to the integer (here you have a list of integers) and sum the product of the
numbers at index 0 and n-1, 1 and n-2, ...

Compare the the code size in Java and Clojure.

If that is not enough, do the same thing but start with java objects (and
their clojure equivalent: a hashmap) for some given object/map property.

EDIT: And if that is not enough, use as property of the object a string,
defined only during run-time by a user input.

~~~
nickbauman
Exactly this. The amount of code to do things is shockingly small.

When I was first learning Clojure I stumbled on a "lack of good documentation"
in third party libraries. I'd google around for something that solved the
problem I was trying to solve so I wouldn't reinvent the wheel. I'd find, say,
a github repo that had a couple of sentences in its README that purported to
solve my problem _and then nothing else._ What the hell, I thought; why no
decent doc? Then I realized: the solution was implemented in 40 lines of
Clojure. Reading the source was the fastest way to figure it out.

It still happens to me. Every time it does, I have this warm feeling of
investing in something of great value.

~~~
dmichulke
I also use several libraries that don't have a decent (or any) doc, just
docstrings in source code and I kind of got used to it now, or, as Emacs puts
it:

 _Code never lies, comments sometimes do_ (Charles de Gaulle)

------
msluyter
Let's say I'm sold on Clojure (I am; I think it's awesome) and I want to
convince my boss to convert a crufty Java 7 enterprise app to a better
alternative. What is the argument for Clojure compared to, say, Kotlin? How
difficult is a complete conversion to Clojure compared to other JVM
alternatives. My guess, in terms of ease of transition:

    
    
      Java 8 > Kotlin > Scala > Clojure
    

That's just my impression, especially if you're risk averse and want to make
improvements as incrementally as possible. But I could be wrong. Anyone have a
good counterexample?

~~~
astine
Clojure's strongest selling point as compared to other JVM languages is
probably its concurrency story. If your enterprise app is of any sort of size,
you've probably run into concurrency related bugs.

Another strong advantage is the development lifecycle. It's much tighter
thanks to the live coding built right in. This should make it much faster to
catch bugs or feel out new code. You can also use this to implement zero-
downtime deploys and patching.

