Intro
Duncan McGregor: Hello and welcome to "GOTO Book Club." I'm Duncan McGregor, and today I'm delighted to be interviewing Uberto Barbini about his book "From Objects to Functions: Build Your Software Faster and Safer with Functional Programming and Kotlin." It was published by Pragmatic Programmer in September. Uberto Barbini, welcome to GOTO Book Club.
Uberto Barbini: Hi, nice to be here, Duncan.
Duncan McGregor: So, Uberto, we worked in the same circles in London. You were a technical reviewer on the book that I wrote with Nat Price, and then I returned a favor by being a technical reviewer on your book, but we've never actually worked together. So, how did you come to work on Kotlin Projects in London and now in Japan?
Uberto Barbini: I was working in banks in London, and... I started learning about Kotlin many years ago, before Version 1. At that time there was also another programming language in the JVM that seemed more promising. But after a few years, Kotlin grew on me and I started using it in the banks. Then I started looking basically, at the beginning we were using Kotlin, you know, introducing slowly creeping to write a test, to write a little tools. Then I started looking for a gig where I could write Kotlin all the time. I think more or less we got in touch and at the time London Kotlin community, back then the Kotlin community was not that big.
Functional Kotlin
Duncan McGregor: So what prompted you to write the book? Who's it for?
Uberto Barbini: I'm very passionate about functional programming, but also about writing good code, you know, with good practice. And I didn't find much content outside about, yeah, how to put together the two things. So, all the books about, you know, TDD, or clean programming or stuff like that tend to be very object-oriented. And all the book about functional programming tends to be quite, you know, very specific exercises on specific things on functional programming. There was no book about, yeah, how to set up a full project from scratch and adopt a functional program with a kind of pragmatical point of view, let's say. So, I think it's quite a useful book for people that came from a Java background also culturally, but use a bit of a, like Java Agile, I mean, simple Java, and they wanted to touch a bit of functional programming. Or people coming from more functional, advanced stuff like Haskell or Scala and wanted to use a... I mean, take advantage of Kotlin's simplicity and productivity.
Duncan McGregor: I should say, the book isn't a sort of academic book. It takes a project, it takes, the example is a sort of to-do list if I remember. And it takes us from sort of inception, the initial sort of prototyping through to a sort of complete database-backed application with a web frontend and so on. And I found that was quite refreshing, it's not just how do you... It's not just, "These are bits of functional programming." It is how to plug functional programming into an entire project lifecycle.
Uberto Barbini: We have a lot of beta readers for this book. And I mean, most of them appreciated that. Some people were a bit, let's say not pissed off, but a bit disappointed that there was not much theory or more drilling down super specific functional programming thing. But I kind of stand my position, because I think it's not functional programming for the sake of doing functional programming. I mean, the point is to deliver an application at the end. In our job, we want to deliver value to the user. So, I'm trying to say, "Come on, with functional programming, we can be more productive," at least for a kind of applications like backends, where... So, this is something that I did, and I think sharing, it can be useful for other people. It's not about let's learn how to use a 25 kind of monads or stuff like that.
Balancing Object-Oriented and Functional Paradigms
Duncan McGregor: Kotlin is a sort of multi-paradigm language. I think Scala took that mantle first, but we can write procedural, we can write object-oriented or functional style. I think, I mean, Kotlin sort of probably starts from OO, being on the JVM. Lots of the sort of libraries we use are object-oriented. But how would you look at some Kotlin code and decide that it was functional versus OO? What characterizes functional programming for you?
Uberto Barbini: The first thing is that it's not that important that is functional programming object-oriented, but I appreciate that the advantage of functional programming is having functions, basically everything is designed using functions, and putting the function together to do some feature, I mean, to do some tasks. The good thing is that you know, combining these functions, each function does just a bit piece of work and is very defined, clearly defined, from the input to the output. So, it's easy to test, and it's easy to use in another place if you have to do the same things. And then you put it together and you have a function. So, when instant code started to reference external things like singleton or external calls without being specified by the type system, then it became also very hard to reuse. I mean, I remember someone that... Actually in the banks at some point, someone was doing some calculations and got a function from another piece of the program. But that function was locking a lot of stuff, and just using that function slowed down the whole application. And we realized in production. So, this kind of stuff it's kind of easier with the functional programming to see what you are doing without the kind of casting the code.
Duncan McGregor: My experience of good OO is that it sort of shares those same sort of properties. Do you think there's still a place for object-oriented programming? Or do you think we should look at all problems as functional?
Uberto Barbini: No, no. I mean, I think this is a great thing about Kotlin that you can use both. Because a lot of classes of problems are much easier to do in functional programming. Or also if we wanted to break the rule, let's say, and have a, like an internal cache or stuff like that so far, that is clearly defined. And it's very convenient, convenient I mean, it's very productive. I can just do this stuff keeping the code clean and having this stuff done. Plus all these kinds of problems require a kind of simulation, where you keep a lot of objects with an internal state that is alive for a long time, they are a much better fit for object-oriented programming than... Functional programming is great when you have a kind of flow of transformation. So, it fits more naturally web server or ETL application that just reads from a message queue and writes to another message. This kind of stuff, which is quite common in the banks and another kind of big backend is great, I think.
Duncan McGregor: Certainly that's something I've sort of come to realize. I suppose only read recently that the object-oriented programming I learned was about, in memory, user interfaces where everything about the system was in one place, we could manage state in our memory. Whereas he says, we just don't have those... We don't program like that anymore, everything is thrown away between requests, and nothing stays in memory. We assume that our state is all gonna be held somewhere outside of our program. So, do you think that functional programming... Where am I going with this? Yeah, functional programming has sort of risen with web-scale things. And that you've...
Uberto Barbini: For this kind of, yeah, cloud or, what is it, a cloud-native, or however you want to call it. This kind of application, where you just, yeah, process the request to responses. And everything is... You keep the state outside the application, so you wanted to have a kind of security around the state to avoid it making... To have a runtime error or stuff like that, because the connection was not open or something like that. All this stuff came very naturally. I mean, it very naturally fits with functional programming. I think in your book you mentioned working along the grain of the language. And in this sense, it's also working along the grain of the application. I mean, you need to do something like that in a kind of cloud-native distributed stuff. The functional program is a very good approach in my opinion.
Duncan McGregor: I think I've concluded that we are still using OO, but the objects that we have are servers now. And that we're using message passing, polymorph, and all those sorts of things to implement OO between things and then functional programming inside those applications?
Uberto Barbini: That's definitely a way to see. I mean, the actual service work is kind of external, from an architectural point of view, they work a bit of a light object. And also this is a bit what... I mean, we are doing a bit of philosophy or history of computing, but Alan Kay came up with this idea that basically objects are a bit like computers on the net. Something like that. Which is not super helpful in my opinion. I mean, it's not super performance-wise a great idea to implement everything like that. But when you have the stuff that is on the net is very good.
Duncan McGregor: I think Alan Kay also said something about the things that Java and I suppose Kotlin, do in terms of OO is not object-oriented programming. It's class-based programming. One of the things that I struggle with in functional programming is that we learned, in OO, that encapsulation was a thing that, like, having data and the operation on those classes together was an important thing. Functional programming says, "No, actually they should be separate." Where do you sit on that spectrum? When do we decide? How do we decide?
Uberto Barbini: In our team, we have the thumb rule that, to decide when to use lambda or an interface just to, maybe it's clear to you, but to clarify. Let's say that you have a function that needs to assess the database. And so you need your function that writes something and you pass another function that assesses the database and gets the user. And then at some other point, you need a function to write a user to a database. Now, the general object-oriented approach will be to define a kind of interface of the database layer or stuff like that, where you put all this stuff together and it's fine. I don't have anything, but if I needed to pass this data assessment object, every time I needed to assess the database I made to pass too much. Because if I just needed to get a user, I'm passing an interface with 10 methods or 20 methods that I really don't need. So in that case, just passing a single function is an advantage. It creates less coupling. Yeah. Our, rule of thumb is that if you need one is okay, if you need two lambda it's okay. But if you need a three lambda from the same kind of interface just pass the interface, something like that.
Duncan McGregor: I think that's probably the rule of thumb we came up with in the book as well, that if you have to express a coupling on reading and writing, then you should probably have an interface. But if it's just reading or writing, then just one thing. Yeah.
Uberto Barbini: That's another great thing about Kotlin, that they allow you, first to leverage on the whole Java world libraries that are huge. And then you can kind of take the Java library and just pass the method, the lambda reference without having... I mean, in Scala enclosure, you need to do a lot of things to be able to interact with Java. It's not that easy.
Beyond Kotlin: Embracing Functional Thinking
Duncan McGregor: Your book has Kotlin in the subtitle, but I don't think you... Would you call it a Kotlin book?
Uberto Barbini: I mean, it's definitely, it's a Kotlin book. You needed to read Kotlin in the book, but I think the kind of teaching, or the approach, let's say is not specific to Kotlin. A couple of beta readers don't use Kotlin as a main language and one learns Kotlin just reading the book. And they were using TypeScript mostly. They said that they can mix a lthey ot of sensoro the support for TypeScript application as well.
Duncan McGregor: It's my experience that Java developers and TypeScript developers come to Kotlin quite easily. There are sort of changes in syntax, but lots of the sort of fundamentals are there. It's an easy language to read, and it's quite an easy language to write. Could you have written the book in a different language?
Uberto Barbini: I mean, why not?
Duncan McGregor: How would it have changed if you'd written it in a different language, I suppose?
Uberto Barbini: There are a few culturally specific things. I mean, things that make more sense. And I had to work on a Java project recently, to be honest, and it's kind of painful to use functional study in Java because everything became a bit harder and harder and harder. So you tend to write less functional stuff because the type declarations are very long. To do some transformation in the collection, you needed to use a stream. Everything is more verbose and it came so... And on the other side, Java programmers when they switch to Kotlin, intend to keep the same Java approach before learning kind of Kotlin idiomatic way. But the main... Sorry, just the main point, I mean, writing this application, I think if had to write in Typescript or some other language with a bit of functional capabilities, it won't be that different.
Duncan McGregor: I think it's trendy to say that the language doesn't matter. But, I do find that the things that our language makes hard we don't do. I had a comment on one of my videos recently.
Uberto Barbini: Doesn't make sense.
Duncan McGregor: Somebody was saying, it was a video on property-based testing and somebody was saying, "Oh, you introduced a type here in a way that I don't think that a Java programmer would, because, you know, introducing a type would've been too painful." But because in Kotlin it's sort of like three lines to introduce a type then it's very natural, I find, in the language to solve problems with types, it's a natural language to solve problems with the things that are easy to do in the language.
Uberto Barbini: In Java, just the fact that you needed to create a new file kind of stops you. I mean, even if the file is just two lines is a bit different if you just put the template, yeah, it's smaller.
Duncan McGregor: I was an object-oriented developer in the 90s, and I had the definition of polymorphism of Pat. It was required in job interviews at the time, but your book talks a lot about thinking in morphisms, what do you mean by that?
Uberto Barbini: The kind of breakthrough of functional programming is when I started realizing that data is not that important. What is more important is data transformation. So, looking at the programming, like the design of the application, like a chain of transformation instead of a flow of data, let's say. And this transformation, I mean, categorically, well, the most general way to call a transformation, yeah, is called a morphism in mathematics. This idea of thinking in morphis, how you transform, without even looking at the code first, but just start looking at a web server as a machine that transforms a request in responses. And then for each possible part, you see, here, I'm transforming a user ID in a user content or web page. And every step is at the end is transformation. And there is this theorem in category theory, which is called Yoneda Lemma, which mostly says, I'm paraphrasing, that, "If you know all the functions from a data type and to the data type, you can identify univocally the data type." This idea that the connection is actually more important than the data shape itself.
Duncan McGregor: Yes, I've heard you say that a type is not the data, it's the operations on that data. Is this the thing that defines the type for us?
Uberto Barbini: The type is, yeah, the shape of the data, but it kind of gets uniquely defined by the regulation that it has with the other data. So looking at...
Duncan McGregor: I'm interested in your background. We didn't hear your education. Where did you learn Category Theory? How has this this come to be?
Uberto Barbini: I mean, it's self-learned, and I'm not an expert. But I mean, I spent part time... I always been, to be honest, interested in mathematics. I didn't finish the university, but I mean, I was studying. Category theory is very mathematical. And I also, to be completely honest, I don't think it's needed to... I mean, if you like, I think it is great, I got a lot of fun and insights. But you don't need to learn category theory to use a functional programming. It's a bit like you don't need to speak Japanese to prepare sushi or to appreciate sushi.
Decoding Functional Paradigms
Duncan McGregor: Can you give an example where thinking in morphism leads to better software?
Uberto Barbini: For me it's a bit like, when we approach a problem and, you know, just we need to do this typically this new API to connect these other two systems to get some result and give the result to the user. This is kind of typical. And instead of, you know, start drawing squares and arrows like this, for me, it's a bit of a, "Okay, what is our input and what is our output?" Trying to identify the transformation and then see, okay, this is the main transformation. So we have, I don't know, a financial product ID and the output is some kind of price or fair value. How do we get from here to there? There are a lot of possible transformations, and possible ways to do this using the system and trying to concentrate on this kind of flow, let's say. And this for me, I mean, thinking in this way, thinking about all transformation, how to put the transformation together, rather than trying to think about, "I create a service A, a service B, service A call to service B." The result may be similar but the mental process for me is very different.
Duncan McGregor: I wonder whether that's a place where...AI can help us, that if, as you say, effectively you're thinking of the type signatures of this transformation, and we know we've got... I've got this ID for this thing and this way of trading this ID for this piece of information, I need this piece of information to find this, that maybe AIs would be good at plugging together those sort of pipelines.
Uberto Barbini: I mean, in a sense, I don't know, maybe just me, but I always find...You said that you started object-oriented in the '90s. I was starting programming in the '90s, and I think I got object-oriented in 2005. So, after 10 years that I was trying to do that... And object-oriented for me has been always a kind of, you know, poetic, it's a bit like literature To get something that works together is a bit hard. Instead functional program is more mathematic, so it's probably something easier for AI to plug together and verify that is...
Duncan McGregor: So, on that subject, I mean, yes, OO has a sort of, not mystique, but it has a sensibility, a sort of like, there is this idea of smells and this idea that this is the system that wants to come out of this problem, isn't there? I've heard it said that we don't need patterns in functional programming. Because patterns were sort of the OO's way of collecting things that didn't smell, ways of collecting nice shapes of things. And there was a lot of talk early at least that patterns were working around the lack of functional paradigms in the languages. But it seems to me there are lots of places in functional programming where we have to learn these reusable solutions to problems. I think from your book, I read about the Reader monad, and that finally sort of clicked for me what problem the Reader monad was solving. But is the Reader monad a pattern in functional programming?
Uberto Barbini: I'm a bit, let's say, why is he using the monad word because have a lot of weird... I mean, some people are saying, "Monads, no, no, no, no." Some people say, "Yes, monads only monads," which are both wrong approaches. And the point is that the monads are a mathematical construct. How you translated that mathematical construct in code is not a given. There could be several ways that you can do that. And, of course, everybody tends to use the kind of an... Well, there are a few variations, but mostly the same approach, but it's still just one possible approach. I think this kind of approach is a pattern. The monad itself is a kind of a mathematical concept that sometimes, I mean, stuff that has been called monads are not much more monads. No programming monad is 100% a mathematical monad. But some are not, probably not even 10%. They just use monads because...
Duncan McGregor: The same, of course, is true of patterns that we learn patterns, but then the thing we call that pattern is not necessarily all of the patterns as it's defined and so on. We kind of stitch these things together, don't we? We build software out of things that play this part in this pattern, or this part in this, you know, in this other pattern.
Uberto Barbini: I remember when the pattern book came out and people at that time were writing stuff like this is a visitor pattern class or abstract factory. You put the name of the pattern in the class, and then the class may be changed. So, in the end, it became super confusing and stuff like that. So I tend now not to use any monad name in my classes. Just use the monads pattern if you want. The idea that trust... It's just a generic that you can transform basically, and you can combine it with other generic, and this idea of transformation makes a lot of sense to me. And also kind of a mark when you have something... if you have a generics around database connection or transaction, that function will be called in a context. It came quite naturally. It's also a good point to mark..
Duncan McGregor: It seems to me that pattern names in the names or types were an anti-pattern, but they were useful for documenting what role this thing had. So, it was good for documentation, good for comments, but not so good for the names of things. And I guess that's probably true of, you know, functional patterns, readers, writers, and so on.
Uberto Barbini: It makes sense if the other people know about you can communicate very quickly, but if the rest of the team is not familiar, it's just confusing.
Functional Programming: Balancing Pleasure and Frustration
Duncan McGregor: On the subject of the rest of the team, I think your book taught me a lot about how, what should I say? Real functional programmers think about solving problems and how to evolve that software as we ask for new features. But how would you go about evolving software on a team from objects to functions?
Uberto Barbini: I think the important thing is to keep the team together, so as not to fight any code that the team is not comfortable with. On the other side, I think is a good idea to keep a bit of heat on. So always trying to introduce a new concept and stuff like that. In my previous team, I mean, same company, but the previous, we were two people of us was coming from, yeah, this kind of functional culture. We introduced the idea to the rest of the team about using results in the operation and stuff like that. And the rest of the team was a bit like, "Well, this is different from using exceptional, how we are using, but let's have a try." And they enjoyed it. The whole project switched very quickly from one to another party. But I mean, I've been in another team where the feeling was really, "No, no, no, we always did it like that. This is not what we are going to do." But yeah, that's also fine.
Duncan McGregor: So, in the preface, you say, "Functional programming makes my job more pleasant every day, even if it drives me crazy sometimes." I think your book does a good job of showing how you can make software more pleasant, but in what ways does functional programming drive you crazy?
Uberto Barbini: I really enjoy having fun about, solving the problem in using transformation. So okay, I can do this with a side effect, but if I can make this explicit to the type system using maybe C class or some kind of stuff like that, it's better. So, this is the stuff that I really enjoy to do that. I think the final code is less backbone, but sometimes it's very hard or you sometimes say, "Okay, now let's go back because it's..." So sometimes making the stuff compile is the most difficult factor, and once it's compiled, you are quite sure that it's correct.
Duncan McGregor: That balance of pragmatism versus correctness, I think, especially again, as we were saying earlier, where what your language makes easy defines pragmatism, I suppose. I know there are places where the Kotlin-type system... There are things where you end up casting that you might in another language than language might see that something was safe, for example. Certainly my experience of Kotlin is it's pragmatism can lead to frustration sometimes because we can't express something we want to, in the same way as we might have problems with Java, making it harder to create new types than we'd like.
Uberto Barbini: There was some stuff that I would really like Kotlin to make a bit easier to do, because there are some, yeah... For example, yeah, the companion object, a bit under user in Kotlin, in my opinion, would be a much better way to use that. And to express some time would be nicer. But actually, yeah, this is true. But what they see is that most people, they really got scared from the beginning when they see the kind of code that I show at the end of the book where basically everything is just a chain of, you know, map, fold and transformation, binding. And so every functionality is just in a single expression. And people got a bit scared about that. On the other side, I think... I mean, in the book there is this origami... Because, you know, in functional programming there is this faulty function. But it's really that functional programming is a bit like origami, and seems much harder than it is actually is, after a while if you learn origami, it's not that...
Duncan McGregor: From what I know about origami, though, sometimes you have to start off with a lot bigger piece of paper than you think you might from the end result.
Uberto Barbini: Ah, well, I mean, the professional one, they really start with the, like, one square-meter piece of paper to do.
The Evolution of Software: Learnings from Writing 'From Objects to Functions
Duncan McGregor: I know the process of writing a book helped me to think about software. Did the book turn out as you sort of planned it at the beginning, or did it change your understanding as you wrote it?
Uberto Barbini: No, this changed a lot. I kind of rewrote it two or three times, I mean, depending on... A bit from the... I mean, the original idea was to have a book, like, "This is the theory, this is the practice." And the editor told me, "No, let's just be the practice. Forget the theory." I think that was a very good suggestion. Then when we got to the beta readers, also I found that I was skipping a lot of mental processes and stuff like that. And when I started doing it slowly, I tried to put it down, I also realized that, yeah, maybe I can change things and make it clearer. And when I finished the book, I realized that, "Okay, if I had to rewrite this book again, I'll probably remove also a lot of...not to remove, but put the theory after. I don't think you need that. I mean, I kind of passionate, I really enjoy doing mathematical stuff, but some people bit got scared about that and it's not really needed. But, yeah, well, you can always skip that part of the book.
Duncan McGregor: Personally, I found the book sort of challenging. But it was enjoyable because it took us through, as I say, unlike most functional programming books, it took us through an actual example from the beginning to the end. There's motivation there in every step. So, we are solving problems and looking at how those problems will be solved in a functional way, rather than just having them in the abstract. So, we are motivated to read the theory, I think. That worked very well for me.
Uberto Barbini: The book is a to-do application, which may be, I mean, to-do list, but actually it's quite a hard problem to solve, to write a good to-do list application. Originally Java do a kind of a more, you know, kind of, Jira kind of software to ticket-processing software. But I realized that just to-do application is a lot of code to write and to explain the code, it really takes a lot of time.
Duncan McGregor: And so finally, Uberto, do you have another book in you? Or is it too soon?
Uberto Barbini: I still have some blogs to write about this book, I mean, and things that I couldn't really put in the book. But my daughter is a 9-year-old and I'm teaching her to do programming, but without pushing, but we do some sessions. And also to her classmate. And I really find it fascinating teaching programming to kids. And I don't know, sometimes I would like to write something about it or to put it together, the experience. I am not very happy with how they teach programming in courses and stuff like that. And instead working with kids is so rewarding, but, you know, you need to raise the interest and let them explore. Programming is a creative activity. Most of the courses seem that programming is like typing.
Outro
Duncan McGregor: I think we've come to the end of our time. Is there anything else you'd like to say about your book?
Uberto Barbini: Yes. One thing that we didn't mention, is that in the book I also put an exercise at the end of each chapter and this exercise is very useful to learn functional programming, but there is no solution in the book because of clearly a choice. But all the solutions are still available on my GitHub repository. And we will put the links here. If you have the book and you want to see my solution, which is not given, that is the best one, you can always see it in the GitHub repository.
Duncan McGregor: Wonderful. So as Uberto says, that will be in the show notes as well as a link to his book, "From Objects to Functions: Build Your Software Faster and Safer with Functional Programming, Kotlin." Uberto, thank you very much. It's been enlightening.
Uberto Barbini: Thank you very much, Duncan.