Today we’ll be talking all about functional programming together with special guest, Adam Trilling. Adam is the Director of Service Delivery at Stride and has a lot of knowledge, insight and tips about functional programming. Today we’ll be tackling concepts from object oriented programming, immutability, Mapping, Filtering, Reducing and the advantages of functional programming. We’ll also be getting into some debates about how Java Script is going to take over the world, why functions are treated as first class citizens and what the best functional programming language is. Functional programming is a complete different thinking process and all of the languages that most coders use, actually have functional programming features in them. Ultimately, we hope that this discussion might give you some insight as to how you should be using functional programming in the workplace… or in the ghetto. Take a listen!
Key Points From This Episode:
Transcript for Episode 27. Functional Programming
[0:00:01.4] MN: Hello and welcome to The Rabbit Hole, the definitive developer’s podcast in fantabulous Chelsea Manhattan. I’m your host, Michael Nunez. My cohost today.
[0:00:09.8] DA: Dave Anderson.
[0:00:11.1] MN: Our producer.
[0:00:11.9] WJ: William Jeffries.
[0:00:13.0] MN: And today we’ll be talking about functional programming but before I continue, we have a special guest here. We have Adam Trilling. How’s it going Adam?
[0:00:22.3] AT: Good, thanks for having me.
[0:00:24.2] MN: Adam is the Director of Service Delivery here at Stride and he will have a lot of things to say about functional programming. So it’s great to have you.
[0:00:31.8] AT: Yes, I will.
[0:00:32.6] DA: Yeah, how do you feel about functional programming?
[0:00:35.6] AT: I like it a lot. I’ve been tinkering with a lot of different programming languages over the past couple of years, especially now that I don’t write code full time. It becomes much more appealing to me to go home and spend a couple of hours writing code and working on things that I couldn’t really do back when I was writing code for my day job.
I was messing with Clojure for a while and with Elixir for a long while and now I’m actually learning Haskell which has been quite an experience. But that started actually with this experimentation when I was still writing code full time and it was very interesting to me how learning functional programming paradigms changed my approach to writing code for work which I was writing Ruby and Java Script at the time.
[0:01:15.4] WJ: Yeah, everybody says that, they say it stretches your brain in weird ways and makes you think differently forever.
[0:01:22.1] DA: Just to like, for any listeners out there who aren’t familiar, what are the main differences between – I guess like, the opposing paradigm at the other corner, is object oriented. The other philosophy that people tend to follow or are probably most familiar with from being taught Java or C++ in college or what have you?
[0:01:40.8] AT: Yeah, people talk about object oriented and functional programming as if they were opposites but they’re not – actually, there are several languages that support both paradigms. Which is actually more opposite is imperative programming which all the languages that you mentioned are imperative languages.
The primary difference in philosophy is that an imperative language, you tell the computer what to do in what order. In a functional programming language, you tell the computer what you want and it figures out how to tell you what you want using a bunch of functions that you’ve defined.
You know, in imperative programming language like Java, you might – if you had a sequence of steps to do, you would tell the computer, do step one, do step two, do step three. But, in a functional programming language, especially as you get into the more pure functional programming languages, you would break the steps down into much smaller pieces and so you might have one function that calls seven other functions and then two others depending on some condition. All of the path creation happens at compile time.
[0:02:44.0] MN: Right, rather than an object oriented programming where you may have these objects that have these methods that only that object can do. Functional programming, you just say “Hey, do this for me” and it’s written in a way where that’s the only thing that that particular function does.
Does functional programming like use inheritance in that aspect at all or no?
[0:03:08.7] AT: It could. Scala for example is object oriented and functional at the same time. Some of those paradigms can be supported – both of them be supported in the same language.
A lot of functional programming languages that are not object oriented use is instead of having – you know, have some sort of a record format that would store all of the properties of an object, in an object oriented language. But functional programming languages that are more dedicated to that also adhere strongly to the concept of immutability.
Which means that once you create an object or create a record or create whatever data structure, you can never change it again. Which is directly opposed to the way one typically writes object oriented code, especially in a language like Java or in a language like Ruby.
Manipulating the state of objects is the primary way of accomplishing things.
[0:03:57.6] DA: Yeah, you’ve got your getters and setters.
[0:03:58.9] AT: Exactly.
[0:04:01.6] DA: Whereas I guess, if you’re writing Java with more of a functional bend, you might only have getters, once you construct the object. Or that’s a more of a immutable side, if not functional, it’s still object oriented.
[0:04:14.0] MN: Right.
[0:04:15.0] AT: In a language with strong support for immutability instead of setters or you have a function that returns a new copy of the object with the appropriate changes made. The initial copy of the object is still in existence but then your function returns a new version of it that has whatever changes you need made.
Which is a significant advantage, for example, if you’re doing concurrent programming because you know that you have guarantees in the language that an object can never be mutated while another thread is operating on it for example.
[0:04:44.6] DA: Yeah, I definitely encountered my share of nasty bugs when arguments get mutated. When dates are truncated randomly and other functions that have been called somewhere else. I just really wish that everything was immutable sometimes.
[0:05:01.5] WJ: Do you program in an object oriented way and a functional way, at the same time? Are you creating objects and then passing those objects that are instances of classes into functions?
[0:05:12.4] AT: That’s a good way of thinking about it because even in languages that are not object oriented, you’ll have certain operations that only apply to certain datatypes. For example, you know, if you have of the plus operator, it’s only going to work on two numbers.
But instead of you know, in a language like Java, I know this is an exercise that I had to do in college, I know they’re pretty common exercise on object oriented programming. You might have a number class and then you have to define operations on it like add, multiply and then those are instance methods on the number class. But in a language like I mean, especially on a language like Haskell.
Plus is instead of function that takes arguments, both of which have to be numbers and then it returns and answers that is a different number.
[0:05:55.8] DA: Right, like, a classic example of like Lisp, you have to just have parenthesis where the operator’s first and then you have two arguments. So you can kind of visualize it in a way that’s in line with any other language basically. Like a Java Script function is in the same format but you know, that’s also an operator in Lisp.
[0:06:15.3] AT: Yeah, and in a lot of functional programming languages, you start to see things that you would traditionally not think of as functions become functions. Like operators, the arrhythmic operators and you know, even function application in some languages becomes an operator.
[0:06:28.5] WJ: Function application?
[0:06:29.8] AT: Yeah. When you pass arguments to a function, there are operators that allow you to – or there are functions that look like operators that change the way the order of operations are changed, the association are changed and fixed versus pre-fix.
[0:06:45.1] WJ: In fix versus pre-fix?
[0:06:46.5] AT: Yeah, for example, what Dave was talking about where in Lisp you have, you can start with the operator like you say, plus three, four and then the result is seven or like you might be able to change the function, you could say three plus four and it would still return seven. In fix versus pre-fix. Notation for functions.
[0:07:06.4] WJ: Why do you call it functional programming?
[0:07:08.6] AT: In functional programming, functions are treated as what’s called first class citizens. Meaning, that a function is a piece of data just like any other variable in the system. For anybody who’s programmed in Java Script, they’ve seen a lot of this where a function will take a call back as an argument and then that call back is a function.
Then at some point, during the execution of the calling function, it will call that callback with certain arguments and so there actually are not a – I was thinking about a counter example. There are not a lot of languages these days that don’t support functions as first class citizens. It’s a pretty common thing but that’s really the basis of what allows all these functional paradigms to work, is the idea of functions as first class citizens.
[0:07:50.9] DA: Yeah, that’s kind of interesting working with a language like Python where functions are first class citizens but also everything is an object. A function is an object but it’s actually a functional first-class citizen and you can pass that around as a Alanda or even just as the function itself, like the named function. It’s secretly an object.
[0:08:13.1] AT: I believe in Python, you can even call functions on functions.
[0:08:16.5] MN: “Yo dog, I heard you like functions.”
[0:08:19.2] DA: Yeah.
[0:08:19.3] WJ: You can do the same thing in Java Script too.
[0:08:21.3] AT: Yeah.
[0:08:21.8] DA: Because I guess they’re member functions of the object, the function object.
[0:08:27.1] WJ: But don’t do that though.
[0:08:28.5] AT: Right, just because you can doesn’t mean you should.
[0:08:31.3] MN: Right.
[0:08:32.6] DA: It’s interesting because you can do a lot of things in these languages but then there are accepted norms that nudge you in another way often. You know, Python, you can do B to D testing, you can do like functions as arguments to methods in your objects but it’s often kind of unexpected.
[0:08:55.5] AT: I know, there’s a lot of talk about writing Java Script in a more functional style, writing ruby in a more functional style but it’s very easy to take it too far and get yourself into trouble. You still – you know, maybe trying to make a code cleaner but you still need to stay within the idioms of the language or you’re going to have a bad time.
[0:09:11.7] DA: Right. Although, it is interesting with Java Script because I feel like they’ve been more open to that kind of functional paradigm than many other languages.
[0:09:22.1] AT: Yeah, and it makes a lot of sense in Java Script because of the way the language is constructed. I’ve noticed Java Script tends to be much happier when you’re programming in a functional style and when you’re going out of your way not to mutate things. For example, the call back scheme is one of the primary design patterns in Java Script.
[0:09:41.3] DA: Yeah, it’s interesting contrasting a web framework like Express were you have the next call back past 10 as a parameter to your function that you’re going to get the page from. In contrast to something like Rails or Jango where you have a controller which is an object and you know, handles methods according to routes which are also objects.
[0:10:08.5] AT: Well, which brings me to one of the primary advantages of functional programming style, which is composability. In Express to figure out, as you mentioned. The passing in the next call back to a route allows you to get very creative about swapping out what that next value is.
It allows you to for example write middle where in a very concise fashion, your middle ware is basically a function that behave like a route and takes your next callback as a parameter and takes your request and returns your response. It makes it much simpler to write middle ware then as compared to say Rails or Jango.
[0:10:43.3] DA: Yeah, that’s true. I guess similarly in Java Script land for middle wares, I was watching the videos that Dan Abramoff, the creator of Redux, put together and he builds a lot of these things for middle ware from first principles in a very functional way. It’s kind of illustrated that style of thinking and how simple it actually is under the covers.
[0:11:06.7] AT: Yeah, Redux takes functional programming even a step further because if you – once you understand the Redux pattern, it actually makes some of the more pure functional programming concepts a lot easier to grasp. Because in Redux, if you're doing things the way that they recommend, there is, you know, when you create an action, you path it in to the – and pass it along.
The action updates the state of the Redux store but it does it an atomic fashion. There’s no possibility of a collision and the actions also must be pure functions. Meaning that the function for any given set of inputs, it returns the same output every time.
[0:11:44.8] DA: Yeah, definitely makes your life a lot easier with testing.
[0:11:47.6] AT: Yeah, absolutely and that’s another one of the primary advantages of functional programming is that pure functions that don’t have any side effects, tend to be very easy to test.
[0:11:56.0] MN: Right, because you expect that result of that function to always be the same thing correct? There’s no like race condition that will come and creep, especially when you have – when you’re working with a language that definitely deals with immutability.
[0:12:11.2] WJ: When would you not want to use functional programming?
[0:12:14.1] AT: When it makes your code harder to read. You know, as I had said, you have to work within the paradigms of the programming language that you’re using. When I first started to seriously get into functional programming, my stride pair at the time will tell you some stories about some things I tried to do that were probably pretty ill advised.
In functional programming, your primary tools for data manipulation are – there are three functions. There’s Map which takes a list and a function and it applies that function to every element of the list. It returns that as a new list which it tells to collect in Ruby. Or commonly used I believe as collect. Then there’s Filter which takes a list and a function and that function takes one element of the list and returns a bouillon.
So Filter will return a new list where that function returns true. If you have a list of the numbers one through 10 and your function set is divisible by two, it only returns the events. And then, Reduce, which is a little more complicated to explain. Reduce takes again, a list and a function – common pattern.
It takes a list and a function but that function takes two parameters both of which are elements of the list and returns a new value, which combines those two in some way. Maybe you’ll pass in the plus operator as your function and so that will give you the sum of all the numbers on the list.
[0:13:34.9] MN: Right.
[0:13:35.7] AT: The idea, it’s called Reduce because it reduces all of your – it reduces a list usually into a single value. That’s also called Injected Ruby. In pretty much any language or functional programming is intended, you’ll have those three operators. Or I mean, in Java Script, using low dash or underscore, it will have that. Python has all three of those functions. Ruby has a sustainable library. Most languages have been in the library these days.
But in using those three, it is very easy to abuse those to do things that don’t necessarily make your code easier to read. For example, a lot of times a very common pattern in Ruby is you have an array or a hash and you do dye each on it. To iterate over the array and within those each block maybe you will have multiple operations. Maybe you will test it for something. If it is one thing you’ll do operation A. If it is another thing you’ll do operation B.
Functional language you would express that using Map and Filter. But Map and Filter only usually allow you to do it one step at a time. So if you have a particularly complex operation it’s a lot of times going to be easier to read through things the traditional, each notation.
[0:14:42.4] MN: One of the things that I have seen before is in low dash. I think we have mentioned it many times before, the chain function allows you to chain all of those different functions into to bring one brand new value. You can definitely get carried away with the thing you can do in chain and then look at ends of, “What did I just write? How does this get me all the information I want? I don’t remember.”
[0:15:10.9] DA: You are using the power functional programming.
[0:15:12.8] MN: There you go, well I wouldn’t recommend it in low dash. I wouldn’t recommend chain at low dash because chain pulls the entire librarian which can be very heavy. So if you are actually just using Map and Reduce, it is better to – not Map and Reduce. If you are able to do multiple low dash functions it is better to just call those two low dash functions rather than chain because then you got even all of the ones that you are not using in your entire application.
[0:15:40.0] DA: Right but yeah, I guess chain is a pretty good illustration of composability that you were talking about before. Where you have these little tiny functions that do one thing and now you call chain and you can make this one crazy thing that maybe it is a little bit harder to reason about, but it’s powerful.
[0:15:55.5] MN: But it’s so much fun.
[0:15:56.4] AT: Well Map and Filter are always composable. I know Java Script gets a little weird because of the way the type system works. But Map and Filter in any language that supports proper arrays, Map and Filter is always composable.
[0:16:08.9] WJ: So what functional programming language is the right one? Which one is best?
[0:16:14.7] MN: Ooh, whoah, wow. You’re taking it there now!
[0:16:17.7] DA: Yeah you do, you should.
[0:16:19.9] MN: I thought we knew better than to ask which programming language is better?
[0:16:24.0] DA: I feel like this is the question of like which camera is best for photography. It’s the one that you have on you. The one that you are using right now.
[0:16:33.6] WJ: I just like putting our guest on the spot here. What is the best one?
[0:16:37.1] MN: Which one, yeah Adam which one is the best?
[0:16:40.4] AT: Yeah which one is the best, I mean it’s obviously Haskell.
[0:16:44.0] DA: It’s the one that you have on you, the one that you are using right now.
[0:16:47.5] AT: Well I mean that’s what I eluded to at the beginning of the episode is I have been learning Haskell in my spare time. That’s something I could not have done when I was writing Ruby for my day job because the paradigms are so different and it’s actually probably the hardest thing I have done in programming since I learned the program. The paradigms are so different in the way of approaching writing code is so different. You can do some tremendously powerful things with it.
And as I am getting used to the language and how it works, I am writing what I consider to be really beautiful code and I am finding my code a lot easier to reason about. But it is not something I would ever recommend for client work because the learning curve is so steep. It is hard to find other people who know the language well and understand the best practices. There are very few companies for which is a good idea to pay their people to spend that much time learning.
[0:17:38.5] DA: There is this pretty good article from Michael Federer’s called ‘The Functional Programming as a Ghetto’. We were just talking about that, it was like ghetto by choice because people who love functional programming only want to work in functional programming and you can only work in these little tiny industries that accept you. So it lies in there.
[0:17:58.3] MN: Yeah it is also hard to get a job doing Haskell but it’s also hard to find someone who does Haskell.
[0:18:04.9] DA: Right, yeah exactly.
[0:18:06.7] AT: But there is a company called Genes Tree Capital in the city. They have written most of their code base in OCaml which is another language along the lines of Haskell. That is if you understand functional programming very deeply, it’s not that difficult but if you’ve only done imperative programming, it’s a lot of work to learn it. But it is a great language for what they are doing because they are doing – I am actually not sure of what they’re –
They are in finance hence their name Capital. But functional programming can be great for these large numeric computation systems because it makes it easier to break down the problem into smaller problems. Each of those problems can be separately reasoned about, separately tested and then composed to solve a much bigger piece of the picture.
[0:18:50.4] DA: Yeah, unlike the big data creators kind of ticked off by Map, Reduce where it’s in the name. It’s math and it’s reduced and it really pretty simple but allows you to spread a really big workload over many distributed nodes and get the big result back.
[0:19:10.4] AT: Exactly. It makes concurrency much simpler to implement because of immutability. It makes it much easier to breakdown the problem into smaller parts not only smaller parts that can be more easily reasoned about and tested but also smaller parts that can be distributed across thousands of cores and some of this like OCaml and Haskell particularly are known for generating super-fast code. You have to be careful about how you write the code just like in any languages, there’s a lot of pitfalls.
But you can get in your C performance with much simpler code than you would have to write in C. But again, these are best for very specific applications. Java Script as I had said before, Java Script when you treat it as a functional programming language, it behaves a lot better than it does when you try to treat it as an imperative language and mutate everything. Ruby also has a lot of functional elements to it and these are both programming languages that are extremely wildly unused.
Java, especially Java 8 implemented a lot of functional programming concepts. You have Lambdas now, you can actually take a function and pass it around as an argument to another function. You have streams in Java 8 which you retrieve values from a collection one by one rather than having to load the entire collection into memory, which is a common paradigm in functional programming.
[0:20:22.3] DA: Yeah, I feel like it is interesting how a lot of these disparate languages are kind of borrowing from the same pool of ideas and arriving in a pretty similar place. Like now you have dynamic languages like Python and Ruby and Java Script having aesthetic type checking brought in and Java becoming more functional in interesting ways.
[0:20:45.0] AT: Yeah, eventually every language is going to be exactly the same.
[0:20:47.7] MN: All Java Script right? Is that what will happen? All going to Java Script.
[0:20:53.4] WJ: So who were the heroes of the functional programming world? Who are the icons and the people and that people idealized and what to learn from?
[0:21:01.5] AT: It’s interesting because I have never been big on following the names of particularly people like, “Oh this person wrote this article and therefore I am going to read it.” I feel like there’s a lot and I know there’s people in the functional programming world. There is a guy who wrote a book that is in beta right now which it blows my mind that a book can be in beta.
[0:21:22.0] MN: Who and what? My face is like, “Hmm what does that even mean?”
[0:21:26.1] AT: He wrote this new book, I believe the title is Programming Haskell from First Principles and he’s a pretty big deal in the world of functional programming. He was a speaker at a big functional programming conference that was held a few months ago. I know there’s a few big names like that but a lot of – there is also a couple of interesting podcasts about functional programming but I am not that familiar with the big names.
I spend a lot more time reading, there’s a few articles and a few books that are considered to be authoritative on the subject.
[0:22:00.7] MN: I see. I mean the only functional, I guess the functional programming language book I read was the Elixir Book I think by the creator, I can’t his name slips my mind right now but even then that was –
[0:22:13.6] DA: We can do some moon magic.
[0:22:14.7] MN: Yeah, let’s use the inter webs to figure out the name of this person. I know he was the creator or at least he had the forward in this book and that alone is like everyone reads this book. Like, “Oh yeah, I read the previous version of that book” and I’m like, “Oh okay, I am outdated now because there are so many new books out.” But I imagine that there are the one person for that language and that’s what everyone follows.
[0:22:41.3] AT: Yeah, I find it interesting especially with that with the Elixir that you mentioned because it is pretty rare that somebody who created a language is also so talented at teaching the language. I feel like that’s not necessarily the common state of affairs. There is people like Rich Hickey who wrote Clojure, he speaks at conferences and he obviously knows more about Clojure than anybody else because he is the one who wrote the language.
But that is a lot of other books that are written by other people that are consider to be great books on the language for example.
[0:23:11.4] MN: The book is by Dave Thomas and I believe the Creative Elixir has a forward on it and is very communicative in the Slack channel. I managed to get an invitation from there. I imagine if I could get it, anyone can. Often times, you will see that people have questions about it and the community is really, really cool for Elixir.
[0:23:30.9] AT: Yeah.
[0:24:31.1] MN: The community is actually really cool for functioning programming in general. There is a Slack, I believe it is called FP Chat, that I have been lurking for a while and there’s a lot of big names. There is a lot of different channels for different languages and there’s a channel for Java Script and there’s a channel for Ruby and there’s channels for Haskell and OCaml and all these hardcore languages. But in some of the smaller communities, there is a lot of big names from the community at large that actively participate.
I know Elixir, in the Elixir Slack, Ujay Evalim is one of the creators of Elixir and Chris McCord who was at the Phoenix Framework are both regular participants. I’ve had discussions in Slack with Chris McCord, a super nice guy.
[0:24:09.4] DA: Rubbing elbows.
[0:24:11.1] MN: You have no idea who I am. That was a very insightful conversation on functional programming. I feel like I learned a lot from Adam today.
[0:24:19.4] DA: Yeah definitely.
[0:24:20.9] MN: How Java Script is going to take over the world, right? Is that what we got out of this? Well like functional programming in general and how it is a complete different thinking process and how you should use it in the workplace and how all of the languages that most people use actually have functional programming features in them.
[0:24:37.4] DA: Yep and making it easier to work and like think about how your function or how your program is operating and you know, being more composable and doing dependency injection and then all of that fun stuff.
[0:24:48.3] AT: And easier to test.
[0:24:50.0] MN: Yes, easier to test. Yes, do we have any teach and learns today that you want to discuss?
[0:24:55.3] AT: Yeah, I have one. There is a testing framework in Java Script called Jest which has been around for a while and I had looked at it a while back and thought, “Hey I am not really interested in using this” and then very recently I have seen people start talking about it again and apparently they have been through some pretty major version updates. I went to take another look and now it is really good.
[0:25:17.1] MN: Yeah, I know. I have definitely heard. I remember looking at Jest and I was like, “Hmm no, I’ll use Imilka, no thanks.” But now you mentioned that and now Jest is a thing everyone should pay attention to.
[0:25:28.3] AT: Yeah, all the cool kids are using it now. So I mean it’s a great thing that now the creators have stuck at it and came up with something that is really good. I’d love to see when that happens.
[0:25:39.1] DA: Yeah, it doesn’t hurt that they got stuffed into creating React. So they’re like default for everyone who is starting out in React.
[0:25:46.4] AT: Well a lot of times that’s how it’s happened with Java Script that like Type Script got a huge boost from being default and angular too.
[0:25:52.7] DA: Right, yeah right.
[0:25:55.0] MN: Awesome, I’d like to thank my cohost, Dave, always great having you, always.
[0:25:59.9] DA: My pleasure.
[0:26:00.6] MN: Always and William, I see you, you’re there. Thanks for being around. It’s great having you here.
[0:26:06.3] WJ: Absolutely.
[0:26:07.2] MN: And Adam, Adam thank you so much for taking your time, precious time to come down and record here at The Rabbit Hole.
[0:26:14.7] AT: Thanks for having me. It was a lot of fun, I’m glad I was finally able to do this.
[0:26:17.9] MN: Yeah, I hope to see you more often or rather we hope to hear you more often at The Rabbit Hole. I’d also like to thank you for listening. Feel free to reach us at twitter.com/radiofreerabbit. This is The Rabbit Hole, we’ll see you next time.
Links and Resources: