Compiled vs. Dynamic Languages

Recently, I’ve been reading about the comparative advantages and disadvantages of compiled languages (C, C#, Swift, Java) vs. dynamic languages (Python, JavaScript).  Python is so elegant and readable.  JavaScript is powerful and ubiquitous.  While the compiled languages seemingly add needless barriers to developers. I was convinced—dynamic languages were the future.  But my latest project gave me a new perspective.

The beauty (or lack thereof) of C# is that it gives the developer the power to use a dynamic type which effectively disables compile time type checking.  The result is code that  behaves similarly to Python or JavaScript with respect to typing.

My current project is using a ASP.NET MVC API with an EmberJs front-end.  All of the API endpoints return dynamic objects to support the proper JSON format for Ember.

When writing unit tests, we often hit the end points directly (to test the entire back-end stack).  Our tests then take the dynamic wrappers and unwrap them so the tests can use the actual object.  One problem we encountered is that the tests don’t “compile.” If we change the internal object of the API dynamic wrappers the code will compile just fine, but when the tests are executed the code will break.  This is an exceedingly frustrating situation caused by dynamic types at the API endpoints.

While it is easy to dismiss this issue as a non-functional issue (since it only applied to tests) unit tests are a cornerstone of good software development.  It would be much nicer if the tests would just compile and do the appropriate type checking during the build process instead of blowing up at runtime.

Consider a code structure with repository layer that is essentially an SQL query wrapper and a query layer which calls the repository and other queries to rebuild complex, nested data structures.  The required use case is that the Query class for a specific entity is the only query allowed to call that entity’s Repository.  Luckily C# is an object orientated and compiled language.   We were able to enforce this requirement with a sexy inheritance trick.  The query classes extend their respective repository and the repository methods are all given the protected access modifier (accessible by sub-classes).  This way we build a compile time enforcing of the repository query interaction rules.

This code structure identifies many hidden bugs where query classes directly call repositories that do not build out the object structure in the correct way. In addition, this structure is much easier for new developers coming on to the project.  Instead of having to read documentation (if it exists), or spend needless hours debugging the developer is given a compile time error that he is calling a function in the wrong place.

While this structure is possible in dynamic languages like Python, leveraging the compiler to enforce coding rules is a huge advantage that compiled languages have over dynamic languages.  When used effectively the compiler can be extremely powerful.



Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s