
Using Clojure for Web Apps - simonpure
https://github.com/tbsschroeder/using-clojure-for-web-apps
======
kgwxd
Here's the video:
[https://www.youtube.com/watch?v=dzGuaO38XDw](https://www.youtube.com/watch?v=dzGuaO38XDw)

~~~
claytn
thanks!

------
lgessler
Some of my favorite Clojure libraries in this space:

\- instaparse: takes EBNF (and other formats) as a string and gives you a
parser instantly (!!!)
[https://github.com/Engelberg/instaparse](https://github.com/Engelberg/instaparse)

\- re-frame: React-Redux alternative that IMO is much easier to work with
[https://github.com/day8/re-frame](https://github.com/day8/re-frame)

\- reagent: React wrapper [https://reagent-
project.github.io/](https://reagent-project.github.io/)

\- ring [https://github.com/ring-clojure/ring](https://github.com/ring-
clojure/ring)

\- fulcro
[https://github.com/fulcrologic/fulcro](https://github.com/fulcrologic/fulcro)

More than any library, though, what keeps bringing me back to Clojure is its
incredibly blissful set of persistent data structures. It's a pernicious
accident of history that we are taught to accept references to mutable objects
as normal, inevitable, and desirable in most CS curricula. It is much easier
to develop, debug, and maintain immutable data structures instead, and I
consider my good fortune every time I get to debug something in Clojure rather
than in some reference-laden OOP soup.

~~~
dominotw
> desirable in most CS curricula.

most of the alogrithms and datastructures that you learn in CS were developed
using mutability.

I am not sure that we can even develop immutable equivalents for most of them
with similar time/space complexities.

~~~
lgessler
Sure, and we could argue about whether mutable code is necessary at systems
layers. But at application layers (i.e., the ones most developers work at),
cost of development is almost always going to come before performance, and I
think it's clear by now that OOP, at least insofar as it has been instantiated
by Java, C#, and friends, has not delivered on its promise to simplify
application development.

------
bloopernova
I've been slowly learning Lisp to hack on Emacs, org-mode and org-babel. Main
goal being to turn AWS JSON data into org-mode headings and org-babel data to
do further work on.

Very much a side project and I'm a bear of very little brain, so it's taking
me a long long time.

Seeing Clojure and other Lisp stuff in the wild gives me hope that I can lean
on enough people's documentation and source that I can eventually learn what I
need.

I know some folks sneer a little at Lisp, but I really enjoy trying to learn
it. I haven't felt as motivated to learn a coding language since about ten
years ago when I used Perl to transfer/munge data from different LDAP systems
into Zimbra.

So, thank you for sharing, this is fascinating stuff.

~~~
defined
> I know some folks sneer a little at Lisp

I wonder why.

Some developers I know and hold in high regard have almost venerated Lisp, so
I've always thought there must be _something_ to it. I just thought it wasn't
something you could actually use IRL, but I was wrong. I found this out when I
was recently motivated to learn Clojure, and now I am starting to grok their
admiration.

~~~
blunte
It will depend on whom you talk to - perhaps how old they are, and certainly
where they come from (experience wise, education wise, etc.)

The usual easy excuse is about parens, but that complaint has been put to rest
so many times that it's not worth replying to anymore. (And people said the
same thing about Python whitespace, but now Python is at or near the top of
the pile.)

~~~
gherkinnn
Python has too few parentheses, Clojure has to many. There’s just no winning.

Ultimately, these complaints are superficial and serve only to justify one’s
laziness.

~~~
blunte
Clojure has the same number of parens as Javascript, C/C++, Java, and similar
languages have parens+squiggle-brackets.

(print "foo") vs print("foo"). same same.

There's so much more to it than this. I can say without reservation that
people who do not take a couple/few weeks to learn a Lisp just do not know
what they are missing, and their arguments against it are viewed as children
who lack enough experience to know what they are rejecting.

~~~
wostusername
>(print "foo") vs print("foo"). same same.

If you look at things other than function calls, it starts to look different:

    
    
        let x = 5,
            y = 10
        foo(x,y)
    

vs

    
    
        (let [x 5 
              y 10]
          (foo x y))
    

I actually like Lisps and think the S expression syntax is one of their best
features, but I'm not going to pretend there are the same number of brackets
in Lisps as there are in C family languages.

~~~
blunte
I can't reply to your lower example because it's too deep, but I would point
out that clojure does not have the other symbols - equal and comma.

In your lower example, Clojure has only one more non alphanumeric character
than the other example.

Furthermore, in Lisp, you always know that you have (function-name param param
etc). Reading it becomes not just easier - it removes an entire layer of
abstraction (syntax rules). Also, with smart editors, you gain the ability to
move these around rapidly in ways that you simply cannot do with other
languages.

Funny thing is, the biggest annoyance I have when not using Clojure is having
to type commas between items in data structure. [1 2 3 4 5] just looks so much
cleaner than [1, 2, 3, 4, 5]. I forget who wrote it, but they complained of
seeing all the mouse turds "," in normal programming languages.

~~~
kazinator
Even math notation dispenses with the silly commas in matrix notation, which
so nice it gets used for vectors also.

------
elamje
If anyone is interested, there is an up and coming Clojure web framework
called Coast, [https://coastonclojure.com/](https://coastonclojure.com/)

For those that aren’t as familiar with Clojure - there isn’t a rails or Django
for web apps, so Coast is trying to fill that void.

~~~
wry_discontent
I've used Luminus to fill that space, and I gotta say I don't think that's the
best way to go for Clojure.

Getting started with Luminus was fine, but it was often very confusing and I
didn't understand a lot, whereas when I added things as I needed them and
checked out a couple libraries, I had a lot easier time debugging what was
wrong.

What's going to make Coast different?

~~~
dvcrn
IMO languages like Clojure (or Go) don’t need a fully powered batteries
included web framework like Rails or Django. The approach to pick together
what you actually need (router, db bits and pieces, etc) with composable
libraries works really great

~~~
goostavos
After having gone through this, I now disagree.

There are a vast many things in which I am not an expert. The pick and choose
/ compose your libraries / lego approach sounds great until your trying to
weigh different options (of which none seem to have a wide enough install base
to be truly battle tested).

Is buddy/buddy-auth the way to go for security? Or is it Friend? The former
seems to receive more recommendations as of late, whereas the latter has more
activity on github. These are not the problems I want to be solving when
building something.

I love the language, but the quality of Clojure's web ecosystem is...
questionable.

If I were to build another webapp in Clojure, I think I'd just use something
widely installed like Jersey for actually interfacing with the outside world.
It'll be crufty Java, but it has nice things like StackOverflow activity,
massive docs, giant userbase, etc.. etc..

~~~
blunte
You express exactly what has kept me from doing webdev with Clojure, despite
my (now perhaps irrational) love for the language.

I will learn whichever language allows me to get my site/app done as quickly
as possible at first. Later after I have refined and refactored enough to know
what's up... then I may decide to change.

Nextjs (despite the javascript), Rails (Ruby is great!... not Clojure, but
pretty good), Django (Python is low-pain, low-effort), etc. are all easy quick
ways to actually get something done BEFORE you really know what you're doing.
This is critically important for those of us who don't spend all our time
doing public-facing web apps.

~~~
Scarbutt
As someone who tries to use Clojure everywhere I can, its very hard to beat
Rails for pushing out a webapp (many long Clojure timers share this opinion).
Clojure shines for web services that require lots of data processing in the
server and for integrating with parts of the Java ecosystem.

~~~
blunte
I have not investigated Coast yet. I know it aims to be a Rails for Clojure...
maybe it is, and maybe it would meet my needs.

But given the incredible power and expressiveness of Clojure, I find no reason
to believe that the _best_ rapid web development framework could be developed
in Clojure if the right motivated people attempted to do so.

I don't know how many people (Plataformatec?) were behind Phoenix, but even in
its early versions it was comparable to Rails. In some ways, it was even
better.

There seem to be two obstacles to doing this in Clojure. The first is that
people who actually know enough about Clojure to do this are actually very
busy (happily) doing Clojure for work. They don't have the personal need to
build a Rails for Clojure. The second is that those who would be capable
already know how to pick and choose the libraries and build their own (even
better, more suited for the purpose) ad-hoc frameworks for their projects.

I suppose it could be a curse of the power of Clojure that the lack of
language pain points lessened the need/motivation for experts to build their
own RAD framework.

~~~
Scarbutt
I'm not denying that something better than Rails can be built with Clojure,
just implying that it doesn't exist, so for quickly pushing out a CRUD webapp
multiple times without repeating yourself again and again(avoiding all the
trivial/tedious stuff), there is Rails.

~~~
blunte
Yup, and that's why Rails is what I still use :). Phoenix was pretty great
too, but its real benefit came from doing bigger back-end stuff on BEAM.

------
juskrey
We use pedestal+fulcro3+pathom

om.next was before that, but it seems to be almost abandoned, also fulcro
author have solved a lot of depressing pain points of om.next.

Those three work like a perfect Lego.

~~~
lgessler
I'm thinking of writing a project with a similar stack, is there any chance
your code is open source? Also, what's your experience with Fulcro been like?
Do you have any thoughts about it in comparison with other Clojure SPA
libraries like re-frame?

~~~
juskrey
Projects are closed source, so I can share only some general architectural
examples.

Experience was like.. two weeks of hair pulling, gallons of coffee and no
weekends, followed by intense relief and gratitude to fulcro author Tony Kay
(also pathom author Wilker Lúcio) for all that not always obvious things which
make great sense in the long run. This happened to me with several great
Clojure things, so I immediately knew good experience was just around the
corner.

Oh and his online book
[http://book.fulcrologic.com/](http://book.fulcrologic.com/) has great general
SPA insights.

Three pretty serious apps with fulcro so far.

------
smnplk
After some time with Clojure, I can not bear to look at _any_ OO code. It's
like I developed an allergic reaction to class-based programming.

~~~
serpix
Even worse is having been through the enlightenment and then witnessing people
talk about Javascript or Scala like it is still 1990. You just want to yell to
them "You're all living in a cave!"

------
currentoor
I gave a talk on using Fulcro for building web apps with Clojure.

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

------
faitswulff
Navigating that slide deck was surprisingly frustrating. Clicking forward 10
times to get through a single slide must have been really annoying to present,
too.

~~~
dominotw
arrow keys seem to work ok.

~~~
Roboprog
Not on my tablet, trying to skim it at lunch.

Future consideration...

------
dana321
Here is a link to the website of the library that they use, its pure chance
that i was watching a talk with one of the creators of this library before i
saw this at the top of hacker news.

[http://pedestal.io/](http://pedestal.io/)

------
abiro
I love Clojure and take every chance to use it, but unfortunately it’s very
much behind the curve. Building web apps is more and more about tying together
managed services with short scripts (aka serverless). This means that most app
developers never have to deal with the hard technical problems that Clojure
was designed to solve and Clojure’s slow startup time on the JVM makes it
unfeasible for serverless functions.

Clojurescript on Node could be a good contender, but last time I tried it, the
development experience was very poor and the power of Clojure doesn’t really
shine in serverless functions, so I just use Python for that which is a
perfectly adequate scripting language.

~~~
james-mcelwain
> Clojure’s slow startup time on the JVM makes it unfeasible for serverless
> functions

GraalVM could totally change this.

~~~
joobus
Clojure uses too much runtime reflection. I tried many iterations of compiling
different server projects with Graal and none worked. I could get simple
programs to compile with an older clojure version, but nothing with recent
code.

~~~
james-mcelwain
I'd expect the tooling will improve over time. This obviously isn't an
immediate solution for running Clojure in situations where cold starts matter,
but in general I think many of the improvements coming to the JVM in the next
few years will pay dividends for Clojure.

------
knubie
What I'd really like to see is a full stack clojurescript framework like
next.js or meteor. I think fulcro comes close but it uses JVM clojure on the
server side, so it's not entirely possible to re-use code on either end.

~~~
currentoor
There are several commercial users of Fulcro using Node JS on the backend. I
am one of them.

~~~
knubie
I had no idea about that, guess I need to dive deeper into the fulcro docs,
thanks!

------
nickik
Pretty simple Webapp that you could have done 7 years ago. That not
necessarily a bad thing but I wouldn't develop a webapp with those tools.

Specifically the 'Component' library. I really didn't enjoy working with it
and it one of the most complex to understand parts of our web application.

So while this seems like a fun set of slides (I have not watched the
presentation yet), it's not what I would call a great introduction to Web
development in Clojure overall.

~~~
ilikehurdles
What a surprise that the stateful edges of the application are the most
complex! I didn't mind component in the past but we just started a project
with mount and I really dislike working with that. Seems like there are a lot
of ways to shoot your own foot with any of these libraries because there is no
"one true way" to integrate them into an application. I haven't tried
integrant yet but everyone and their dog seemed to be using it at the 2019
Conj.

I would totally start a project with pedestal today though.

~~~
dm3
Out of curiosity - what are the pain points related to Mount?

~~~
ilikehurdles
Its composability is a bit of a double edged sword. While it leads to a more
declarative style of state management, I've found our implementation of it to
lead to confusion about when /where/which states are swapped in or out. But
honestly I think anyone can have a great or cruddy experience with any state
management library depending on how it's weaved into the code, and I don't
blame the library so much as I blame our implementation thus far.

------
mscasts
Honest question, does anyone actually gain anything from reading slides
without hearing the actual talk?

~~~
defined
Honest answer: I feel like I did.

------
jrobn
Clojure and Elixir (Erlang) are my favorite languages. When you get to the
point where the parens and brackets just melt away and you have this
awakening.

It makes me wish José (creator of elixir) would have chosen Clojure syntax
instead of Ruby.

~~~
ska80
Have you looked at LFE?

[http://lfe.io](http://lfe.io)

------
pinopinopino
I am more of Scheme guy and always feel Lisp is pretty overwhelming, but this
looks quite clean. I like the little language for writing HTML.

~~~
pinopinopino
But this looks like a sql injection awaiting to happen:

    
    
        (defn inc! [id]
          (kc/exec-raw (format "UPDATE articles SET count = count + 1 WHERE id = %s" id)))
    
    

(From [https://github.com/tbsschroeder/clojure-webshop-
app/blob/mas...](https://github.com/tbsschroeder/clojure-webshop-
app/blob/master/src/metro/components/db/articles.clj#L27)) You don't need
format it seems:
[https://github.com/korma/Korma/blob/master/src/korma/core.cl...](https://github.com/korma/Korma/blob/master/src/korma/core.clj#L518)

~~~
hellofunk
sanitizing SQL queries is just as simple in Clojure as in any other language
(maybe more so), even if it wasn't done in this example.

~~~
pinopinopino
It looks like it is builtin even in the library he uses. So not sure why he
chooses format.

------
jgoodhcg
Is pedestal a better experience than luminus?

