What should be my lingua franca of programming?

In a fast paced business environment with fast changing requirements, the tools for expressing and constructing a program become extremely vital for the productivity of the programmer. Given this assumption, the primary of these tools, the choice of programming language becomes extremely essential for productivity. Having worked in C and C++ and having seen a host of different languages I have formed a vague idea of where I am headed next. My attempt is to find out which language should be my lingua-franca of programming.

I am a clear advocate of the horses for courses philosophy, however, it is also important to work with a language that best shapes my thinking. I have here a list of languages I am acquainted with and hopefully a choice emerges and hope that one of these quickly becomes an arrow in my quiver (that I am able to build at least something substantial and useful with it). I had scribbled down the following languages and their pros and cons and hope to master one of them by the end of the year (a 10000 hours later…). Each of these languages have already been used in production and proved their value well already for other companies.

Here is my humble attempt to deconstruct the pros and cons of each language and use one of them before jumping headlong into one.


Erlang

The grand daddy of all the “Programming in the Large” languages. In spite of its quirky syntax (read non-C typish), it is a revelation to work in a language where there is no mutability. In fact, once I worked in Erlang, it has forever changed my way of thinking about data problems. My typical PHP or Python code is now littered with a lot of small functions returning tuples where earlier I was prone to over-engineer with a lot of classes.

Killer app

  • ejabberd (/mongooseIM) – XMPP
  • CouchDB
  • Riak

Pros

  • Immutable programming model
  • Modules + Function overloading
  • Good set of BIFs
  • Interop with C (performance optimization)
  • Robust and scalable with OTP
  • REPL

Cons

  • Weird syntax (non Cish) – strict naming conventions (might be a win actually) – Elixir might be a big win here actually!
  • Low real world usage (might be an offshoot from above)
  • Slow
  • Not so great plugins for common usecases (webapps) – mysql

Scala

Scalable language or Scala we call is one of those languages which target the JVM directly. And being a hybrid language, it has found good reception among codistas.

Killer app

  • Play
  • Twitter – Finagle
  • Typesafe platform

Pros

  • Java interop – so support for Netty is directly available – Batteries included
  • LISP + Object oriented + Functional = multi-paradigm language
  • REPL
  • Touted as the future of Java
  • Compiles to Java bytecode so almost as fast as similar Java code

Cons

  • New language
  • Multi-paradigm – philosophy of 1 language – many ideals
  • Mix of immutable (val) and mutable (var) – tries to be too many things to many people

Go

Go is a new language from Google which seems to have a C type syntax as well as the fundamentals of programming in the large systems.

Killer app

  • Docker
  • Google Infrastructure

Pros

  • Looks like C – small learning curve
  • Compiled
  • Backed by Google
  • Battle tested
  • Performance close to C
  • Goroutines

Cons

  • Not used by a lot of companies – hard to find developers in the market
  • Still very recent and not fully battle tested

Clojure

Coming with a LISP syntax and a immutability as a core tenet it is a refreshing take of LISP in a JVM. Created by Rich Hickey, its driven very strongly by its creator, the language is quite opinionated.

Killer app

  • Datomic
  • Clojure Script

Pros

  • Java interop – Batteries included
  • LISP syntax – almost
  • REPL
  • Touted as the future of Java
  • Rich Hickey’s philosophy
  • Channels

Cons

  • New language
  • Lisp Style

Python

My lingua franca now. It is very neatly done language and the fact that it is objects (dicts) all the way through is extremely refreshing.

Killer app

  • Django

Pros

  • REPL
  • Good / Fixed syntax
  • Simple modules
  • Batteries included approach – powerful glue, scripting and even a general purpose language
  • pip

Cons

  • Lacking multicore support
  • STM
  • Green threads

Lua

While not being in the same league as these full-fledged languages, Lua is one of those languages that can quickly turn an extremely well performing C / C++ code and turn it into a powerfully scriptable system without losing any of the performance

Killer app

  • Open Resty
  • Game programming systems

Pros

  • C / C++ support
  • Performance / Speed

Cons

  • Not a full-fledged language. Any errors bubbles up from the base language directly into Lua

Conclusions

