Web Development Principles: One Platform
Posted on June 3, 2015
As it is today, we have to decide very early in our development where the code will run. I want to delay that decision as long as possible, even until runtime if needed. A good example of this could be the tweet button on Twitter. Let’s assume that pressing the button not only showed us the modal, but updated the URL. (Arguably when we press the tweet button, we should have another URL since it’s another resource, but that’s an argument for a different blog entry). Hence it would be possible to link directly to the tweet modal in addition to summoning it via the tweet button on the timeline. It should be possible to render the tweet modal on the server for when a browser directly links or render in the browser when the user clicks. Certainly this optimization would be overkill for the tweet button, but this is the idea. I want to build in such a way the content can be rendered in either place, client or server.
We can do so much better. Thankfully, compiling good languages to JS is a thing. My team decided to use CoffeeScript to give us a slight boost in this regard. It greatly reduces the syntactic noise, provides a few higher-level abstractions, and gives us expression-based semantics (my favorite enhancement). While this was a good choice for my team at that point in time, the community as a whole can do much better than CoffeeScript.
The first compile-to-JS alternative that comes to my mind is Clojurescript. I like it primarily because it is a functional, expression-based programming language with default immutability. There is an awesome community around it with folks who I enjoy running around with.
I could also consider Scala.js. I got interested in Scala.js really early on when I wanted to play around with scraping Craigslist posts. Unfortunately, I abandoned the idea and never tried it. By the time Scala.js was announced as no longer being experimental, I had completely lost interest.
Why? I feel that neither Clojurescript and Scala.js are what I want to deal with. Neither one was designed to compile to JS. It was an afterthought. As a result, there are pages dedicated to stuff that does not work the same as on the original platform. Clojurescript has this page dedicated to the differences from Clojure. Scala.js likewise has its differences.
If I’m dreaming of all the webs from scratch, I’m not picking one of these two which had to deviate from the original vision to make the compilation to JS use case work. I want something that was designed with JS in mind from day one because that is my target platform. This is where I am gaining a lot of interest lately in Purescript. Although work is being done to target alternative back ends, the very description of the language is one which compiles to JS.
Furthermore, I see little value in supporting multiple platforms with my language of choice. The browser runs JS. Node lets us run the same code on the server. I know that Node is not a great runtime compared to the JVM at this point in time, but I strongly suspect this will greatly improve in the near term. Too many people are keen on it working well, so the work is being done. If my gamble on Node being awesome is right, then compilation to other platforms only benefits us by opening up more library reuse.
Having multiple platforms for the language may actually even hurt the community a bit. What I mean is that a new language’s success depends greatly on leveraging its parent platform’s existing libraries. Having multiple platforms means libraries and applications need to be mindful of where the code will run and hence which library to use. This code then isn’t portable between client and server the way I want it to be. If you want it to be portable, you either have to write adapters for the different libraries or rewrite them from scratch. Both exercises are expensive and counterproductive. I could see a community spending a lot of time on writing these backends, dealing with the portability problem, and not focusing on solutions which build on what is already available.
Just to be clear, I don’t mean to be antagonistic towards writing alternative platforms for languages like Purescript. I’ll support doing so because there are other benefits which may be important to other people in the community. I just mean that my needs do not require multiple backends, nor is it likely I will apply much effort towards those efforts. Furthermore, I doubt the alternative backend will gain enough attraction in the community as a whole to survive long-term.
While I’m talking about Purescript, I should mention the implicit requirement I have here. The language of my ideal stack will fully embrace the functional programming paradigm. Although I understand it is possible to write functional code in any language, I want one which apologetically favors the paradigm. Furthermore, I want the entire stack to embrace functional programming, avoiding side effects and mutation.
I’m still on the fence about static typing, to be honest. Everyone here knows how much I like it, but there are always compelling arguments against it especially for web development. This is particularly true for the JS platform where we have to do something like TypeScript has to do in order to introduce the types it needs. It is a costly effort with maintenance and should be considered alongside the benefits of static typing.
There you have it. I’m looking to make the jump from the JVM to Node for my long-term future web adventures. I think that the principle of having one platform for development is just too compelling to ignore. Add to that the fact we have some really strong functional languages targeting JS, I see no reason to continue avoiding it.