Like everyone who has been programming for some time, I have a set of tools and utility functions which I have developed over time, and reuse often.
The purpose of this series of posts is to talk about observations in my evolution as a functional programmer, and how the implementation and approaches I tend to take these days increasingly use functional concepts.
As you browse the code, you’ll come across more utilities than the ones discussed in this blog series. This series is going to try and focus on those utilities which demonstrate some facet of functional programming.
What is Functional Programming? Why do I care?
Functional Programming is a programming paradigm that treats programs as the evaluation of mathematical functions and expressions.
One can conceive of a kind of spectrum of programming abstraction:
- Assembly Language which abstracts away parameterized opcodes
- FORTRAN, COBOL and BASIC introduce control flow statements and subroutines
- Pascal and C which allow for rich user-defined types, abstracting data and largely obviating the GOTO construct
- Modula-2 and C++ which introduce concepts of objects maintaining state, encapsulating both data and related functions
- Java and C# 1.0 which introduce concepts of managed memory and a virtual runtime environment, allowing for simpler creation of objects and popularizing Exceptions
- Modern C# which introduces concepts of true type parameterization, lambdas and attributes. LINQ is a very powerful programming extension which is available here.
- Scala introduces type classes and F# provides full type inference. These languages also use pattern-matching and recursion constructs to obviate some familiar imperative programming patterns.
- LISP, a proto-functional language, is actually a multi-paradigm language, and as such, generally provides a great introduction to programming. LISP relies heavily on recursion, obviates some of the familiar programming constructs such as for loops and variables, introduces the concept of isomorphic code and data which makes it trivial to generate and immediately execute a function, and provides powerful meta-programming support.
- Haskell, which emphasizes purity to the extent of introducing the concept of IO Monads to limit the impact of side-effects on a pure functional language.
Other authors have spoken cogently about the experience of a programmer skilled in a language somewhere in the spectrum (say a Java expert) looking up towards a more abstract language and not being able to comprehend why a construct or concept from that language would be useful or even necessary.
Therefore, it isn’t unreasonable to ask why we would need a functional programming perspective when we can do almost all we need with our daily programming language. Hopefully, as we go through this blog series, we’ll get a flavour of the kinds of things that functional programming makes easier, or possible!
What’s coming down the track?
- Functions as Function Arguments
- Functions as Function Results
- Classes and Memoization - A Neat C# Trick
- Introduction to Monads
- The trouble with Exceptions!
- Static methods and Classes
My involvement with functional programming goes all the way back to college, where teachers like Dr. Takis Metaxis introduced me to symbolic computing with LISP.
I highly recommend reading Real-World Functional Programming: With Examples in F# and C# by Tomas Petricek and Jon Skeet.
If you get a chance to listen to the “Programming with Purity” talk by Joseph Albahari, do so – he has one of the most lucid explanations of Monads around!
Do stick around, and I’ll try to explain how I synthesize some of these concepts into tools that I use frequently.