All said, there are a few features I like in a programming language I like working with …

  • REPL
  • Modularization of code without having to resort to using classes. This is where PHP loses out for me.
  • Installable modules. Batteries included approach.
  • Variables naming with hyphen instead of underscores or camelCase. Feels more natural
  • Function naming with question mark. Makes reading and building boolean returning functions ending with a ? a natural read.
  • Garbage collection. I have seen C, C++ and Erlang’s immutability and any language that does not have me worrying about the trivial pursuit of hanging pointers is a big win!
  • Homoiconic systems. It becomes very easy when we start thinking about data and code not as two separate lines of thought (storage, DRY, versioning) but as two varying types of storage semantics only. Where processing (code) and data systems can both crash and need to be restored on demand, it becomes extremely useful when the code itself can be used to express infrastructure, data, configuration and other systems.
  • Clear and convention driven programming style. Telling me that it will work the way it looks (WYSIWYG) is simply a huge win. Quite simply, Erlang excels here for me. So does Go and Python.

My only crib. I wish Elixir was in the Python syntax instead of Ruby (of course taking nothing away from Ruby – its an extremely natural language – just a bit too Englishy and flexible for my taste).

Table Helper in PHP

Custom built frameworks are always a zero-sum game. You get the freedom to build the framework completely suited to your business needs, but then you will more or less have to retread the bug ridden path of other frameworks. For our company currently, as an architect I have immense freedom to look at application from completely ‘techie’ viewpoint and keep building better and simpler solutions to make the lives of ouri developers a bit simpler.

PHP is an amazingly simple language to build webapps in. Though personally I am in favor of Python or even Ruby to build webapplications, the amount of workforce in PHP available in the market makes it an immensely favored language.

Anyways, back in my work, we have this interesting problem where we have to render hundreds of analytics reports. Pull from the DB and display the results in table format. To deal with this tedium of having to write innumerable presentation layer files to deal with table rendering we use a small function to render the tables. Its a pretty simple function that formats the data in neat table cells using

and encloses each of the resultset in the table rows.

. However, because of this limitation we had the presentation layer tainting the data with the presentation tags.

Hence the genesis of this unit test code.

require 'table_helper.lib.php';

################# FOR UNIT TESTING THE FUNCTION #######################
function url_logos($profile_id) {
  switch($profile_id) {
    case 1: return "abcde"; break;
    case 2: return "vwxyz"; break;
    default: return "NONE"; break;
  }
}

$Data = array(
  array('john', 'john carmack', 1, 75, '2008-12-1 00:0:00'),
  array('galt', 'john galt', 2, 2, '2008-06-06 06:06:06'),
  array('dagny', 'dagny taggart', 1, 180, '2008-11-00 00:0:00'),
  array('hank', 'hank rearden', 2, 200, '2008-06-02 06:06:06'),
  array('roark', 'howard roark', 1, 0, '2008-12-1 00:0:00'),
  array('john', 'john carmack', 1, 75, '2008-12-1 00:0:00'),
);
$Headers = array('Alias', 'Name', 'Profile', 'Games', 'Joining Date', 'Square');
$Templates = array(
  '"{$data[0]}"',
  '$data[1]',
  '"http://www.someurl.com/profile.php?id={$data[2]}&name={$data[0]}"',
  '"{$data[3]}"',
  '$data[4]',
  'url_logos($data[2]);'
);

TableHelper::Render($Headers, $Templates, $Data);

This led to the first version of my code for the TableHelper class which would simply use the PHP ‘eval()’ code the replace the Templates and fill it with data.

class TableHelper {
        /**
         * @func   Render($Headers, $Templates, $Data, $Prefix = 'data')
         * @desc   renders a table for the given data and the cell templates given.
         * @param1 $Headers a string array of table column headers
         * @param2 $Templates string of cell templates. The data bucket should be named 
         *         as data in the default case. If you think of any other name be sure
         *         to pass the correct prefix to the function.
         * @param3 $Data Data to fill the templates with.
         * @param4 $Prefix Default bucket for row data is 'data'. Can be anything else.
         * @note   This function now builds a template file instead of using eval.
         */
        static function Render($Headers, $Templates, $Data, $Prefix = 'data') {
                $NumCols = count($Headers);

                echo '< table>';
                echo '< tr>';
                        foreach ($Headers as $header)
                                echo '< th>'.$header.'< /th>';
                echo '< /tr>';

                foreach ($Data as $$Prefix) {
                        echo '< tr>';
                        for ($i = 0; $i < $NumCols; $i++) {
                                        eval("$_cell="$Templates[$i]";");
                                        echo '< td>',$_cell,'';
                        }
                        echo '< /tr>';   
                }
                echo '';
        }
}

As any seasoned programmer will tell you looking at the code, I was sacrificing speed (lots!) for want of better code separation by using eval(). After days of rumination I decided to use aggressive template caching in pphplace of eval(). And here’s the class with the caching mechanism built in…

# BEGIN Section Table Template Caching Section
define(CACHED_TEMPLATES_FOLDER, './cache/');

class TableHelper {
        /**
         * @func CachedFilePath($Id)
         * @desc The table template cached file is just named as unique id.tpl.php
         *       in the CACHED_TEMPLATES_FOLDER folder.
         */
        static function CachedFilePath($Id) {
                return CACHED_TEMPLATES_FOLDER.$Id.'.html.php';
        }

        /**
         * @func BuildTemplate($Id, $Headers, $Templates)
         * @desc Generates the php code for rendering the table and writes the
         *       table generation view code template to the cached folder.
         */
        static function BuildTemplate($Id, $Headers, $Templates) {
                assert(is_writeable(CACHED_TEMPLATES_FOLDER)) or die('Error THL001: Cache Folder has no Write Permissions.');

                $str = '';

                /* Build the Table Rendering PHP Code String */
                $str .= "< table>n";
                $str .= "< tr>n";
                        foreach ($Headers as $header)
                                $str .= "< th>$header< /th>n";
                $str .= "< /tr>n";
                
                $str .= '< ? php foreach ($Data as $$Prefix) { ?>';
                        $str .= "< tr>n";
                        foreach ($Templates as $template)
                                $str .= "< td>< ?= $template ?>< /td>n";
                        $str .= "< /tr>n";
                $str .= "< ? php } ?>n"; 
                $str .= "n";

                $handle = fopen(TableHelper::CachedFilePath($Id), 'w'); 
                        fwrite($handle, $str);
                fclose($handle);

                return true;
        }
        # END Section Table Template Caching Section

        /**
         * @func   Render($Id, $Headers, $Templates, $Data, $Prefix = 'data')
         * @ver    1.2
         * @desc   renders a table for the given data and the cell templates given.
         * @param1 $Headers a string array of table column headers
         * @param2 $Templates string of cell templates. The data bucket should be named 
         *         as data in the default case. If you think of any other name be sure
         *         to pass the correct prefix to the function.
         * @param3 $Data Data to fill the templates with.
         * @param4 $Prefix Default bucket for row data is 'data'. Can be anything else.
         * @note   This function now builds a template file instead of using eval.
         */
        static function Render($Id, $Headers, $Templates, $Data, $Prefix = 'data') {
                $NumCols = count($Headers);

                /* Attempt to just include the cached template file for this table */
                $cached_file_path = TableHelper::CachedFilePath($Id);
                if(!file_exists($cached_file_path)) 
                        TableHelper::BuildTemplate($Id, $Headers,$Templates);
                
                if(file_exists($cached_file_path)) {
                        include_once $cached_file_path; return;
                }

                /* If Cached File cannot be created, just do the EVAL way! */
                echo '< table>';
                echo '< tr>';
                        foreach ($Headers as $header)
                                echo '< th>'.$header.'< /th>';
                echo '< /tr>';

                foreach ($Data as $$Prefix) {
                        echo '< tr>';
                        for ($i = 0; $i < $NumCols; $i++) {
                                        eval("$_cell="$Templates[$i]";");
                                        echo '< td>',$_cell,'< /td>';
                        }
                        echo '< /tr>';   

                }
                echo '< /table>';
        }
}

Catches
The only dependency with this code is that you have to create a Apache writeable folder referenced by the CACHED_TEMPLATES_FOLDER. After that its just fun all the way! Also note that the call to the Render in the unit testing class will now have to be supplied a unique Template Id.

TableHelper::Render($Id, $Headers, $Templates, $Data);