
Why I Switched from Python to Clojure (2016) - bsg75
https://www.bradcypert.com/why-i-switched-from-python-to-clojure/
======
hetman
It's interesting that the very things that attracted the author to Clojure was
what kept me from moving to it from Python.

I enjoyed the syntax. Loved the immutability. However, I wasn't able to
understand the structure of program data at a glance even when reading my own
code. The reliance on lists and maps everywhere meant that the structure of
data was encoded in the code of the functions that created it and sometimes
you had to go several functions deep just to understand the bit you wanted.

In Python if I'm returning a tuple that's more than 2 or 3 elements long, I
know that it's time for, at the very least, a namedtuple because I've had to
deal with code in the past that has mysterious 5-tuples etc that just becomes
too tiring to deal with.

To be clear, big collections in Python aren't a problem as long as the type of
the contained data remains uniform.

~~~
kevin_thibedeau
The fundamental problem with S-expressions is that they are intended for
(1950s) machine readability and human ergonomics takes a back seat.

~~~
iLemming
sure, because Sure, because this (taken from React's JSX example page):

    
    
        <DashboardUnit data-index="2">
          <h1>Scores</h1>
          <Scoreboard className="results" scores={gameScores} />
        </DashboardUnit>;
        

is more readable than this:

    
    
        [dashboard-unit {:data-index 2}
          [:h1 "Scores"]
          [scoreboard {:class-name "results"
                       :scores game-scores]]
                       

Please tell me more about Lisp readability.

~~~
doteka
For someone familiar with HTML/XML, so any developer in the last 30 years, yes
it is. Your point being?

I like the ideas behind clojure, I really do. I even wrote a non-trivial
personal project with it. However, coming back to that code after two months
was basically like the plot of Memento. I ended up rewriting it in JavaScript
instead.

~~~
profalseidol
Almost anything (if not all) requires one to put in years of practice before
one is adept. "a" non-trivial "personal" project probably won't cut it.

Comparing that to your 30 years practice of XML is not at all useful.

~~~
doteka
I didn't say anywhere I have 30 years of experience with XML. What I said is,
EVERYONE is familiar with the syntax. JSX is especially suited for expressing
HTML because it is, in fact, almost HTML.

As to your other point - maybe. I'm not seeing anywhere near enough potential
payoff to invest years into it, though. Also, I'd argue that makes it a
terribly impractical language if you're interested in getting work done.

To clarify, I don't agree one needs years to become competent in clojure. But
if one did, that just makes it a worse value proposition.

~~~
profalseidol
I'd rather work with Clojure than the monstrosity we make with our 30 years of
experience.

Sure you can get things done and ignore the maintenance horror later.

Anyways, in the 30 years we at least steadily transfer features from Lisp.

------
yingw787
My impression of Python is that it's a Fisher Price Little Tikes coupe with a
few GE90 jet turbine hardpoints mounted on it.

It's a very simple language. Literally when things get made to be complex
Guido says do it the simple way, because when unbreakable things break it's
just that much harder to fix. This makes it very easy to debug, very easy to
fix/patch, very easy to onboard new/junior developers in, and very easy to
start using in production. It's literally a baby.

But man, you can do some crazy things in Python if you want. You can write
C/C++ extensions sure. You can also use things like orchestration with `py4j`
and `jpype` in order to execute IPC with a JVM dedicated to the Python
process. In that sense all Python in your application becomes a request layer
with the JVM or a binary acting as the data layer, and request layers don't
require as much in performance because you only need to issue so many
requests. Request layers may also need to change faster than data
layers/pipelines, and in that Python's great because it's so flexible. Based
on some performance testing our team did there's absolutely no reason to
simply switch away from Python, though that may also be due to legacy reasons.

I'd like to stick to Python and maintain my Python proficiency going forward
(though with Guido out as BFDL we'll have to see how the language evolves).
I'd like to maybe add Rust or Elixir to my repertoire and see how they extend
my capabilities in ways Python/C/C++ may not. But Python will always be my
Swiss Army knife turned combat shovel. It gets the job done.

~~~
iLemming
Are you implying Clojure is not simple? Have you ever watched Rich Hickey's
"Simple made easy" talk? If you haven't, I highly recommend it. Disclaimer:
It's not about Clojure.

~~~
yingw787
I haven’t watched it, but I have heard about it. In contrast to the simplicity
of a programming language in the happy path, I’m talking more about simplicity
in the case where things break. For example, Python doesn’t implement tail
call optimization in part to eliminate stack trace collapses. On the other
hand, many reasons my current tool stops working is due to the underlying
configuration of the JVM. Configuration management is a leading problem in
distributed systems, and a fairly significant one given how it took down both
Google and Facebook in two days. Clojure is a lisp on the JVM; I doubt it
matters how pretty you write your code if you don’t say allocate enough memory
on the heap for the process, and if it implements tail call recursion when
that happens you may get an incomplete stack trace.

This is more speculation, but I do hope it gives some insights into why you
may choose one paradigm for a problem over another. Overall I’d say break your
problem domain into subdomains and choose the best paradigm for each.

~~~
iLemming
> I doubt it matters how pretty you write your code

Clojure it's not (just about) beautiful and concise code. There's a lot more
to it. And JVM in my experience is not a problem. I was skeptical at first,
but as it turned out - JVM is pretty stable and solid piece of tech. Besides -
there's also Clojurescript (and less popular Clojure CLR). Depending of what
you are trying to solve, you can go that route too. I may not convince you to
give Clojure a try, but please do yourself a favor and watch/read Rich
Hickey's talks. [https://changelog.com/posts/rich-hickeys-greatest-
hits](https://changelog.com/posts/rich-hickeys-greatest-hits) They are
perfectly applicable and do make sense even outside of Clojure context. Many
developers characterized those talks to be "eye opening".

------
Townley
I can, and do, appreciate opinions on languages themselves. But my decision to
continue using Python over Clojure is much less about the language's syntax
and more about the available libraries. How do Clojure web frameworks compare
to Django/Flask? What would I use instead of Pandas for data analysis? Are
there keras-like deep learning tools?

Switching languages based on a comparison of idiosyncrasies between the two
seems like moving to a new city based solely on the weather: a valid
consideration, but nowhere near sufficient.

~~~
soulnothing
I'd argue that the JVM is a good move from python. There are a number of rich
frame works on the JVM with great tooling. Also if you use PyCharm switching
IDEs is easy with Intellij. I switched from python -> F# -> Kotlin.

I do agree the language is part of the battle. The other is tooling, and
libraries. F#/dotnet was painful as a linux dev. The JVM works on almost any
platform with great tooling.

For Libraries. I haven't found anything akin to django admin, but I don't
really miss it. For me

SQLAlchemy -> Jooq

Flask -> Spark/Vertx

~~~
vips7L
I like writing Kotlin, but I feel like I'm still struggling with the
"functional" side it. I think I just like writing java too much.

------
Aeolun
Sometimes I read these pieces and I wonder how much of the joy of the new
language is just having become a better programmer in the meantime.

~~~
Insanity
At least for me, it definitely factors in. Getting a new perspective on
problems by using a language with a different toolbox (functional rather than
OOP for example) can help with future problems. And it's just good fun to
learn a new language just to challenge yourself a bit.

------
snrji
I have considered multiple times switching from Python to other alternatives.
However, I instantly discard any language with a Lisp-like syntax. I just
cannot work with it. Being a Haskell hobbyist, I would like Python to be
statically type and have better support for pure functional programming, but
Python has the libraries that I need.

~~~
jhhh
Every person that I've talked to that seemed to have a strong negative opinion
about parens never used it. They just think they won't like it but wouldn't
take the minimal amount of time to give it a try with something like paredit.
I was also in this camp for a long time until I figured I would give it a
serious try instead of disparaging something I had not used. You might
consider that creating and editing code with balanced parenthesis doesn't
actually require you to insert them manually when you have an editor that will
always keep the code data-structure balanced and makes structural editing
simple.

~~~
Syzygies
I've been using Scheme as one of my languages for a decade. (Haskell, Python,
Ruby, Bash are the main others.) I generally use a preprocessor for each
language. The Haskell preprocessor treats indented as code, flush as comments,
also supported by my syntax highlighting. Comment characters feel to me like a
thousand Hitchcock birds shat on my car. They're so easy to avoid. It also
introduces here docs; no language should be so full of itself that it can't
embed multiple lines of another language verbatim.

I've gone through several period of straight Lisp parens, and several periods
of using a preprocessor. I believe in committing to muscle memory before
deciding; I've oscillated back and forth between Querty and Dvorak, for
example. I'm more committed to psychological experiments than anyone who
claims the parentheses haters are newbies who haven't tried.

Study counting in higher mammals: One finds that "one, two, three, many" is
core to all of us, and higher systems are strapped on like the multiple layers
of vision mechanisms. Humans can't deal with the tiger tails at the end of
lisp expressions. But machines can? Yes, but machines can also handle inferred
parentheses. The complainers about parentheses complainers want off-the-shelf
support. Real programmers write their own support.

Lisp looks best with indentation to help infer parentheses. Use a pipe "|" to
open a parenthesis that auto-closes at the next ")" or the end of the line.
Use a dollar "$" (borrowed from Haskell) to open a parenthesis that auto-
closes when the indentation returns. Lisp written this way is stunningly
beautiful poetry, cleaner than any of the dozens of languages I've programmed
in. The remaining parentheses actually matter, so one pays attention to them.

I've spent years each way, back and forth. Inferring parentheses is better,
and one can write any tool to follow this syntax.

~~~
jiyinyiyong
You would be interested in my old project using `$` as a way for reducing
parentheses: [http://text.cirru.org/](http://text.cirru.org/) .

------
o10449366
I notice this was written in 2016, but I wonder if the author's opinion has
changed since dataclasses have been implemented in Python.

~~~
Scarbutt
The author switched to kotlin from clojure, kotlin's interop with java is
leagues ahead of clojure.

~~~
zeroDivisible
I do not have experience with Kotlin and it's interop with Java. Do you maybe
have examples or articles which you'd recommend on the subject?

~~~
fgonzag
[https://kotlinlang.org/docs/reference/java-to-kotlin-
interop...](https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html)

[https://kotlinlang.org/docs/reference/java-
interop.html](https://kotlinlang.org/docs/reference/java-interop.html)

[https://developer.android.com/kotlin/interop](https://developer.android.com/kotlin/interop)

------
GorgeRonde
If you allow me to compare my very limited experience with Python (hacking
SublimeText plugins) to my rather extended experience writing Java or Ruby
(i.e class-based languages that traditionally newline-&-deindent closing
parens rather than aggregating them in a trailing tiger tail like in lisps)
...

... I would say writing programs in Clojure leads me to writing 10 to 20 times
less code on average.

I recently rewrote 15000 lines of Java (several weeks worth of effort split in
several dozen files) down to 500 Clojure lines (in one weekend and one single
file).

Anyone else with that kind of experience ? To me this is a tremendous
advantage and any argument for code readability is really just argumentation
about reading code at a small scale (say one file) that unknowingly makes
trade off about reading code at bigger scales (say the readability of a whole
project).

------
UncleEntity
> ...the “implied self parameter” on python methods turned me off.

If I had a nickel for every time I got the "TypeError: random_function() takes
1 positional argument but 2 were given" because I forget the "self" parameter
I could buy myself a coffee. Probably a fancy one from the Starbucks even!

~~~
fiddlerwoaroof
I always thought this made sense: a method, considered as a property of a
class isn’t yet bound to any particular instance while, considered as a
property of an instance has an implicit parameter of the instance you’re
currently operating on: languages like Java hide this “this” parameter from
you by passing it automatically while python makes it explicit so you can form
a better mental model of what’s going on

~~~
zwp
The problem is that Python is the exception here. Those of us that learnt
other languages first already have a mental model and find this explicit self
parameter weird. And it's more typing.

Yegge thinks that "self" is a wart and I agree. The article is a fun read but
it's showing its age. I suspect Python might just have beaten Perl by now.

[https://sites.google.com/site/steveyegge2/tour-de-
babel#TOC-...](https://sites.google.com/site/steveyegge2/tour-de-babel#TOC-
Python)

I suppose Python's way there's one less reserved word. Are there any other
advantages?

~~~
fiddlerwoaroof
I also like how you can call the method on the class and pass self in
explicitly. e.g.:

    
    
        class Foo:
          b = 4
          def foo(self, a):
            return a + self.b
    
        inst = Foo()
        inst.foo(3)
        Foo.foo(inst, 3)
    

I haven't written python in a while, but I really like that python makes this
possible and obvious and I've found this behavior pretty handy when working in
a more functional style.

~~~
fiddlerwoaroof
Also, I find writing languages with an implicit self like Java, Kotlin and
Scala really irritating because there's nothing to distinguish access to a
locally-scoped variable or function from access to a class member. I've always
appreciated how, in Python, `x` always refers to something bound according to
Python's pseudo-lexical scoping rules while class members always have a
`self.` to make them stand out.

These days, however, I mostly write Common Lisp and Clojure which, each in
their own way, have explicit selfs: Common Lisp because it uses multiple
dispatch and, consequently, there isn't one "self" and Clojure's protocols are
designed to dispatch on the first argument, which is always passed explicitly.

------
doktrin
Willing to bet money the author switched to something else by 2017. For the
overwhelming majority of developers Clojure is this tinker toy we fiddle with
for 6 months to a year before getting bored and fed up with its limitations.

------
luckydata
I don't have a horse in this race but I find it interesting that in my career
I've seen a lot of bad code but the worst clusterfucks I've met where all in
Clojure while the community seems to be chock full of purists and in general
people that takes craftmanship seriously at least at face value.

¯\\_(ツ)_/¯

~~~
jonahx
"The worst injuries I've ever seen were in big factories with large, powerful
tools -- not in home garages where people just use hammers and hand-saws."

Powerful abstractions are... powerful. They're more difficult to use
correctly, and take longer to learn.

The conclusion shouldn't (always) be to avoid them entirely.

~~~
preommr
I'd wager good money the exact opposite is true.

Big factories should be better regulated and more professional leading to less
accidents. It's the weekend dad with a beer in his hand trying to get
something done quickly that saws through their tendon and fucks up their
wrist.

Also python is definitely not as simple as a hammer and hand-saw.

~~~
jonahx
Allow me to direct your attention to one of the internet's hidden gems:

[https://www.youtube.com/user/USCSB/videos?view=0&sort=p&flow...](https://www.youtube.com/user/USCSB/videos?view=0&sort=p&flow=grid)

Beyond that, these metaphors have gotten too out of hand to have a meaningful
conversation :)

------
amelius
Not sure if it's still a thing, but the slowness of starting the REPL was what
kept me from moving to Clojure. Python is doing much better in that regard.

------
anentropic
`__setup__.py` is not a thing

it's `setup.py`

------
sridca
I switched from Python to Clojure (because abstractions), and then to Go
(static types; efficiency) and then to Elixir (because work) and then to
Haskell (no more lame types and stupid nil errors).

I feel like with Haskell I have basically achieved perfection, and I'm more
prepared to work on the other languages if the situation calls for it.

------
wyclif
"Why I Switched from Python to [Shiny Newer Language]" seems to be the thing
on HN this week.

~~~
jaabe
The really hilarious part about this one is that it’s from 2016, and the
author seem to have since switched from Clojure to Kotlin.

I think it’s still interesting to read about people switching. I mean, I’ll
never understand why people prefer functional languages to OOP. I think it’s
just so much easier to maintain OOP in the long run, and you can frankly build
most of the advantages of functional languages within OOP if you need to. But
then you read an article like this and you get a reminder that freedom can
lead to some really horrible stuff and that is especially true for Python in
general.

I don’t see this as “we should all switch from Python” sort of thing, but
rather a “don’t do these things with Python”.

~~~
bradcypert
I write Clojure, Kotlin, and Scala all on a pretty regular basis. Truthfully,
I do write less Clojure now than at the time I wrote this post, but that's
predominantly because my current interest (and salary) are centered around
Kotlin + Android.

I still write Clojure quite a far amount, but I don't blog about it as much as
I'm not "exploring" the language as much. Sometimes, I'll find or create
something cool and share it, but most likely that'll be Kotlin/Android related
right now.

