Learn functional programing with me - Part 1 : Language choice
Olivier Guimbal
Posted on February 23, 2021
So, I've decided to write a blog.
Sure, I could use one of many solutions out there and setup a blog in minutes, but writing a blog is not the main purpose here (who gives a 💩 about my opinion anyway ?).
I'd like to learn a language AND build something while doing so.
If you're interested, I'd like this to be collaborative in some way: You could comment my choices, learn from them, and influence them (for instance, you can today influence the language I will use - see below).
🤔 Why would you care ?
TLDR : I will explain, step by step, how I built it, and I will post all the resources that I used to learn how to do it along the way.
In my (relatively) long experience, I learnt and used on real projects many languages that could be qualified as imperative more than functional languages, such as Javascript/Typescript, C#, Dart, Java, VB, C++ (non exhaustive list).
I've always been toying with FP languages, but never had the oportunity to use them on an actual project, so I've decided to build a blog using one of those.
If like me, you already know imperative languages, but you're interested by learning a functional language, you might want to stick with this series.
It aims experienced developpers with at least a little bit of awareness about FP concepts.
Being myself a semi-begginer in most FP languages, you will probably learn the language progressively with me, see (and discuss?) my architectual choices, my mistakes, my misunderstandings, and the solutions I came up with.
🤪 Why do I do that ?
My goal here is to write a tutorial which is progressive, and hands on.
I'm tired of reading hundreds of attempts of guys who already got it to teach category theory by the menu, because they think that their approach at teaching it is better. Reading those, I've been admitedly learning a lot, but I feel incapable of building an actual project with all that knowledge. Which seems retrospectively crazy to me... I don't recall having this kind of feeling when learning simple non FP languages.
When it comes to learning, I believe practice is better that theory to begin with, and that learning practice with someone is better that learning it from someone. Even if it means not learning things the academic way.
🎯 Specifications - what should it do ?
Here is what I'm expecting it to do:
- To be server-side rendered (for SEO) - so no client-only/SPA stuff.
- To be serverless, and to be served via a CDN, zero fixed cost (if possible via Cloudflare Workers, because I 💖 them.. if not, via some kind of Lambda@Edge or equivalent, or even some kind of FAAS + github pages... why not ?)
- To have a git repository containing .md files as raw source (I don't want any online editor, authentication system, or other 💩) - will probably be implemented using hooks/github actions which will update the actual blog.
- To have multiple blogging categories (tech, opinions, ...), presented as columns on the landing page.
- To support multiple formats: tweet-like, pictures, videos, articles (to begin with)
- To automatically repost articles I'm writing on various medium (dev.to, medium.com, reddit, twitter, mastodon, ...), and if legally and technically possible, show the associated comments/likes/claps/retweets/etc on the main blog.
- To be written using FP language(s)
👅 Language
So, I must say, I've toyed a lot with FP languages, thinking that at one point, one of those might strike me as "the best for my needs". That did not happen. Instead, I got lost along the way, learning a little bit about each one, but never mastering any.
Here is a non exhaustive list of the languages that I considered:
- 1️⃣ Purescript
- 2️⃣ ELM
- 3️⃣ ReasonML/ReScript
- 4️⃣ Haskell
- 5️⃣ Clojure(Script)
Below is my perception about each one of those.
As of writing this article, my curiosity about Haskell or equivalent would make me choose Purescript (I'm not settled on the UI lib to use).
If you'd rather see me write it in another of those languages, please comment, I might (or might not) be convinced or influenced , and take your choice into account 😊
1️⃣ Purescript
Purescript is a child of Haskell (their syntax are almost identical), targeting mostly Javascript.
✔ PROS:
- Pure FP Purescript is a pure functional language. This seems to bring a lot of liberties and guarantees while reasoning about your code.
Interop: It outputs quite readable Javascript, and has a very clean FFI (meaning that you can interact with existing Js code/libraries very easily).
Client+Server:It is usage agnostic, meaning that it can be used both server-side (running NodeJS), and client-side
Typing: I've only explored a bit of them, but Haskell-like type systems seems soo smooth, and leads to elegant implementations.
💥 CONS:
- Learning curve: This is no little thing, it is a "next-level" programming language. Meaning that the concepts that you can play with are so much more powerful and advanced that your brain will hurt by learning it. A single line of code can hide much more meaning compared to a classic language, which always make you wonder if you got it all, when reading code. Seems to worth it, though.
📚 Framework:
My first exploratory work would point at either purescript-halogen or purescript-elmish.
Halogen seems nice and widely used, but its SSR story is less clear. On the other hand, Elmish has the advantage of kind-of learning Elm along the way, but is less used (then, there will be less learning resource).
2️⃣ ELM
Like Purescript, Elm is also a child of Haskell, but much more simpler. It actually feels like a simplification + specialization of Haskell, bringing more guarantees on the table, along with a much more nicer syntax error messages.
✔ PROS:
- Pure FP ELM is also a pure functional language.
- Safety: ELM proudly guarantees near-zero runtime exceptions. Meaning that it is literally impossible to encounter any runtime error with ELM (except inevitable things such as out-of-memory & stack-overflow errors). It obviously does not imply that you cannot write errors in your logic, but it means that if it compiles, it will not crash.
- Error messages: ELM is very well known to have state-of-the art syntax error messages. They seem useful, pointing at solutions/suggestions/useful links.
- Bundle sizes ELM seems to crush every other language/framework when it comes to bundle size. ELM bundles seems to casually weight about an order of magnitude less than other tech typical bundle sizes.
- Relatively widespread: Compared to the other languages I considered, I think ELM is the most used to build frontends (it still remains a fringe comunity, though)
- Relatively easy to learn Its ecosystem is very simple... there is often only one way of doing things, and its syntax is straightforward... that makes it easy to learn.
- Coherent ecosystem The community around ELM seems helpful, not flawed by the dissentions I seem to have percieved in other communities, and its package system is rock solid (it enforces semver to published libraries, ensuring nothing will ever break)
💥 CONS:
- No SSR - That is not a small one... ELM cannot do SSR + Hydration. Meaning that we will have to choose between server side rendering and interactivity. I think I would have chosen ELM no question asked if it did suport SSR. But I'm not trying to build a SPA :(
- Interop - As neat as the dev experience is using ELM, it is quite bad when it comes with interacting with JS. You have to communicate through ports, which are quite rigid and tedious. You'll also have much trouble on basic things when it comes to speaking non-elmish, like when deserializing JSON coming from an AJAX query (If i'm correct, you'll systematically have to implement explicit ad-hoc JSON decoders 😑).
📚 Framework:
Not relevant :) ELM is its own framework !
That said, elm-ui seems quite interesting as a library. I think I would use it
3️⃣ ReasonML/ReScript
It is an OCaml descendent.
It seems to put an accent on interoperability with JS, and pragmatism. But I don't know much about it except the basic syntax.
So any feedback is welcome.
✔ PROS:
- More familiar: While you could not guess what random code from the previous two languages is doing without any initiation to their syntax, Reason feels more familiar. It "looks like" something you would understand if you already know languages which are not considered as purely functional, but have some affinity with the functional style, such as Scala, Rust, Kotlin... and even JS.
💥 CONS:
- Messy ecosystem: Sooo... well... It takes at least half an hour to understand that Reason, ReasonML, ReScript, Bucklescript, and all that are actually kind of the same thing, I guess, but not really, but they're not anymore, but they are transitioning, but ... wait wat ? Couldnt someone tell me why all the fuss ? Couldnt we have one way to go ? And how am I sure I'm not starting to use a version that will lead me to a dead-end ?
📚 Framework:
Like I said, I don't know enough about it, but reasonreact seems to be the way to go ! Any feedback appreciated
4️⃣ Haskell
The father of all languages. Over the decades, Haskell has never exploded in popuplarity, but it has inspired in one way or another most of the typed languages out there.
✔ PROS:
- Syntax & type system: Same as purescript... Haskell feels and is very powerful.
- Performance: Not really something that is useful when chosing a language to write a blog, but Haskell can compare to C++ in terms of performance.
💥 CONS:
- Server only: There is no efficient way to use Haskell client-side. Weirdly enought, we'll face the same dilemma as with ELM (which is client-only).
- Learning curve: Same as purescripts...
- Somehow weird ecosystem: I wrote about it here, but Haskell has been out there for a very long time... meaning that you never know when a resource is relevant, abandoned, ...
📚 Framework:
Given that Haskell is only running server-side, and given the "serverless" constraint, using Haskell with widespread frameworks to develop websites such as yesod seems out of the question. If using Haskell, I would have to write some kind of lambda which generates a fully static website. After a bit of research, it would seem that an aws lambda running aws-lambda-haskell-runtime should be a good match.
5️⃣ Clojure(Script)
Clojure (or Clojurescript if you want to compile to JS) is a Lisp language.
I included it here because I used to play a bit with Clojurescript a while ago, and I found it quite original, but I wont dive into details here, since I find it too diferent to be compared with the other 4:
- Is is a fully dynamic language, no typing (there is spec, though)
- Like all Lisps, it does not have a syntax, per se. It's only parenthesis 🤪
- Is is quite flexible
... but I have not investigated weather if SSR is easy, nor about its deployability on a FAAS platform (that said, it runs on the JVM, so it should be the same as Java), cold-start times, etc... and I'd prefer using a typed language. So I'd need a lot of convincing to go with that one ! (even if I like it to play, learn, and write prototypes)
👋 Conclusion
Okay, that was long. So I have questions:
- What do you think ?
- Would you have something to add or to correct ?
- Would you be interested in following such a series ?
- Which language interests you the most ?
- Have I forgotten a FP language that you love and would like to be considered ?
- Which kind of supporting tech (lambda, cloudflare workers, azure functions, github actions, ...) ?
If this interests some, I will post articles & thoughts as I develop this blog. Otherwise, well... I guess that will remain a private journey !
Thanks for reading, and stay tuned for the follow-up !
Posted on February 23, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.