If you’re writing a web application, it is likely that you aren’t going to write all the code from scratch – there is a tremendous amount of work that was already done dozens of times and you don’t really want to repeat it. So you’re going to pick a framework – and it isn’t easy! Rails, Hanami, Django, Flask, Express, KOA, Spring, Play, Lift, Phoenix, Revel and dozens of others, most of which I’ve never heard about. Why create next one? There are several reasons, language focus being one of the strongest. Rails, Hanami, Padrino and Volt focuses on Ruby. Django, Flask and Pyramid on Python, Express, KOA and Synth on JavaScript (specifically Node.js), Spring and Struts on Java, Lift and Play on Scala (though Java/Scala framework division is a little artificial, since Play works on Java as well), Phoenix on Elixir, Revel on Go etc. Another one is the focus on programming model – most of the popular frameworks use MVC (Model-View-Controller) approach, but some – like Lift, Wicket or Asta4D – use different, View-First approach. Of course, there are also lots of different reasons – changing some old paradigm, using new language feature, solving a problem other frameworks have for long time or simply “writing a more elegant framework”.
In such a jungle, choosing the best framework for the job is vitually impossible, so we settle for “good enough”. And this usually boils down to choosing one of the most common frameworks – Rails, Django or Express, possibly Spring if your company is Java-inclined, or something from Go if you’re feeling hippie (or maybe Elixir or some other new language if you’re feeling super-hippie).
And it is usually a good decision – not a perfect one, but good. You know the language, you know the framework, you can write code fast. Cool, eh?
Well, yeah. If you’re writing a one-team app or a prototype, or at least an app in write-and-forget mode, then choosing Rails, Express or Django is a great choice. But for bigger projects, well… sure, it’s possible. But if you lack discipline your Sentry (you have Sentry or something similar hookend up on your production servers, right?) will start shouting with things like undefined is not a function
or 'NoneType' object is not callable
. If you have discipline things are slightly better and you simply have to maintain gazillions of unit tests for all weird scenarios where internal flow was not valid or user data was not properly sanitized or whatever. And you usually have to either maintain these unit tests forever, or drop features. What’s worse, these UTs usually aren’t well-written
and are an obstacle for refactoring, while you would want them to aid it. Sounds familiar? Well, bad news then – it’s not a problem of the framework.
There are two main reasons for such situation: one is obviously the development process – with a perfect process and discipline, you can go really far with any tool you want. But using the right tool makes it easier (or at least forces you to keep the discipline). Dynamically typed languages, like Ruby, Python or JavaScript are great for small projects, small teams or prototypes, but on bigger ones well-known problems appear: interfaces. It’s hard to define interface on a language that roughly checks the syntax of the source code – of course, possible, but much harder than in statically typed languages with compilers – like Java, Scala, C++ or Haskell. There are attempts to create things like “JavaScript with types” (TypeScript, Flow), but this simply doesn’t work – it’s a part added artificially to a language after it’s already in the field, and doesn’t really make people happy.
Statically typed languages, on the other hand have another problem – they usually have a steep learning curve, and some of them (for example, Java) require quite some boilerplate to create reasonable applications. Scala with its type-safe approach is much better in the area of enforcing interface contract – value of features like type-safe database queries is hard to overestimate. Scala is quite a new language (started in 2001) with a very interesting paradigm and full power of the JVM behind – it’s really worth checking out.
However, in this series I’m going to focus on a different alternative to Ruby/Python/JS frameworks. One that is considered arcane and hard and has quite a steep learning curve if you have mostly a dynamically-typed background. I’m going to show you how to develop a simple web application in Haskell, by using its arguably biggest web framework – Yesod. If type-safe database access sounds like “wow”, then you’re going to like it – in Yesod even routes are type-safe. And since I’m lazy, I believe in tools imposing as much useful restrictions as possible. Since I believe type-safe stuff to be incredibly useful, I’ve decided to give it a try. This is the first post of a series of introductory posts to Yesod (occassionally also with Haskell insertions). Fun starts next week.
Stay tuned!