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 :-)
I can highly recommend this article (also just in general for people curious about Elixir): http://theerlangelist.com/article/spawn_or_not
> 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.
That said, if I had a choice I'd choose Clojure every time. I just enjoy it so much more. And it has a lot of good web options: you can easily write REST APIs via Ring, build your front-end in re-frame, and use Lacinia for GraphQL endpoints.
To the OP, I'd highly recommend checking out Elixir and Clojure and spending a little time with each before ruling either out.
If you want to play around with getting up and running with a functional clojure backend, I put up this:
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
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!
I've never used F# on .NET Core, but I'd be surprised if it didn't work.
Do you consider Java a functional language?
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.
Scala is, amongst other things, a functional language. How much to its HTTP frameworks embrace that?
Rust has an ecosystem for building web backends.
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.
* 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.
F# on .NET Core is stable and there are templates for an F# web application.
Do you need some sort of rest-like HTTP API? Highly suggest Haskell and the Servant framework! It's amazing.
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.
I wrote a blog post about using Giraffe here: https://blogs.msdn.microsoft.com/dotnet/2017/09/26/build-a-w...
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.
For example you might be interested in: 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.
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.
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 :-) .)
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.
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.
Fair point. I have to say that I appreciate both the
reactive programming movement is a neat example where we can
find functional ideas brewing .
If you want purely functional, both haskell and clojure do have a good backend community and quite a few good tools.
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).