Functional programming gains popularity in recent years. Many main-stream imperative languages, e.g. C++11 and Java8, are adding functional features (actually templates in C++ are fully functional). Some new languages such as Scala even go further with comprehensive functional supports in an object-orient way. In this series, I will give an introduction to an elegant functional language OCaml, derived from ML. ML-derived languages are well known for their static type systems and type-inferring compilers. Unlike purely functional programming languages such as Haskell, ML/OCaml allows imperative programming that has side-effects. Moreover, OCaml supports object-oriented programming with an interesting design that is very different from class-based approach in C++/Java or message-based approach in Smalltalk/Ruby.

OCaml is very expressive and OCaml programs are concise and clean (but hard to understand for beginners). OCaml’s static type system helps eliminate runtime problems. On the other hand, its type-inferring compiler greatly reduces the need for manual type annotations. Compared to most academia-origined programming languages, OCaml puts a lot of emphasis on performance, which is very important for the use in industry. New languages like F# and Scala are strongly influenced by OCaml. In fact, F# is largely based on OCaml except objects, functors, and polymorphic variants. Therefore, F# even features a legacy “ML compatibility mode” which allow programs written in a large subset of OCaml to be immediately compiled as F#.

Before diving into the details of OCaml, let’s have a light discussion on what’s functional programming from a programmer’s point of view, which will be very helpful to understand the designs of OCaml. For some programmers (e.g. who use JavaScript), functional programming means lambdas (i.e. anonymous functions) and closures. Well, a Java programmer may argue that the inner class does achieve the same effects (of course, less pleasingly succinct). Some people claim that functional programming treats the computation as the evaluation of functions and thus the whole program can be regarded as a single function. While it is true, a C program can also be regarded as a single main function but it is clearly not functional. Interestingly, OCaml has no main entry function at all. Furthermore, people argue that the signature of functional languages is that functions are first-class citizens. Specifically, this means that the language supports passing functions as arguments to other functions, returning them as the values from other functions, and assigning them to variables or storing them in data structure. But we can do all of these in C with function pointers. Of course, there are people talking about the immutable data in functional programming. Clearly immutable data are supported by const keyword in many imperative languages.

All above features touch some parts of function programming but fails to come to the key – functions in functional programming are pure mathematical functions that produce results that depend only on their inputs and not on the program state. In contrast, functions in imperative languages are just subroutines (i.e. a group of statements) for the purpose of code reuse, which may have side effects. Eliminating side effects can make it much easier to understand and predict the behavior of a program, which is one of the key motivations for the development of functional programming. Note that side effects could be useful in some cases, e.g. I/O and pseudo random number generators.

Theoretically, functional programming has its roots in lambda calculus. Many functional programming languages can be viewed as elaborations on the lambda calculus, where computation is treated as the evaluation of mathematical functions (don’t forget it) and avoids state and mutable data. But I won’t go further on this math heavy topic in case scaring away potential readers. In the next post, I will cover the basic building blocks of OCaml programs – expressions.

Advertisements