Trends in Programming Languages
It’s been a while since my last post, due to work pressure and little spare time. But in between some code analysis for the maintenance projects I’m involved, the preparation of a Linq presentation and some new blogs I discovered, I’ve been thinking about program language evolution.
It’s not new that imperative languages are integrating functional characteristics. The novelty is the big push by Microsoft, mainly Anders Helsjberg and the .NET team in that direction. Right now, we have XAML, WPF, WCF, and Linq, SilverLight, Entities, VS Orcas just ahead. I still remember the backlash that Java received because it incorporated Garbage Collection, and a Virtual Machine that run bytecode. Nowadays, the main platforms (C# and Java) all include these characteristics, and the new contenders (Ruby, Python) all incorporate it.
Recently I found a great blog that explains the characteristics and advantages of functional programming, in a way that our imperative brains can associate with. In the aptly named article Functional Programming For The Rest of Us, the author presents the following advantages:
- Greater Expressiveness, which equates to less lines of code and less bugs;
- Meta-programming in the same language, dismissing the need to learn a new languge and displacing many code generators;
- Code as Data (in Lisp, it’s possible to treat code as data, by quoting), opening the door to code manipulation, analysis and generation;
- Data as Code (in Lisp, a data structure can be “executed”);
- Composibility, or the possibility to change/define an application behaviour by the simple composition of functions;
- No SIDE EFFECTS
- Easier testing as the result of a function depends only on it’s arguments and produces no side effects. This way a test with the same arguments has always the same behaviour;
- Debugging is simpler as there are no dependencies on Global State;
- Concurrency (with the advent of multi-cores, this is extremely important) scales much better, because locks aren’t necessary because there is no shared state;
- Hot code deployment, without the need to persist and import state (it is passed on the stack in the arguments), it becomes possible to substitute code without stopping the system;
- Machine assisted proofs and Optimizations, without state and side effects, it’s possible to reason about the functions and demonstrate some characteristics about it
From my recollections, this blog and some other blogs on Functional Programming, these are the characteristics attributed to Functional Programming Languages:
- Anonymous Functions (lambda calculus)
- Type Inference
- Higher Order Functions (functions as a first citizen language construct. Can receive and apply functions passed as arguments)
- Currying (adaptation to an interface, by fixing one or more arguments)
- int pow(int i, int j);
- square = int pow(int i, 2);
- Lazy Evaluation allows:
- New types of optimization (complex calculations that are not used aren't computed)
- Creation of new abstract control structures
- Infinite data structures
- Continuations (allows the storing of state and the definition of return point or the function to execute)
- Pattern Matching (definition of functions based on types, values and expressions)
- Closures (functions that can reference the encompassing environment, typically defined in the body of another function, allowing the association of intermediate set of data with the function: http://en.wikipedia.org/wiki/Closure_%28computer_science%29)
Why does it matter or In what way does it affect me?
Due to the natural evolution of micro-processors, the future doesn't hold increases in speed but in integration of multiple cores in the same die. Because of this, it becomes very important to not limit the concurrency, which is simpler in functional programming (because of no shared state and the expressiveness).
Also the evolution in the .NET space points in the same direction (transition from imperative to declarative), with the eminent arrival of Linq. It's clear in the .NET evolution the trend to a more declarative style with the incorporation of many characteristics of Functional Programming.
.NET evolution
C# 1.0
- Function Pointers (delegate)
C# 2.0
- Limited Continuations (yield)
- Closures (anonymous methods)
C# 3.0
- Expressiviness
- Query expressions: from x in …
- Automatic Properties (get; set;)
- Partial Methods (“lightweight” event handling)
- Extension Methods: public static void Print(this string s)
- Type Inference for local variables (var)
- Lambda Expressions/Anonymous functions (x => x * x)
- Anonymous Types (new {c.name, c.Phone})
- Code as Data (ExpressionTrees)
- Func<int, bool> nonExprLambda = x => (x & 1) == 0;
- Initizalizes a delegate: public delegate T Func<T, A>(A a);
- Expression<Func<int, bool>> exprLambda = x => (x & 1) == 0;
- Is equivalent to
- ParameterExpression xParam = Expression.Parameter(typeof(int), "x");
Expression<Func<int, bool>> exprLambda = Expression.Lambda<Func<int, bool>>(
Expression.EQ(
Expression.BitAnd(xParam, Expression.Constant(1)),
Expression.Constant(0)),
xParam);
- Func<int, bool> nonExprLambda = x => (x & 1) == 0;
References
Functional Programming explained
http://www.defmacro.org/ramblings/fp.html
http://www.defmacro.org/ramblings/lisp.html
Artigo MSDN C# 3.0
http://msdn.microsoft.com/msdnmag/issues/07/06/CSharp30/default.aspx?loc=en
Expression Trees
http://www.interact-sw.co.uk/iangblog/2005/09/30/expressiontrees
http://spellcoder.com/blogs/bashmohandes/archive/2006/06/12/143.aspx
Closures
http://pluralsight.com/blogs/dbox/archive/2005/04/27/7780.aspx
http://www.claassen.net/geek/blog/2006/08/c-closures.html
Blogs
http://blogs.msdn.com/wesdyer/rss.xml