You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

2296 lines
80 KiB

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>YBlog - Rational Web Framework Choice</title>
<meta name="keywords" content="programming, framework, web" />
<link rel="shortcut icon" type="image/x-icon" href="../../../../Scratch/img/favicon.ico" />
<link rel="stylesheet" type="text/css" href="/css/y.css" />
<link rel="stylesheet" type="text/css" href="/css/legacy.css" />
<link rel="alternate" type="application/rss+xml" title="RSS" href="/rss.xml" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="apple-touch-icon" href="../../../../Scratch/img/about/FlatAvatar@2x.png" />
<!--[if lt IE 9]>
<script src="http://ie7-js.googlecode.com/svn/version/2.1(beta4)/IE9.js"></script>
<![endif]-->
<!-- IndieAuth -->
<link href="https://twitter.com/yogsototh" rel="me">
<link href="https://github.com/yogsototh" rel="me">
<link href="mailto:yann.esposito@gmail.com" rel="me">
<link rel="pgpkey" href="../../../../pubkey.txt">
</head>
<body lang="en" class="article">
<div id="content">
<div id="header">
<div id="choix">
<span id="choixlang">
<a href="../../../../Scratch/fr/blog/Rational-Web-Framework-Choice/">French</a>
</span>
<span class="tomenu"><a href="#navigation">↓ Menu ↓</a></span>
<span class="flush"></span>
</div>
</div>
<div id="titre">
<h1>Rational Web Framework Choice</h1>
</div>
<div class="flush"></div>
<div id="afterheader" class="article">
<div class="corps">
<div>
<img src="../../../../Scratch/img/blog/Rational-Web-Framework-Choice/battle-of-lepanto-vicentino-andrea.jpg" alt="Main image" />
</div>
<div class="intro">
<p><span class="sc"><abbr title="Too long; didn't read">tl;dr</abbr>: </span> Determine with the most objectivity possible the best(s) web framework(s) depending on your needs. <a href="#the-result">Here are the results</a>. Please note the actual ability to take a rational decision is pretty bad for now.</p>
</div>
<p>This is it.<br />
You’ve got the next big idea.<br />
You just need to make a very simple web application.</p>
<p>It sounds easy! You just need to choose a good modern web framework, when suddenly:</p>
<figure>
<img src="../../../../Scratch/img/blog/Rational-Web-Framework-Choice/choice_paralysis.gif" alt="[Choice Paralysis][choice_paralysis]" />
<figcaption>
<a href="https://en.wikipedia.org/wiki/Analysis_paralysis">Choice Paralysis</a>
</figcaption>
</figure>
<p>After your brain stack overflowed, you decide to use a very simple methodology. Answer two questions:</p>
<p><strong>Which language am I familiar with?<br />
What is the most popular web framework for this language?</strong></p>
<p>Great! This is it.</p>
<p>But, you continually hear this little voice.</p>
<blockquote>
<p><strong>“You didn’t made a bad choice, yes. But …<br />
you hadn’t made the best either.”</strong></p>
</blockquote>
<p>This article try to determine in the most objective and rational way the best(s) web framework(s) depending on your needs. To reach this goal, I will provide a decision tool in the result section.</p>
<p>I will use the following methodology:</p>
<p><strong>Methodology</strong></p>
<ol type="1">
<li>Model how to make choice
<ol type="a">
<li>choose important parameters</li>
<li>organize (hierarchize) them</li>
<li>write down an objective chooser</li>
</ol></li>
<li>Grab objective quantified informations about web frameworks relatively to choosen parameters</li>
<li>Sanitize your data in order to handle imprecisions, lack of informations…</li>
<li>Apply the model of choice to your informations</li>
</ol>
<blockquote>
<p><strong>☞ Important Note</strong><br />
I am far from happy to the actual result. There are a lot of biases, for example in the choice of the parameters. The same can be said about the data I gathered. I am using very imprecise informations. But, as far as I know, this is the only article which use many different parameters to help you choose a web framework.</p>
<p>This is why I made a very flexible decision tool:</p>
<p><a href="#the-result">Decision tool</a>.</p>
</blockquote>
<h2 id="model">Model</h2>
<p>Here are the important features (properties/parameters) I selected to make the choice:</p>
<ol type="1">
<li><em><strong>Popularity</strong></em>, which correlate with:
<ul>
<li>number of tested libraries</li>
<li>facility to find learning material</li>
<li>ability to find another developer to work with</li>
</ul></li>
<li><em><strong>Efficiency</strong></em>, which is generally correlated to:
<ul>
<li>how much processing power you’ll need per user</li>
<li>maintenance price per user</li>
<li>how long the user will wait to see/update data</li>
</ul></li>
<li><em><strong>Expressiveness</strong></em>, which is generally correlated to:
<ul>
<li>faster development</li>
<li>flexibility, adaptability</li>
</ul></li>
<li><em><strong>Robustness</strong></em>, which correlate with:
<ul>
<li>security</li>
<li>fewer bugs</li>
</ul></li>
</ol>
<p>Each feature is quite important and mostly independant from each other. I tried to embrace most important topics concerning web frameworks with these four properties. I am fully concious some people might lack another important feature. Nonetheless the methodology used here can be easily replicated. If you lack an important property add it at will and use this choice method.</p>
<p>Also each feature is very hard to measure with precision. This is why we will only focus on order of magnitude.</p>
<p>For each property a framework could have one of the six possible values: Excellent, Very Good, Good, Medium, Bad or Very Bad</p>
<p>So how to make a decision model from these informations?</p>
<p>One of the most versatile method is to give a weight for each cluster value. And to select the framework maximizing this score:</p>
<pre><code>score(framework) = efficiency + robustness + expressiveness + popularity</code></pre>
<blockquote>
<p>For example:</p>
<table>
<tbody>
<tr class="odd">
<td>Expressiveness</td>
<td style="text-align: right;">10</td>
<td style="text-align: right;">7</td>
<td style="text-align: right;">1</td>
<td style="text-align: right;">-∞</td>
<td style="text-align: right;">-∞</td>
<td style="text-align: right;">-∞</td>
</tr>
<tr class="even">
<td>Popularity</td>
<td style="text-align: right;">5</td>
<td style="text-align: right;">5</td>
<td style="text-align: right;">4</td>
<td style="text-align: right;">3</td>
<td style="text-align: right;">2</td>
<td style="text-align: right;">1</td>
</tr>
<tr class="odd">
<td>Efficiency</td>
<td style="text-align: right;">10</td>
<td style="text-align: right;">8</td>
<td style="text-align: right;">6</td>
<td style="text-align: right;">4</td>
<td style="text-align: right;">2</td>
<td style="text-align: right;">1</td>
</tr>
<tr class="even">
<td>Robustness</td>
<td style="text-align: right;">10</td>
<td style="text-align: right;">8</td>
<td style="text-align: right;">6</td>
<td style="text-align: right;">4</td>
<td style="text-align: right;">2</td>
<td style="text-align: right;">1</td>
</tr>
</tbody>
</table>
<p>Using this weighted table, that means:</p>
<ul>
<li>we discard the three least expressive clusters.</li>
<li>We don’t make any difference between excellent and very good in popularity.</li>
<li>Concerning efficient framework in excellent cluster will have 2 more points than the “very good” cluster.</li>
</ul>
<p>So for each framework we compute its score relatively to a weighted table. And we select the best(s).</p>
<p><strong>Example</strong>: Using this hypothetic framework and the preceeding table.</p>
<table>
<thead>
<tr class="header">
<th></th>
<th>Expressiveness</th>
<th>Popularity</th>
<th>Efficiency</th>
<th>Robustness</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>yog</td>
<td>Excellent</td>
<td>Very Bad</td>
<td>Medium</td>
<td>Very Good</td>
</tr>
</tbody>
</table>
<pre><code>score(yog) = 10 + 0 + 4 + 8 = 22</code></pre>
</blockquote>
<p>Most needs should be expressed by such a weighted table. In the result section, we will discuss this further.</p>
<p>It is now time to try to get these measures.</p>
<h2 id="objective-measures">Objective measures</h2>
<p>None of the four properties I choosen can be measured with perfect precision. But we could get the order of magnitude for each.</p>
<p>I tried to focus on the framework only. But it is often easier to start by studying the language first.</p>
<p>For example, I have datas about popularity by language and I also have different datas concerning popularity by framework. Even if I use only the framework focused datas in my final decision model, it seemed important to me to discuss about the datas for the languages. The goal is to provide a tool to help decision not to give a decision for you.</p>
<h3 id="popularity">Popularity</h3>
<p><a href="http://redmonk.com/sogrady/2013/02/28/language-rankings-1-13/">RedMonk Programming Language Rankings (January 2013)</a> provide an apparent good measure of popularity. While not perfect the current measure feel mostly right. They create an image using stack overflow and github data. Vertical correspond to the number of questions on stackoverflow. Horizontal correspond to the number of projects on github.</p>
<p>If you look at the image, your eye can see about four clusters. The 1<sup></sup> cluster correspond to mainstream languages:</p>
<figure>
<img src="../../../../Scratch/img/blog/Rational-Web-Framework-Choice/mainstreamlanguages.png" alt="Mainstream Languages Cluster from [RedMonk][redmonk]" />
<figcaption>
Mainstream Languages Cluster from <a href="http://redmonk.com/sogrady/2013/02/28/language-rankings-1-13/">RedMonk</a>
</figcaption>
</figure>
<p>Most developer know at least one of these language.</p>
<p>The second cluster is quite bigger. It seems to correspond to languages with a solid community behind them.</p>
<figure>
<img src="../../../../Scratch/img/blog/Rational-Web-Framework-Choice/secondtierlanguages.png" alt="Second tier languages from [RedMonk][redmonk]" />
<figcaption>
Second tier languages from <a href="http://redmonk.com/sogrady/2013/02/28/language-rankings-1-13/">RedMonk</a>
</figcaption>
</figure>
<p>I don’t get into detail, but you could also see third and fourth tier popular languages.</p>
<p>So:</p>
<p><strong>Mainstream</strong>: JavaScript, Java, PHP, Python, Ruby, <code>C#</code>, <code>C++</code>, <code>C</code>, Objective-C, Perl, Shell</p>
<p><strong>Good</strong>: Scala, Haskell, Visual Basic, Assembly, R, Matlab, ASP, ActionScript, Coffeescript, Groovy, Clojure, Lua, Prolog</p>
<p><strong>Medium</strong>: Erlang, Go, Delphi, D, Racket, Scheme, ColdFusion, F#, FORTRAN, Arduino, Tcl, Ocaml</p>
<p><strong>Bad</strong>: third tier <strong>Very Bad</strong>: fourth tier</p>
<p>I don’t thing I could find easily web frameworks for third or fourth tier languages.</p>
<p>For now, I only talked about language popularity. But what about framework popularity? I made a test using number of question on stackoverflow only. Then by dividing by two for each 6 cluster:</p>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Cluster</th>
<th style="text-align: left;">Language</th>
<th style="text-align: left;">Framework</th>
<th style="text-align: right;">#nb</th>
<th style="text-align: right;">%</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Excellent</td>
<td style="text-align: left;">Ruby</td>
<td style="text-align: left;">Rails</td>
<td style="text-align: right;">176208</td>
<td style="text-align: right;">100%</td>
</tr>
<tr class="even">
<td style="text-align: left;">Very Good</td>
<td style="text-align: left;">Python</td>
<td style="text-align: left;">Django</td>
<td style="text-align: right;">57385</td>
<td style="text-align: right;">&lt;50%</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Java</td>
<td style="text-align: left;">Servlet</td>
<td style="text-align: right;">54139</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Java</td>
<td style="text-align: left;">Spring</td>
<td style="text-align: right;">31641</td>
<td style="text-align: right;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Node.js</td>
<td style="text-align: left;">node.js</td>
<td style="text-align: right;">27243</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">Codeigniter</td>
<td style="text-align: right;">21503</td>
<td style="text-align: right;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Groovy</td>
<td style="text-align: left;">Grails</td>
<td style="text-align: right;">20222</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td style="text-align: left;">Good</td>
<td style="text-align: left;">Ruby</td>
<td style="text-align: left;">Sinatra</td>
<td style="text-align: right;">8631</td>
<td style="text-align: right;">&lt;25%</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Python</td>
<td style="text-align: left;">Flask</td>
<td style="text-align: right;">7062</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">Laravel</td>
<td style="text-align: right;">6982</td>
<td style="text-align: right;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">Kohana</td>
<td style="text-align: right;">5959</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Node.js</td>
<td style="text-align: left;">Express</td>
<td style="text-align: right;">5009</td>
<td style="text-align: right;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Medium</td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">Cake</td>
<td style="text-align: right;">4554</td>
<td style="text-align: right;">&lt;13%</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">C♯</td>
<td style="text-align: left;">ServiceStack</td>
<td style="text-align: right;">3838</td>
<td style="text-align: right;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Scala</td>
<td style="text-align: left;">Play</td>
<td style="text-align: right;">3823</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Java</td>
<td style="text-align: left;">Wicket</td>
<td style="text-align: right;">3819</td>
<td style="text-align: right;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Dart</td>
<td style="text-align: left;">Dart</td>
<td style="text-align: right;">3753</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">Slim</td>
<td style="text-align: right;">3361</td>
<td style="text-align: right;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Python</td>
<td style="text-align: left;">Tornado</td>
<td style="text-align: right;">3321</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Scala</td>
<td style="text-align: left;">Lift</td>
<td style="text-align: right;">2844</td>
<td style="text-align: right;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Go</td>
<td style="text-align: left;">Go</td>
<td style="text-align: right;">2689</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td style="text-align: left;">Bad</td>
<td style="text-align: left;">Java</td>
<td style="text-align: left;">Tapestry</td>
<td style="text-align: right;">1197</td>
<td style="text-align: right;">&lt;6%</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">C♯</td>
<td style="text-align: left;">aspnet</td>
<td style="text-align: right;">1000</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Haskell</td>
<td style="text-align: left;">Yesod</td>
<td style="text-align: right;">889</td>
<td style="text-align: right;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">Silex</td>
<td style="text-align: right;">750</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">Lithium</td>
<td style="text-align: right;">732</td>
<td style="text-align: right;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">C♯</td>
<td style="text-align: left;">nancy</td>
<td style="text-align: right;">705</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td style="text-align: left;">Very bad</td>
<td style="text-align: left;">Java</td>
<td style="text-align: left;">Grizzly</td>
<td style="text-align: right;">622</td>
<td style="text-align: right;">&lt;3%</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Erlang</td>
<td style="text-align: left;">Cowboy</td>
<td style="text-align: right;">568</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Perl</td>
<td style="text-align: left;">Dancer</td>
<td style="text-align: right;">496</td>
<td style="text-align: right;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">Symphony2</td>
<td style="text-align: right;">491</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Go</td>
<td style="text-align: left;">Revel</td>
<td style="text-align: right;">459</td>
<td style="text-align: right;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Clojure</td>
<td style="text-align: left;">Compojure</td>
<td style="text-align: right;">391</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Perl</td>
<td style="text-align: left;">Mojolicious</td>
<td style="text-align: right;">376</td>
<td style="text-align: right;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Scala</td>
<td style="text-align: left;">Scalatra</td>
<td style="text-align: right;">349</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Scala</td>
<td style="text-align: left;">Finagle</td>
<td style="text-align: right;">336</td>
<td style="text-align: right;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">Phalcon</td>
<td style="text-align: right;">299</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">js</td>
<td style="text-align: left;">Ringo</td>
<td style="text-align: right;">299</td>
<td style="text-align: right;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Java</td>
<td style="text-align: left;">Gemini</td>
<td style="text-align: right;">276</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Haskell</td>
<td style="text-align: left;">Snap</td>
<td style="text-align: right;">263</td>
<td style="text-align: right;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Perl</td>
<td style="text-align: left;">Plack</td>
<td style="text-align: right;">257</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Erlang</td>
<td style="text-align: left;">Elli</td>
<td style="text-align: right;">230</td>
<td style="text-align: right;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Java</td>
<td style="text-align: left;">Dropwizard</td>
<td style="text-align: right;">188</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">Yaf</td>
<td style="text-align: right;">146</td>
<td style="text-align: right;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Java</td>
<td style="text-align: left;">Play1</td>
<td style="text-align: right;">133</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Node.js</td>
<td style="text-align: left;">Hapi</td>
<td style="text-align: right;">131</td>
<td style="text-align: right;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Java</td>
<td style="text-align: left;">Vertx</td>
<td style="text-align: right;">60</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Scala</td>
<td style="text-align: left;">Unfiltered</td>
<td style="text-align: right;">42</td>
<td style="text-align: right;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">C</td>
<td style="text-align: left;">onion</td>
<td style="text-align: right;">18</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Clojure</td>
<td style="text-align: left;">http-kit</td>
<td style="text-align: right;">17</td>
<td style="text-align: right;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Perl</td>
<td style="text-align: left;">Kelp</td>
<td style="text-align: right;">16</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">Micromvc</td>
<td style="text-align: right;">13</td>
<td style="text-align: right;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Lua</td>
<td style="text-align: left;">Openresty</td>
<td style="text-align: right;">8</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">C++</td>
<td style="text-align: left;">cpoll-cppsp</td>
<td style="text-align: right;">5</td>
<td style="text-align: right;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Clojure</td>
<td style="text-align: left;">Luminus</td>
<td style="text-align: right;">3</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">Phreeze</td>
<td style="text-align: right;">1</td>
<td style="text-align: right;"></td>
</tr>
</tbody>
</table>
<p>As we can see, our framework popularity indicator can be quite different from its language popularity. For now I didn’t found a nice way to merge the results from RedMonk with these one. So I’ll use these unperfect one. Hopefully the order of magninute is mostly correct for most framework.</p>
<h3 id="efficiency">Efficiency</h3>
<p>Another objective measure is efficiency. We all know benchmarks are all flawed. But they are the only indicators concerning efficiency we have.</p>
<p>I used the benchmark from <a href="http://benchmarksgame.alioth.debian.org/u64q/benchmark.php?test=all&amp;lang=all&amp;data=u64q">benchmarksgame</a>. Mainly, there are five clusters:</p>
<table>
<tbody>
<tr class="odd">
<td style="text-align: left;">1x→2x</td>
<td style="text-align: left;"><code>C</code>, <code>C++</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">2x→3x</td>
<td style="text-align: left;">Java 7, Scala, OCamL, Haskell, Go, Common LISP</td>
</tr>
<tr class="odd">
<td style="text-align: left;">3x→10x</td>
<td style="text-align: left;">C♯, Clojure, Racket, Dart</td>
</tr>
<tr class="even">
<td style="text-align: left;">10x→30x</td>
<td style="text-align: left;">Erlang</td>
</tr>
<tr class="odd">
<td style="text-align: left;">30x→</td>
<td style="text-align: left;">PHP, Python, Perl, Ruby, JRuby</td>
</tr>
</tbody>
</table>
<p>Remarks concerning some very slow languages:</p>
<ul>
<li>PHP ; huge variations, can be about 1.5x C speed in best case.</li>
<li>Python ; huge variations, can be about 1.5x C speed in best case</li>
<li>Perl ; Can be about 3x C speed in best case</li>
<li>Ruby, JRuby ; mostly very slow.</li>
</ul>
<p>This is a first approach. The speed of the language for basic benchmarks. But, here we are interrested in web programming. Fortunately techempower has made some tests focused on most web frameworks:</p>
<p><a href="http://www.techempower.com/blog/2013/07/02/frameworks-round-6/">Web framework benchmarks</a>.</p>
<p>These benchmark doesn’t fit well with our needs. The values are certainly quite imprecise to your real usage. The goal is just to get an order of magnitude for each framework. Another problem is the high number of informations.</p>
<p>As always, we should remember these informations are also imprecise. So I simply made some classes of efficiency.</p>
<p>Remark: I separated the clusters by using power of 2 relatively to the fastest.</p>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Cluster</th>
<th style="text-align: left;">Language</th>
<th style="text-align: left;">Framework</th>
<th style="text-align: center;">#nb</th>
<th style="text-align: left;">slowness</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Excellent</td>
<td style="text-align: left;">C++</td>
<td style="text-align: left;">cpoll-cppsp</td>
<td style="text-align: center;">114,711</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">gemini</td>
<td style="text-align: center;">105,204</td>
<td style="text-align: left;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Lua</td>
<td style="text-align: left;">openresty</td>
<td style="text-align: center;">93,882</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">servlet</td>
<td style="text-align: center;">90,580</td>
<td style="text-align: left;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">C++</td>
<td style="text-align: left;">cpoll-pool</td>
<td style="text-align: center;">89,167</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Go</td>
<td style="text-align: left;">go</td>
<td style="text-align: center;">76,024</td>
<td style="text-align: left;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Sca</td>
<td style="text-align: left;">finagle</td>
<td style="text-align: center;">68,413</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Go</td>
<td style="text-align: left;">revel</td>
<td style="text-align: center;">66,990</td>
<td style="text-align: left;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">rest-express</td>
<td style="text-align: center;">63,209</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;">Very Good</td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">wicket</td>
<td style="text-align: center;">48,772</td>
<td style="text-align: left;">&gt;</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Sca</td>
<td style="text-align: left;">scalatra</td>
<td style="text-align: center;">48,594</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Clj</td>
<td style="text-align: left;">http-kit</td>
<td style="text-align: center;">42,703</td>
<td style="text-align: left;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">spring</td>
<td style="text-align: center;">36,643</td>
<td style="text-align: left;">&gt;</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">php</td>
<td style="text-align: center;">36,605</td>
<td style="text-align: left;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">tapestry</td>
<td style="text-align: center;">35,032</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Clj</td>
<td style="text-align: left;">compojure</td>
<td style="text-align: center;">32,088</td>
<td style="text-align: left;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">JS</td>
<td style="text-align: left;">ringo</td>
<td style="text-align: center;">31,962</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">dropwizard</td>
<td style="text-align: center;">31,514</td>
<td style="text-align: left;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Clj</td>
<td style="text-align: left;">luminus</td>
<td style="text-align: center;">30,672</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;">Good</td>
<td style="text-align: left;">Sca</td>
<td style="text-align: left;">play-slick</td>
<td style="text-align: center;">29,950</td>
<td style="text-align: left;">&gt;</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Sca</td>
<td style="text-align: left;">unfiltered</td>
<td style="text-align: center;">29,782</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Erl</td>
<td style="text-align: left;">elli</td>
<td style="text-align: center;">28,862</td>
<td style="text-align: left;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">vertx</td>
<td style="text-align: center;">28,075</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">JS</td>
<td style="text-align: left;">nodejs</td>
<td style="text-align: center;">27,598</td>
<td style="text-align: left;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Erl</td>
<td style="text-align: left;">cowboy</td>
<td style="text-align: center;">24,669</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">C</td>
<td style="text-align: left;">onion</td>
<td style="text-align: center;">23,649</td>
<td style="text-align: left;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Hkl</td>
<td style="text-align: left;">yesod</td>
<td style="text-align: center;">23,304</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">JS</td>
<td style="text-align: left;">express</td>
<td style="text-align: center;">22,856</td>
<td style="text-align: left;">&gt;</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Sca</td>
<td style="text-align: left;">play-scala</td>
<td style="text-align: center;">22,372</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav g</td>
<td style="text-align: left;">rizzly-jersey</td>
<td style="text-align: center;">20,550</td>
<td style="text-align: left;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Py</td>
<td style="text-align: left;">tornado</td>
<td style="text-align: center;">20,372</td>
<td style="text-align: left;">&gt;</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">phalcon</td>
<td style="text-align: center;">18,481</td>
<td style="text-align: left;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Grv</td>
<td style="text-align: left;">grails</td>
<td style="text-align: center;">18,467</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Prl</td>
<td style="text-align: left;">plack</td>
<td style="text-align: center;">16,647</td>
<td style="text-align: left;">&gt;</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">yaf</td>
<td style="text-align: center;">14,388</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;">Medium</td>
<td style="text-align: left;">JS</td>
<td style="text-align: left;">hapi</td>
<td style="text-align: center;">11,235</td>
<td style="text-align: left;">&gt;10×</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">play1</td>
<td style="text-align: center;">9,979</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Hkl</td>
<td style="text-align: left;">snap</td>
<td style="text-align: center;">9,196</td>
<td style="text-align: left;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Prl</td>
<td style="text-align: left;">kelp</td>
<td style="text-align: center;">8,250</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Py</td>
<td style="text-align: left;">flask</td>
<td style="text-align: center;">8,167</td>
<td style="text-align: left;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">play-java</td>
<td style="text-align: center;">7,905</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav p</td>
<td style="text-align: left;">lay-java-jpa</td>
<td style="text-align: center;">7,846</td>
<td style="text-align: left;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">micromvc</td>
<td style="text-align: center;">7,387</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Prl</td>
<td style="text-align: left;">dancer</td>
<td style="text-align: center;">5,040</td>
<td style="text-align: left;">&gt;20×</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Prl</td>
<td style="text-align: left;">mojolicious</td>
<td style="text-align: center;">4,371</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">JS</td>
<td style="text-align: left;">ringo-conv</td>
<td style="text-align: center;">4,249</td>
<td style="text-align: left;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Py</td>
<td style="text-align: left;">django</td>
<td style="text-align: center;">4,026</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">codeigniter</td>
<td style="text-align: center;">3,809</td>
<td style="text-align: left;">&gt;30×</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Bad</td>
<td style="text-align: left;">Rby</td>
<td style="text-align: left;">rails</td>
<td style="text-align: center;">3,445</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Sca</td>
<td style="text-align: left;">lift</td>
<td style="text-align: center;">3,311</td>
<td style="text-align: left;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">slim</td>
<td style="text-align: center;">3,112</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">kohana</td>
<td style="text-align: center;">2,378</td>
<td style="text-align: left;">&gt;40×</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">silex</td>
<td style="text-align: center;">2,364</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;">Very Bad</td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">laravel</td>
<td style="text-align: center;">1,639</td>
<td style="text-align: left;">&gt;60×</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">phreeze</td>
<td style="text-align: center;">1,410</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">lithium</td>
<td style="text-align: center;">1,410</td>
<td style="text-align: left;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">fuel</td>
<td style="text-align: center;">1,410</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">cake</td>
<td style="text-align: center;">1,287</td>
<td style="text-align: left;">&gt;80×</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">symfony2</td>
<td style="text-align: center;">879</td>
<td style="text-align: left;">&gt;100×</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">C#</td>
<td style="text-align: left;">aspnet-mvc</td>
<td style="text-align: center;">871</td>
<td style="text-align: left;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Rby</td>
<td style="text-align: left;">sinatra</td>
<td style="text-align: center;">561</td>
<td style="text-align: left;">&gt;200×</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">C#</td>
<td style="text-align: left;">servicestack</td>
<td style="text-align: center;">51</td>
<td style="text-align: left;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Dar</td>
<td style="text-align: left;">dart</td>
<td style="text-align: center;">0</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">C#</td>
<td style="text-align: left;">nancy</td>
<td style="text-align: center;">0</td>
<td style="text-align: left;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Prl</td>
<td style="text-align: left;">web-simple</td>
<td style="text-align: center;">0</td>
<td style="text-align: left;"></td>
</tr>
</tbody>
</table>
<p>These are manually made clusters. But you get the idea. Certainly, some framework could jump between two different clusters. So this is something to remember. But as always, the order of magnitude is certainly mostly right.</p>
<h1 id="expressiveness">Expressiveness</h1>
<p>Now, how to objectively measure expressiveness?</p>
<p>RedMonk had a very good idea to find an objective (while imprecise) measure of each language expressiveness. Read this <a href="http://redmonk.com/dberkholz/2013/03/25/programming-languages-ranked-by-expressiveness/">article</a> for details.</p>
<p>After filtering languages suitable for web development, we end up with some clusters:</p>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Cluster</th>
<th style="text-align: left;">Languages</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Excellent</td>
<td style="text-align: left;">Coffeescript, Clojure, Haskell</td>
</tr>
<tr class="even">
<td style="text-align: left;">Very Good</td>
<td style="text-align: left;">Racket, Groovy, R, Scala, OCamL, F♯, Erlang, Lisp, Go</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Medium</td>
<td style="text-align: left;">Perl, Python, Objective-C, Scheme, Tcl, Ruby</td>
</tr>
<tr class="even">
<td style="text-align: left;">Bad</td>
<td style="text-align: left;">Lua, Fortran (free-format), PHP, Java, C++, C♯</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Very Bad</td>
<td style="text-align: left;">Assembly, C, Javascript,</td>
</tr>
</tbody>
</table>
<p>Unfortunately there is no information about dart. So I simply give a very fast look at the syntax. As it looked a lot like javascript and js is quite low. I decided to put it close to java.</p>
<p>Also an important remark, javascript score very badly here while coffeescript (compiling to js) score “excellent”. So if you intend to use a javascript framework but only with coffescript that should change substantially the score. As I don’t believe it is the standard. Javascript oriented framework score very badly regarding expressiveness.</p>
<div id="toggle-expressiveness-table" class="button">
<span>Click here to show/hide the table for frameworks</span>
</div>
<div id="expressiveness-table">
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Cluster</th>
<th style="text-align: left;">Language</th>
<th style="text-align: left;">Framework</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Excellent</td>
<td style="text-align: left;">Clj</td>
<td style="text-align: left;">luminus</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Clj</td>
<td style="text-align: left;">http-kit</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Clj</td>
<td style="text-align: left;">compojure</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Hkl</td>
<td style="text-align: left;">snap</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Hkl</td>
<td style="text-align: left;">yesod</td>
</tr>
<tr class="even">
<td style="text-align: left;">Very Good</td>
<td style="text-align: left;">Erl</td>
<td style="text-align: left;">elli</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Erl</td>
<td style="text-align: left;">cowboy</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Go</td>
<td style="text-align: left;">go</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Go</td>
<td style="text-align: left;">revel</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Grv</td>
<td style="text-align: left;">grails</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Sca</td>
<td style="text-align: left;">lift</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Sca</td>
<td style="text-align: left;">finagle</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Sca</td>
<td style="text-align: left;">scalatra</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Sca</td>
<td style="text-align: left;">play-scala</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Sca</td>
<td style="text-align: left;">play-slick</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Sca</td>
<td style="text-align: left;">unfiltered</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Medium</td>
<td style="text-align: left;">Prl</td>
<td style="text-align: left;">kelp</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Prl</td>
<td style="text-align: left;">plack</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Prl</td>
<td style="text-align: left;">dancer</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Prl</td>
<td style="text-align: left;">web-simple</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Prl</td>
<td style="text-align: left;">mojolicious</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Py</td>
<td style="text-align: left;">flask</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Py</td>
<td style="text-align: left;">django</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Py</td>
<td style="text-align: left;">tornado</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Rby</td>
<td style="text-align: left;">rails</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Rby</td>
<td style="text-align: left;">sinatra</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Bad</td>
<td style="text-align: left;">C#</td>
<td style="text-align: left;">nancy</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">C#</td>
<td style="text-align: left;">aspnet-mvc</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">C#</td>
<td style="text-align: left;">servicestack</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">C++</td>
<td style="text-align: left;">cpoll-pool</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">C++</td>
<td style="text-align: left;">cpoll-cppsp</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Dar</td>
<td style="text-align: left;">dart</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">play1</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">vertx</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">gemini</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">spring</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">wicket</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">servlet</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">tapestry</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">play-java</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">dropwizard</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">rest-express</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">play-java-jpa</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">grizzly-jersey</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Lua</td>
<td style="text-align: left;">openresty</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">php</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">yaf</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">cake</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">fuel</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">slim</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">silex</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">kohana</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">laravel</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">lithium</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">phalcon</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">phreeze</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">micromvc</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">symfony2</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">codeigniter</td>
</tr>
<tr class="even">
<td style="text-align: left;">Very Bad</td>
<td style="text-align: left;">C</td>
<td style="text-align: left;">onion</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">JS</td>
<td style="text-align: left;">hapi</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">JS</td>
<td style="text-align: left;">ringo</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">JS</td>
<td style="text-align: left;">nodejs</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">JS</td>
<td style="text-align: left;">express</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">JS</td>
<td style="text-align: left;">ringo-conv</td>
</tr>
</tbody>
</table>
</div>
<h3 id="robustness">Robustness</h3>
<p>I couldn’t find any complete study to give the number of bug relatively to each framework/language.</p>
<p>But one thing I saw from experience is the more powerful the type system the safest your application is. While the type system doesn’t remove completely the need to test your application a very good type system tend to remove complete classes of bug.</p>
<p>Typically, not using pointer help to reduce the number of bugs due to bad references. Also, using a garbage collector, reduce greatly the probability to access unallocated space.</p>
<figure>
<img src="../../../../Scratch/img/blog/Rational-Web-Framework-Choice/languagesafety.png" alt="Static Type Properties from [James IRY Blog][typesanalysis]" />
<figcaption>
Static Type Properties from <a href="http://james-iry.blogspot.fr/2010/05/types-la-chart.html">James IRY Blog</a>
</figcaption>
</figure>
<p>From my point of view, robustness is mostly identical to safety.</p>
<p>Here are the clusters:</p>
<table>
<tbody>
<tr class="odd">
<td style="text-align: left;">Excellent</td>
<td>Haskell, Scheme, Erlang</td>
</tr>
<tr class="even">
<td style="text-align: left;">Very Good</td>
<td>Scala, Java, Clojure</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Good</td>
<td>Ruby, Python, Groovy, javascript, PHP</td>
</tr>
<tr class="even">
<td style="text-align: left;">Medium</td>
<td>C++, C#, Perl, Objective-C, Go, C</td>
</tr>
</tbody>
</table>
<p>So applying this to frameworks gives the following clusters:</p>
<div id="toggle-robustness-table" class="button">
<span>Click here to show/hide the table for frameworks</span>
</div>
<div id="robustness-table">
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Cluster</th>
<th style="text-align: left;">Language</th>
<th style="text-align: left;">Framework</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Excellent</td>
<td style="text-align: left;">Erl</td>
<td style="text-align: left;">elli</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Erl</td>
<td style="text-align: left;">cowboy</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Hkl</td>
<td style="text-align: left;">snap</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Hkl</td>
<td style="text-align: left;">yesod</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Very Good</td>
<td style="text-align: left;">Clj</td>
<td style="text-align: left;">luminus</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Clj</td>
<td style="text-align: left;">http-kit</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Clj</td>
<td style="text-align: left;">compojure</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">play1</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">vertx</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">gemini</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">spring</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">wicket</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">servlet</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">tapestry</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">play-java</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">dropwizard</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">rest-express</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">play-java-jpa</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Jav</td>
<td style="text-align: left;">grizzly-jersey</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Sca</td>
<td style="text-align: left;">lift</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Sca</td>
<td style="text-align: left;">finagle</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Sca</td>
<td style="text-align: left;">scalatra</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Sca</td>
<td style="text-align: left;">play-scala</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Sca</td>
<td style="text-align: left;">play-slick</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Sca</td>
<td style="text-align: left;">unfiltered</td>
</tr>
<tr class="even">
<td style="text-align: left;">Good</td>
<td style="text-align: left;">Grv</td>
<td style="text-align: left;">grails</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">JS</td>
<td style="text-align: left;">hapi</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">JS</td>
<td style="text-align: left;">ringo</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">JS</td>
<td style="text-align: left;">nodejs</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">JS</td>
<td style="text-align: left;">express</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">JS</td>
<td style="text-align: left;">ringo-conv</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Lua</td>
<td style="text-align: left;">openresty</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">php</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">yaf</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">cake</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">fuel</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">slim</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">silex</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">kohana</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">laravel</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">lithium</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">phalcon</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">phreeze</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">micromvc</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">symfony2</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">PHP</td>
<td style="text-align: left;">codeigniter</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Py</td>
<td style="text-align: left;">flask</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Py</td>
<td style="text-align: left;">django</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Py</td>
<td style="text-align: left;">tornado</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Rby</td>
<td style="text-align: left;">rails</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Rby</td>
<td style="text-align: left;">sinatra</td>
</tr>
<tr class="even">
<td style="text-align: left;">Medium</td>
<td style="text-align: left;">C</td>
<td style="text-align: left;">onion</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">C#</td>
<td style="text-align: left;">nancy</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">C#</td>
<td style="text-align: left;">aspnet-mvc</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">C#</td>
<td style="text-align: left;">servicestack</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">C++</td>
<td style="text-align: left;">cpoll-pool</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">C++</td>
<td style="text-align: left;">cpoll-cppsp</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Dar</td>
<td style="text-align: left;">dart</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Go</td>
<td style="text-align: left;">go</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Go</td>
<td style="text-align: left;">revel</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Prl</td>
<td style="text-align: left;">kelp</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Prl</td>
<td style="text-align: left;">plack</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Prl</td>
<td style="text-align: left;">dancer</td>
</tr>
<tr class="even">
<td style="text-align: left;"></td>
<td style="text-align: left;">Prl</td>
<td style="text-align: left;">web-simple</td>
</tr>
<tr class="odd">
<td style="text-align: left;"></td>
<td style="text-align: left;">Prl</td>
<td style="text-align: left;">mojolicious</td>
</tr>
</tbody>
</table>
</div>
<h2 id="the-result">The result</h2>
<p>For the result I initialized the table with my own needs.</p>
<p>And I am quite happy it confirms my current choice. I sware I didn’t given yesod any bonus point. I tried to be the most objective and factual as possible.</p>
<p>Now, it is up to you to enter your preferences.</p>
<p>On each line you could change how important a feature is for you. From essential to unsignificant. Of course you could change the matrix at will.</p>
<p>I just show a top 10 frameworks. In order to give a more understandable measure I provide the log of the score.</p>
<table id="choice-matrix">
<tr>
<th>
</th>
<th>
Excellent
</th>
<th>
Very good
</th>
<th>
Good
</th>
<th>
Medium
</th>
<th>
Bad
</th>
<th>
Very bad
</th>
<th>
Importance
</th>
</tr>
<tr id="t-expressiveness">
<th>
Expressiveness
</th>
</tr>
<tr id="t-popularity">
<th>
Popularity
</th>
</tr>
<tr id="t-efficiency">
<th>
Efficiency
</th>
</tr>
<tr id="t-robustness">
<th>
Robustness
</th>
</tr>
</table>
<div id="compute" class="button">
<span>Click to force refresh</span>
</div>
<div id="result">
</div>
<script>// <![CDATA[ // <![CDATA[
function lt(x,y){return (x < y);}
function bal(balname,str){return '<'+balname+'>'+str+'</'+balname+'>';}
function ret(){return '<br/>';}
// ]]> // ]]></script>
<script>// <![CDATA[
String.prototype.repeat = function(num){return new Array(num+1).join(this);};
(function(){function run(){if (window.$){
var languageOf={};
languageOf["elli"]="Erlang";
languageOf["cowboy"]="Erlang";
languageOf["snap"]="Haskell";
languageOf["yesod"]="Haskell";
languageOf["luminus"]="Clojure";
languageOf["http-kit"]="Clojure";
languageOf["compojure"]="Clojure";
languageOf["play1"]="Java";
languageOf["vertx"]="Java";
languageOf["gemini"]="Java";
languageOf["spring"]="Java";
languageOf["wicket"]="Java";
languageOf["servlet"]="Java";
languageOf["tapestry"]="Java";
languageOf["play-java"]="Java";
languageOf["dropwizard"]="Java";
languageOf["rest-express"]="Java";
languageOf["play-java-jpa"]="Java";
languageOf["grizzly-jersey"]="Java";
languageOf["lift"]="Scala";
languageOf["finagle"]="Scala";
languageOf["scalatra"]="Scala";
languageOf["play-scala"]="Scala";
languageOf["play-slick"]="Scala";
languageOf["unfiltered"]="Scala";
languageOf["grails"]="Groovy";
languageOf["hapi"]="javascript";
languageOf["ringo"]="javascript";
languageOf["nodejs"]="javascript";
languageOf["express"]="javascript";
languageOf["ringo-conv"]="javascript";
languageOf["openresty"]="Lua";
languageOf["php"]="PHP";
languageOf["yaf"]="PHP";
languageOf["cake"]="PHP";
languageOf["fuel"]="PHP";
languageOf["slim"]="PHP";
languageOf["silex"]="PHP";
languageOf["kohana"]="PHP";
languageOf["laravel"]="PHP";
languageOf["lithium"]="PHP";
languageOf["phalcon"]="PHP";
languageOf["phreeze"]="PHP";
languageOf["micromvc"]="PHP";
languageOf["symfony2"]="PHP";
languageOf["codeigniter"]="PHP";
languageOf["flask"]="Python";
languageOf["django"]="Python";
languageOf["tornado"]="Python";
languageOf["rails"]="Ruby";
languageOf["sinatra"]="Ruby";
languageOf["onion"]="C";
languageOf["nancy"]="C#";
languageOf["aspnet-mvc"]="C#";
languageOf["servicestack"]="C#";
languageOf["cpoll-pool"]="C++";
languageOf["cpoll-cppsp"]="C++";
languageOf["dart"]="Dart";
languageOf["go"]=" Go";
languageOf["revel"]=" Go";
languageOf["kelp"]="Perl";
languageOf["plack"]="Perl";
languageOf["dancer"]="Perl";
languageOf["web-simple"]="Perl";
languageOf["mojolicious"]="Perl";
popularityClusters=[[ "rails", "php"
],[ "django" , "servlet" , "spring" , "nodejs" , "codeigniter" , "grails"
],[ "sinatra" , "flask" , "laravel" , "kohana" , "rest-express", "express"
],[ "cake" , "servicestack" , "play-java", "play-slick"
, "wicket" , "dart" , "slim" , "tornado" , "lift" , "go"
],[ "tapestry" , "aspnet-mvc" , "yesod" , "silex" , "lithium" , "nancy"
],[ "grizzly" , "cowboy" , "dancer" , "symfony2" , "revel"
, "compojure" , "mojolicious" , "scalatra" , "finagle" , "phalcon"
, "ringo" , "gemini" , "snap" , "plack" , "elli" , "dropwizard"
, "yaf" , "play1" , "hapi" , "vertx" , "unfiltered" , "onion"
, "http-kit" , "kelp" , "micromvc" , "openresty" , "cpoll-pool"
, "cpoll-cppsp" , "luminus" , "phreeze"
]];
efficiencyClusters=[[ "cpoll-cppsp" , "gemini" , "openresty" , "servlet"
, "cpoll-pool" , "go" , "finagle" , "revel" , "rest-express"
],[ "wicket" , "scalatra" , "http-kit" , "spring" , "php" , "tapestry"
, "compojure" , "ringo" , "dropwizard" , "luminus"
],[ "play-slick" , "unfiltered" , "elli" , "vertx" , "nodejs" , "cowboy"
, "onion" , "yesod" , "express" , "play-scala" , "grizzly"
, "tornado" , "phalcon" , "grails" , "plack" , "yaf"
],[ "hapi" , "play1" , "snap" , "kelp" , "flask" , "play-java"
, "play-java-jpa" , "micromvc" , "dancer" , "mojolicious" , "ringo-conv"
, "django" , "codeigniter"
],[ "rails" , "lift" , "slim" , "kohana" , "silex"
],[ "laravel" , "phreeze" , "lithium" , "fuel" , "cake" , "symfony2"
, "aspnet-mvc" , "sinatra" , "servicestack" , "dart" , "nancy" , "web-simple"
]];
expressivenessClusters=[[
"luminus" , "http-kit" , "compojure"</