Advertisement
Guest User

Untitled

a guest
Jan 9th, 2016
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.43 KB | None | 0 0
  1. Table of contents:
  2.  
  3. [TOC]
  4. Functional Programming
  5. ===================
  6. Why are we so fussed about Functional Programming? Is it really better than Object Oriented programming? Can it solve our problems?
  7.  
  8. If you are like me you'll have heard a lot of buzz about functional programming these last few years you might be wondering how this "functional programming" fits into your day to day work and how it affects your code.
  9.  
  10. The answer is quite simple, yes, functional programming will make you a better programmer. Yes, functional programming will solve a lot of problems arising from complexity; but most of all functional programming is the only way to leverage the power of multi-core chip-sets.
  11.  
  12. ----------
  13.  
  14. ## What is Functional Programming (FP)
  15. There are a lot of definitions about FP buzzing around the internet. Some definitions are more chaotic than others and some definitions are bias. For example, Uncle Bob would have everyone believe that functional programming is about state and that Object Oriented Programming (OOP) can be stateless and thus have the same power as FP. FP is not about state, state is an effect of writing mathematical functions. Working with mathematical functions is at the center of FP. What does that mean? Mathematics is not a part of my day job right?
  16.  
  17. Wrong, everything about software and hardware is bound to mathematics, just like everything else is. Bridges suspend because of math savvy engineers; even colors are calculated using mathematical equations to make them aesthetically appealing. So, to write a blog post about programming without any math would be to deny it's importance and I would not deprive people of that. Now to nuance this, you do not need a maths degree but you need to know what it is about. You need to be able to read their *syntax* and you need to be able to follow *logical proofs*. To be honest, you should already be able to do that as a professional programmer, *logical proofs* are what code is all about and lets not get started about syntax. What I want to achieve with this blog series is to awaken a curiosity and raise the level of awareness about the power of programming, in my opinion this can only be done through functional programming!
  18.  
  19. So, to reiterate, functional programming is about writing code using mathematical functions. Math is a part of programming which we as a profession have denied for too long and you need to have a firm grasp of the *syntax* and how to form *logical proofs*.
  20.  
  21. ## What is this function thou speaketh of?
  22. In OOP we confuse static methods for mathematical functions. A static method in most languages is the same as method with a **this** parameter as first parameter. So imagine the following method:
  23.  
  24. ```
  25. public class Person {
  26. private string name = "Peter Pan";
  27. public string GetName() {
  28. return this.name;
  29. }
  30. }
  31.  
  32. // call
  33. var person = new Person();
  34. Console.WriteLine(person.GetName());
  35. ```
  36. We could rewrite this function as:
  37. ```
  38. public class Methods {
  39. public static string sGetName(Person this) {
  40. return this.name;
  41. }
  42. }
  43.  
  44. // call
  45. var person = new Person();
  46. Console.WriteLine(
  47. Methods.sGetName(person));
  48. ```
  49. Here we can see that the *insides* of the methods `GetName` and `sGetName` haven't changed we have just created a parameter *this* which contains the data.
  50.  
  51. > **Note:**
  52. > Maybe we shouldn't call the parameter *this*. *this* just doesn't say anything. *data* would be better. Within the class the *this* might be better served by calling it *self*.
  53.  
  54. Pure mathematical functions are different, first let's look at the same functionality but now written in F#:
  55.  
  56. ```
  57. type Person = { name : string }
  58. let getName data = data.name
  59.  
  60. let person = { name = "Peter Pan" }
  61. printf "%s" (getName person)
  62. ```
  63.  
  64. A few things should stand out:
  65. * There is no class keyword.
  66. * The type definition, the data and the behavior are separated.
  67. * There are no access modifiers.
  68.  
  69. Before we get into why these differences are there we will need to look at what it is what pure mathematical functions want to achieve. Let's start by looking at what an operator is:
  70.  
  71. > An **operator** is a symbol or function denoting an operation.
  72.  
  73. This is the mathematical description of what an operator is. So we can have a symbol or a function, this is odd. In general programming symbols tend to be thought of as different *things* than functions; but in mathematics we can think of both of these things as *morphisms*.
  74.  
  75. > A **morphism** is a structure preserving map from one mathematical structure to another.
  76.  
  77. Ah, now we're getting somewhere, *maps*, I can deal with maps! In C# we can use the `Select` function in `Linq` to achieve a map:
  78.  
  79. ```
  80. // people is of type IEnumerable<string>
  81. var people = ["Bianca", "Trish", "Paula", "Michelle"];
  82.  
  83. // nameLengths is of type IEnumerable<int>
  84. var nameLengths = people.Select(p => p.Length);
  85. ```
  86.  
  87. Somehow this magic select function has turned an `IEnumerable<string>` to an `IEnumerable<int>`. Does this comply with the definition of a *morphism* I just gave? Well, that depends on what a *mathematical structure* is. So let's dive into mathematical structures.
  88.  
  89. > A **mathematical structure** is a *structure on a set* which describes a relationship between objects in that set.
  90.  
  91. Another way of thinking about a structure is that a structure gives a subset of the set meaning. This comes really close to how we as programmers think about types! There can be multiple objects which fall into a type definition. For example, `1 2 3 4 5 6 7` are all of type `Integer`. So for the sake of this article I will treat *mathematical structures* as types. And while we're at it; I'll treat the programming language as a *container* of all of these types. This container in mathematics could be called a **category**.
  92.  
  93. So, we now have a *programming language* which has *objects* of a *type* and which has *morphisms* over these objects. One thing to note is that these morphisms can be completely random, there is no reason why there should be a pure mapping between two mathematical structures. This might be the most fundamental difference between **Category Theory** and **Algebra**. In Category Theory you have Objects and Morphisms of a Category. In Algebra you always define the context, on which you define your Algebraic types.
  94.  
  95. Now, let's think about these morphisms for a little bit, I could write something like: `f:: x -> y` where `y` can also be written as `f(x)` so you get `f(x) = y` which might seem more familiar to some. Now `f(x)` in functional programming languages is usually written as `f x` which gives the idea of multiplication and because of this *association with multiplication* is exactly why it is written that way.
  96.  
  97. ##Monoids
  98. Let us think about the positive whole numbers:
  99.  
  100. $\mathbb{N} = { 1, 2, 3, 4, 5, .. }$
  101.  
  102. Now imagine an operation $\oplus{}$ which can be applied to two of these elements from the collection $\mathbb{N}$. We can now define $\oplus{}$ as:
  103.  
  104. $$
  105. Given\;a,b,c,id\; where\; a,b,c,id\;\in\;\mathbb{N}\\
  106. \\There\;exits\;an\;operation\;\oplus\;so\;that:
  107. \\(\;a\;\oplus\;b\;)\;\oplus\;c\;=\;a\;\oplus\;(\;b\;\oplus\;c\;)\quad and\;that:
  108. \\a\;\oplus\;id\;=\;a\quad and \quad id\oplus\;a\;=\;a
  109. $$
  110.  
  111. We can now say that $\mathbb{N}$ is a **monoid** under operation $\oplus$.
  112.  
  113. What could be a valid operation for $\oplus$? Well, multiplication seems reasonable. Multiplication is associative (the first rule of a monoid) and $1$ seems to satisfy the $identity$ rule. So the natural numbers ($\mathbb{N}$) is a $monoid$ under multiplication.
  114.  
  115. Why is this important? This is important because instead of the $\mathbb{N}$ we can look at the objects of a type, for example the type $'a$ and as the operation $\oplus$ we can think of $function \; composition$.
  116.  
  117. Imagine the following functions:
  118.  
  119. $$
  120. f\;::\;'a\rightarrow\;'a\\
  121. g\;::\;'a\rightarrow\;'a\\
  122. h\;::\;'a\rightarrow\;'a
  123. $$
  124.  
  125. Now we can say that the $'a$ is a $monoid$ under $function \; composition$ because we can say something like:
  126.  
  127. $$
  128. f \oplus ( \; g \oplus h \; ) \; = \; (\; f \oplus g \; ) \oplus h
  129. $$
  130.  
  131. I am not giving any proofs, they would not give any extra information and would cloud the explanation. If you really want to have proofs, I applaud you and I'm sure you will find that the internet is littered with proofs about function composition being associative.
  132.  
  133. ##Back to reality
  134. So, now that we've seen that function composition on a generic type $'a$ is a *monoid* we might start to wonder how this affects our daily job. I'll bet you that you've never written a web site with a database backend and thought about *monoids*. Now, you might be right. There seems to be really little use you can get out of these mathematical definitions; but you couldn't be further from the truth. We can now say with absolute certainty that if for example $'a$ is for example the type $Person$ and we have three functions:
  135.  
  136. $$
  137. create\;::\;Person\rightarrow\;Person\\
  138. save\;::\;Person\rightarrow\;Person\\
  139. log\;::\;Person\rightarrow\;Person
  140. $$
  141.  
  142. That:
  143. $$
  144. create \; ( \; save \; ( \; log \; ( \; new \; Person \; () \; ) \; ) \; ) ;
  145. $$
  146.  
  147. Can never, ever fall out of the type definition. This knowledge, this security is huge! But, and this is a big *but*, this presumes that the programming you do is using *pure mathematical functions*. If you use for example *C#* you can always `thow new Exception("Oh nooes!");` and circumvent the type safety of our *monoid*. Also, `out` parameters mess up our system as well. *Exceptions* and *out parameters* are added functionality. There was absolutely no reason to add these *features* to the language. Because of something like exceptions we will have to rewrite our simple function composition for a language like C#:
  148.  
  149. ```
  150. var person = new Person();
  151. try {
  152. person = create(person);
  153. } catch (Exception ex) {
  154. // do something...or not...
  155. }
  156.  
  157. try {
  158. person = save(person);
  159. } catch (Exception ex) {
  160. // do something...or not...
  161. }
  162.  
  163. try {
  164. person = log(person);
  165. } catch (Exception ex) {
  166. // do something...or not...
  167. }
  168. ```
  169.  
  170. Apart from the incredulously long windedness of this code it is also too specific. I haven't even caught all the specific exceptions each function can throw. To be honest, this is just silly. There should be no reason why we would write code like that. Any other way of rewriting, for example one bit try an catch around the entire set of functions would be sillier because you lose specificity.
  171.  
  172. In F# we would simply write:
  173.  
  174. ```
  175. new Person() |> create |> save |> log
  176. ```
  177.  
  178. if we wanted to go all out we could compose the functions like so:
  179.  
  180. ```
  181. let useCase_01 = create >> save >> log
  182. let p = useCase_01 (new Person())
  183. ```
  184.  
  185. We should start to feel excited right about now.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement