Ask HN: Which functional language has the best ecosystem for a web backend? - xstartup
======
joaomdmoura
I have been using Elixir for the past more than 2 years and got say that it
has an awesome ecosystem for overall web development, I've been using and
writing open source libraries and they are looking pretty solid as well. The
company I work for also uses it as its main backend for the past almost 3
years and it has been working nicely since then. Hiring also got way easier,
not only because of the existing developers using it already but also because
the interest on it has increased.

~~~
skrebbel
I second that Elixir's ecosystem is exceptionally great for such a young
language. I love working with it.

That said, I'd wager it can hardly be called a functional language. Sure, you
can't write for loops, but every Elixir process encapsulates a little piece of
mutable state. Elixir and its ecosystem allow and encourage you to have (very)
many processes, and thus many global singleton-like pockets of mutable state.
It's a powerful and pragmatic concept, it works very well, but it doesn't
really feel very functional.

The most extreme example of this design philosophy is a Elixir standard
library module called "Agent", which is just a cute name for "global mutable
variable". When used with care it's a very handy tool but, well, functional?
Nah :-)

~~~
mercer
While I don't disagree entirely, I find that Elixir is actually quite
functional. Using processes for state as if they're objects is generally
considered bad practice.

I can highly recommend this article (also just in general for people curious
about Elixir):
[http://theerlangelist.com/article/spawn_or_not](http://theerlangelist.com/article/spawn_or_not)

A quote:

> But before starting, since this is going to be a long article, I want to
> immediately share my main points:

> Use functions and modules to separate thought concerns.

> Use processes to separate runtime concerns.

> Do not use processes (not even agents) to separate thought concerns.

> The construct “thought concern” here refers to ideas which exist in our
> mind, such as order, order item, and product for example. If those concepts
> are more complex, it’s worth implementing them in separate modules and
> functions to separate different concerns and keep each part of our code
> focused and concise.

> Using processes (e.g. agents) for this is a mistake I see people make
> frequently. Such approach essentially sidesteps the functional part of
> Elixir, and instead attempts to simulate objects with processes.

------
nicwest
Clojure! the thing I like most about a lot of the libraries is how they seem
to blend so seamlessly. I don't know if it's an artefact of just being a lisp
or just a lot of the developers sharing a mindset, but the whole experience
feels less janky.

~~~
tuddman
agree. Once I discovered Clojure, it's all kinds of fun to write in! The
community is great. The ecosystem now has plenty of robust libraries to handle
most any heavy-lifting task(s).

If you want to play around with getting up and running with a functional
clojure backend, I put up this:

[https://github.com/tuddman/moarweba](https://github.com/tuddman/moarweba)

feedback welcome

~~~
xstartup
Did you ever try F#? I've tried both Clojure and F# and I honestly prefer the
latter.

------
Odytrice
Well, IMHO It's F#. F# is really good due to it's better tooling and you have
access to the plethora of libraries and framework of the .NET Ecosystem.
Unlike Scala or Kotlin, F# retains a lot from it's functional roots like \-
Automatic Currying \- ML Type System

Plus it adds some really innovative features like \- Type Providers which
allows you to lazily/automatically generate Types for real world data/systems
which is pretty cool.

Ultimately it boils down to the Runtime/Tools/Ecosystem which is also true for
Scala and Kotlin but it retains a lot from it's OCAML Heritage which makes it
lean more towards FP than it contemporaries

PS - I didn't mention clojure as I don't consider dynamic languages a good fit
for building large codebase backend systems

------
ninofloris
We at Crowded ([https://crowded.co](https://crowded.co)) have had some very
good successes with running F# on .NET Core, both with giraffe and just bare
ASP.NET Core. The ecosystem has no shortage of good tooling and libraries, all
well maintained by knowledgeable authors. Application performance and our
development productivity is excellent, osx/linux tooling took a while to
mature but is only getting better than ever now.

The choice we made when .NET Core was still in development (pre 1.0) for it to
become our main stack is definitely paying off!

------
minhajuddin
Elixir/Erlang are one among best functional programming languages for web
today. Phoenix is a very performant and productive web framework. You can
build a typical web app really fast using Phoenix and Elixir.

~~~
nickserv
You mentioned Erlang, where do you normally use it?

~~~
minhajuddin
Well, the erlang vm is what runs Elixir apps. Elixir runs on the erlang VM
(called BEAM) similar to how scala/clojure run on the JVM. However, while
writing a lot of elixir code you end up using the erlang standard library for
things which are not available in Elixir, :crypto is a module which comes to
mind. Elixir apps at the end of the day are erlang apps.

------
dustinmoris
I find .NET Core (particularly ASP.NET Core with F# via Giraffe -
[https://github.com/giraffe-fsharp/Giraffe](https://github.com/giraffe-
fsharp/Giraffe)) extremely good since Microsoft went all open source. I have
multiple backends running in a GCloud Kubernetes cluster and develop all my
stuff from a non Windows environment. Couldn't be more happy and the speed of
ASP.NET Core with Giraffe is fantastic (~100K r/s).

~~~
dustinmoris
I'd like to add that with F# you get all the benefits of an extremely mature
web stack with asp.net core and a huge eco system of very high quality
libraries. Frameworks like Giraffe, Suave or Freya make it all possible to
write your backend in a functional idiomatic way. Also a big plus for F# is
the choice of top notch tooling. You've got Visual studio which works on
Windows and Mac, then JetBrains Rider which is awesome and Visual studio code
with the Ionide extension. I'd highly recommend anyone to go and check it all
out!

~~~
xstartup
I am also leaning towards F#. What do you use for json serialisation? Any
guide which describes basic steps to put together a web api.

~~~
EnderMB
JSON.NET is the standard library for handling JSON on the .NET platform, and
to my knowledge it's available for both .NET Core and for use with F#
collections.

I've never used F# on .NET Core, but I'd be surprised if it didn't work.

~~~
edgarsanchez
Yep F#, the language, works all right in .NET Core 2.0. Some libraries,
particularly, type providers, not yet, but they are working, on it. And
JSON.Net also works fine on .NET Core.

~~~
vorotato
As I understand it type providers work with dotnet core code, provided you
build the providers in mono. But yeah that's not exactly ideal.

------
axlprose
Haskell's Yesod framework has a pretty solid ecosystem. It even comes with a
free book:

[https://www.yesodweb.com/book](https://www.yesodweb.com/book)

------
edgarsanchez
F#, first because its ecosystem is the whole .NET Framework world of
libraries, utils, etc. Second, because it's got its own set of very functional
libraries like suave.io for web apps/services, FSharp.Data for consuming data
of diverse sources/natures, Fable.io an elegant JavaScript transpiler.
Finally, with very demanding production projects like jet.com it already has
proved that it can process massive amounts of transactions.

------
anthonyskipper
Today I would say Java/Scala mostly because of jvm access to huge numbers of
libraries. But also because of things like Akka.

There may be other options depending on whether you consider JavaScript or Go
to be a functional language.

~~~
dtech
Scala has a number of good HTTP frameworks, Play, spray/akka-http and Lift
come to mind.

Spring boot (Java) is also very decent, and Play and akka-http have both
first-class Java and Scala API's.

Kotlin has the same JVM advantage.

~~~
twic
The OP specifically asked for a functional language, though. Java and Kotlin
have adopted some ideas from functional languages, but they aren't themselves
functional languages, and their HTTP frameworks certainly aren't designed
along functional lines.

Scala is, amongst other things, a functional language. How much to its HTTP
frameworks embrace that?

~~~
owlmusic
[https://github.com/http4s/http4s](https://github.com/http4s/http4s) Is a a
good example of a HTTP Framework in Scala providing idiomatic FP interfaces

------
bringtheaction
Some would say that Rust is a functional language.

[http://science.raphael.poss.name/rust-for-functional-
program...](http://science.raphael.poss.name/rust-for-functional-
programmers.html)

Rust has an ecosystem for building web backends.

[http://www.arewewebyet.org/](http://www.arewewebyet.org/)

Does Rust have the _best_ ecosystem for a web backend, though? I think that
will depend on who you ask and what you are looking for specifically.

~~~
steveklabnik
Third party resources can be sort of out of date; your first link is from
2014, and therefore has a bunch of inaccuracies. Your second was last updated
last Octoboer, so not so much, but is still missing out on stuff.

~~~
DennisP
Do you have a source that isn't missing stuff, or you could you mention some
of the important bits?

~~~
steveklabnik
Some examples:

* the h2 crate was released last week, which adds http2 support to the ecosystem

* the frameworks page is missing, off the top of my head, shio and actix. It also includes pencil, which has been abandoned for a long time.

* It includes nothing about Rust's fairly recent wasm support and all of the crates that let you work with that

In general, this is an extremely active area, with few "winners" so far, and
crates.io is adding roughly 23 crates a day, though obviously not all web-
related. There's just so much stuff all the time that keeping a curated
resource like this up-to-date is a lot of work.

------
carlmr
For backend you'd have Scala on the JVM side and F# on the .NET side.

~~~
partisan
I second F#. You have access to the full .NET Standard library as well as all
of the open source libraries available. I personally found it more of a joy to
use than Scala, but that may be due to my knowledge of and experience with
.NET.

F# on .NET Core is stable and there are templates for an F# web application.

~~~
brightsize
I'm an experienced Scala dev but after reading the "fun and profit" ebook F#
looked really interesting. Naturally I tried to take the next step of creating
a small webapp with it on a Linux dev machine. Unfortunately I ran into a lot
of problems identifying and setting up the needed tools and frameworks on
Linux and eventually gave up. My assumption was that the tooling+frameworks
were likely "not quite there yet" (late 2017) for Linux but I'd love to be
proven wrong. Any suggestions for an up-to-date tutorial on "web development
using F# on Linux"?

~~~
edgarsanchez
For a from zero to "Hello world!" no frills installation try
[https://medium.com/@edgarsanchezg/four-easy-steps-for-
instal...](https://medium.com/@edgarsanchezg/four-easy-steps-for-installing-f-
in-ubuntu-linux-88122323f12b). Then, you can go on to
[https://www.demystifyfp.com/FsApplied2/](https://www.demystifyfp.com/FsApplied2/)
great e-book (not free, but really inexpensive) on building F# webapps with
suave.io

~~~
brightsize
Thanks for the pointers, I will definitely check both of these out. In my last
attempt I got to the "can compile 'Hello World' from the command line and even
debug it in VSCode" stage but after that things quickly went off the rails
IDE-wise. I even tried MonoDevelop (did some C# work with it long ago) but
IIRC the Xamarin stuff was barfing on one or more asp.net dependencies.
Hopefully one of your links will be to an "Idiot's guide to F# on Linux" and
then I'll be in good shape. :-)

------
kahnpro
This completely depends on what you want out of your web backend!

Do you need some sort of rest-like HTTP API? Highly suggest Haskell and the
Servant framework! It's amazing.

------
Nelkins
Been using F# in a web-backend capacity for about two years now. Language is
great, hits a very sweet spot when it comes to productivity, tooling (F# has
some of the best dev tools out there), etc. Interop with the rest of .NET is
pretty much seamless, so there's no lack of good libraries.

------
phillipcarter
I'd say that in terms of ecosystem, anything running on the JVM is probably
going to be the broadest; that is, you'll have the most choices (mostly Java
libs and frameworks) to decide from. In terms of functional libs/frameworks,
that number will drop a lot, but in practice you'll probably have what you
need.

If the JVM or Scala/Clojure doesn't sound like a good time, F# is a good
option (I'm biased as I work on it). The ecosystem is similar in that most
libs/frameworks on NuGet are for C# developers, but in practice you really
won't need them for a web service. Giraffe, Suave, and Freya are three choices
that will run on .NET Core today.

~~~
xstartup
Out of these 3 (Giraffe, Suave, and Freya) which one do you recommend to a F#
newbie?

~~~
phillipcarter
Giraffe and Suave are _likely_ to be easier for a newbie, and both have the
"Suave programming model" for API routing, so you'll find the way to set
things up is very similar (despite a few different names, such as _WebPart_
and _HttpFunc_ ). Both run on .NET Core as well. The main difference is that
Giraffe sits atop the Kestrel HTTP server which ASP.NET Core is built on,
whereas Suave has its own web server implementation.

I wrote a blog post about using Giraffe here:
[https://blogs.msdn.microsoft.com/dotnet/2017/09/26/build-
a-w...](https://blogs.msdn.microsoft.com/dotnet/2017/09/26/build-a-web-
service-with-f-and-net-core-2-0/)

------
agentultra
Eco-system-wise you might want to try compiling from a functional language to
JS and target Node.js -- Bucklescript or GHCJS would be my choices. That way
you get access to all of the libraries on NPM.

~~~
dustinmoris
I like Fable [https://github.com/fable-
compiler/Fable](https://github.com/fable-compiler/Fable)

------
dmcgillen
I've been using Clojure on the backend for about 5 years now and find it an
absolute joy to work with, having come from a Java background. You get full
access to the masses of Java libraries out there as it's on the JVM. Great
community support, too.

As an addition, there's also ClojureScript for the front-end. It's come a long
way recently, and I've been using it for the last couple of years in
production (check out reagent and re-frame if you're interested).

------
steinuil
I wouldn't call its ecosystem great, but if you like complex type hackery and
don't need to do anything very complicated, Ur/Web can get you quite far.

It's very hard to learn, especially if you're not that familiar with Haskell
and SML/OCaml, but once you grok it writing CRUD apps is a breeze. Just be
prepared to spend a lot of time looking at the standard library's signature
files.

------
pkese
Do note, that some functional languages have good out-of-the-box support for
both backend and frontend. An this is not negligible. I'm using F# which in
combination with Fable (F#->.js transpiler) lets me really quickly share code,
datastructures and serialization with frontend code.

Now, I'm a primarily a backend developer. But sometimes it is just really
convenient to be able to hack together an in-house real-time data-analysis or
reporting service and render statistics as webpages rather than .csv
documents.

If your frontend team is functional as well, then the benefits of sharing the
language could be even bigger.

Sure, not everything is perfect in the F# world. However having the
possibility to share code with frontend saves me more time than I spend in
fighting with the F# ecosystem. And also: programming in F# is just fun
joyful. And productive.

------
terminalcommand
I'm surprised nobody mentioned good-old Common Lisp. With quicklisp you get
access to a ton of libraries.

For example you might be interested in:
[http://8arrow.org/caveman/](http://8arrow.org/caveman/)

Lisp ecosystem is really mature and gives you a lot of freedom.

Dynamic typing, interpeted language, homoiconity, tons of great battle-tested
libraries etc., Lisp is truly a great language for backend web development.

Even this very site runs on a homebrew lisp dialect (Arc) running on Dr.
Racket (Scheme). If even that bizarre setup (sorry PG :)) can handle this much
traffic on a single server, you shouldn't worry about speed or scalibility if
you opt for Common Lisp.

~~~
jwhite
Interpreted language? Common Lisp is typically compiled. Besides which, why is
interpreted a particular advantage? e.g. Python was interpreted 10 years ago
when I was using it, but Common Lisp felt far more flexible and powerful,
because you can compile single functions with a key press in SLIME and
seamlessly load them into your running (compiled) image... shortest feedback
loop I've ever experienced. Maybe Python has caught up in the mean time, I
haven't used it seriously for a long time though, so I don't know.

~~~
terminalcommand
I instinctively used the "interpreted" term, because mainly you can execute
instructions on the fly in an interpreter the language ships with. Whether
it's compiled to bytecode and then executed from there is IMHO an
implementation detail. With compiled languages (following this logic) such as
Java or Go or C, you need to write your program pass it through a compiler to
get an output.

With languages like Javascript, Lisp, Python, Ruby etc. you can write your
programs incrementally, going back and forth between the REPL.

Sorry if my terminology has caused you trouble. I regard dynamically typed
languages that ship with an interpreter as interpreted languages. For
optimization reasons the implementation probably uses some sort of compilation
but you can still use the built-in interpreter on all of these "interpreted"
languages.

I should probably have used the term "ships with an interpreter" :)

BTW the current python-mode in Emacs also allows SLIME-like behaviour. You can
open a python process with C-c C-p and then send the buffer, functions, marked
areas, lines etc. to the python session.

~~~
jwhite
Well, SBCL does not ship with an interpreter, for example. Expressions entered
at the REPL get compiled directly to machine code, so there's no difference in
performance for a function entered at the REPL (or via SLIME C-c C-c) and one
built as part of a batch compile.

Contrast that to Haskell's ghci interpreter, which is slower (last time I
checked) than the same code built on the command line with ghc, the compiler.
But I would still consider Haskell a compiled language, not an interpreted
one, since you never run code in production under ghci, you always ship your
binaries.

I suppose it's about perception. To me "interpreter" refers to a language
implementation strategy. It's fuzzy, I know, since there is some continuum
between interpreting an AST directly, compiling the AST to bytecode and
running the bytecode on a VM, JIT compiling the bytecode to machine code on
the fly, and compiling offline direct to machine code (like C/Go/Rust). To
some ears, "interpreted" can sound synonymous with "slow", which is I guess
what prompted my comment.

Finally, to me the place where you can enter expressions to try out your
program interactively is the REPL, not the interpreter.

Anyway, thanks for explaining your position to me. (Also, good to know Python
dev environments have improved, but I guess it's to be expected, 10 years is a
long time :-) .)

------
mercer
I got excited by both Elixir and Clojure, but vastly prefer Elixir. That said,
Clojure would probably be my second choice and one major advantage is that
ClojureScript would allow you to also build out the front-end in the same
language. As far as I know Elixir's equivalent, ElixirScript, is nowhere near
ready enough for that.

------
ostvp
js actually supports functional paradigm. So, node.js has the most mature
ecosystem for web i guess.

~~~
macintux
There’s a huge difference between being a functional language and supporting
functional paradigms.

Nearly every major language does the latter, but if you consider immutability
a key functional feature, for example, you’ll sorely miss it when the language
doesn’t really support it.

~~~
jbob2000
You don't need the language to enforce immutability. If the project is small
enough, you can enforce it yourself with a linter or by hand.

~~~
Veen
Or use something like Immutable.js, but enforcing immutability on anything but
a tiny project is likely to go awry. Takes a lot of discipline from everyone
involved.

------
dtech
Define "ecosystem for webbackend". If all you want to do is put up a decent
HTTP/REST-ish API all large languages have multiple good options.

------
bennyp101
Elixir is a good bet

------
sidcool
Idris with Idris4Web is a very basic framework

------
zeckalpha
Arc?

------
cooervo
elixir or scala + akka

------
sioa
JavaScript.

If you want purely functional, both haskell and clojure do have a good backend
community and quite a few good tools.

~~~
TomMarius
I'd rather recommend TypeScript

~~~
sidhuko
Have they sorted the differences with async/await? I'd be using if it wasn't
from the different implementation meaning you need to use typescript to babel.

~~~
miaklesp
Sorted already. Transpiles async/await natively.

------
gaius
OCaml with Ocsigen

