Duration 34:29
16+
Play
Video

RailsConf 2019 - Sprinkles of Functional Programming by John Schoeman

John Schoeman
Product Consultant and Developer at thoughtbot
  • Video
  • Table of contents
  • Video
RailsConf 2019
April 30, 2019, Minneapolis, USA
RailsConf 2019
Request Q&A
Video
RailsConf 2019 - Sprinkles of Functional Programming by John Schoeman
Available
In cart
Free
Free
Free
Free
Free
Free
Free
Free
Add to favorites
2.56 K
I like 0
I dislike 0
Available
In cart
Free
Free
Free
Free
Free
Free
Free
Free
  • Description
  • Transcript
  • Discussion

About speaker

John Schoeman
Product Consultant and Developer at thoughtbot

Product focused software engineer knowledgeable in web development and data engineering. I enjoy collaborating with others to build great products that users love. My ever expanding skillset includes Scala, Kafka, Elm, Ruby, Rails, TypeScript, ReactJS, React Native, GraphQL, RDBMS/SQL and related technologies.

View the profile

About the talk

RailsConf 2019 - Sprinkles of Functional Programming by John Schoeman


Often in Rails apps there is a need to accomplish tasks where we are less interested in modeling domain concepts as collections of related objects and more interested in transforming or aggregating data. Instead of forcing object oriented design into a role that it wasn’t intended for, we can lean into ruby’s functional capabilities to create Rails apps with sprinkles of functional code to accomplish these tasks.

Share

Alright everyone. Let's get started. This is my talk sprinkles of functional programming for beginners like to say a couple of thank yous for stuff. Thank you very much to resend school for inviting me to come speak today in super thrilled to be here and be yet another amazing rails conference. They only think all of you guys for coming in joining me on this first hour of the conference super excited about this material at that a lot of benefits to my programming practice over the past couple years. I've been thinking about these things and I'm excited to be able to share with it with

it. Share it with you. So, I'm John I work at. Botts the developer is a Consultants. When I was when I first told some of my colleagues that I had to talk a couple into the rail, very first thing they said was his all the best railsconf talks. Have a have a Twitter slide. Turns out I don't have a Twitter, but I still made you a Twitter slide. That is my real GitHub. If you want to find me on the internet, and I just go by my name John Schumann. So let's just dig into the talk. My goal of

this talk is to convince all of you that the ideas in the functional programming style are worth thinking about and bringing into your rails practice and it helped give a lot of benefits in terms of qualitative code effectiveness of developers. So a roadmap for this talk will start with a thesis or the key points if that established get go suck a little bit about functional programming and metaprogramming very high-level different people tend to mean different things when they say these terms are bit ambiguous. I'm going

to explain to you what I mean when I say though so we can all be on the same page to make you a recommendation. You'll be a story that's going to have some code. That's what was that is where we will spend most of our time today and then we'll recap and we'll have a An action item to kind of go home with to try that take home with us. One thing in those that's not on this road map is I am not planning to talk about implementation details of how to write functional functionally styled code and like the line by line faces. So if you have zero exposure to

functional programming, it's totally okay. We won't be going over to those things in detail, but we will be spending most our time in a much higher level talking about kind of why and where you might want to consider functional programming and Leah slide at the end with some resources if I'm successful and inspiring you to go learn some more on your own good good starting points for you. So I was just taken to the thesis. Hopefully the points that we can all agree on. First off is Ruby's a general-purpose programming language multi Paradigm

programming language is excellent at both object-oriented programming and functional programming. We have the developer get to choose which style as review as soon as you're all very familiar with classes inheritance funding methods inheritance polymorphism encapsulation, so and so forth but we also have access to things like we have the innumerable module B25 introduce yourself as a list of Van into 6, so they building a bit of pipelines is even more convenient. Another more functional ideas are coming in as time goes on. Second point is a different

paradigms lend themselves to different tasks specifically object-oriented programming comes to be very good at modeling behavior for functional programming, Tennessee pretty good at handling. based off of those two 2 points I'm arguing that we should as developers was doing rails developers. We should be choosing a programming style based off of the task at hand doing so will lead to ultimately better products. I mean specifically by that if you'll forgive me from just reading correctly office light here. Is it your modeling

Behavior? You should be preferring classes and composition as where if you are handling data, if you should be leveraging the appliance and bolts about special programming programming like most people when they're talking about them. They focus a lot on objects and functions, which is a a great way to categorize different programs in terms of their style in object-oriented programming uses objects to sort of the base unit that we build it more complicated things from as we're functional programming uses functions in that role and I think

from especially from an academic prospective. This is very useful. However in my day-to-day development practice and I'm shipping things building things. I found that considering what's difficult to change in the different styles is a more useful distinction to be paying attention to And to describe that I have a table here. I'll let you all read it for a moment and then we will discuss. So given a change that you want to add so you want to add a new method that is a new behavior and I'll be going to program is is one such that is very

easy to do you tend to not need to I need to change existing code. You can just add that method in there and it works as riding your data tends to require some more factoring eat. Stuff apart. Put it back together functional programming on the other hand is the opposite adding a new method cancer require some change the code as we're adding data tends to be easier. You can just do that and move on with your Talent Susan typical cases for LG phones programming anything with modeling in the name. Usually so these are your users and your posts interactions between

entities in your business domain whether that's an admin can edit a comment or your notification systems things that are nouns that you can kind of point at. Functional programming typical cases usually anything with the data in the name of data transformation aggregation. These are the moments where you need to be able to text data and some point a and want to get to point B, whatever that means. Maybe you have a bit of data Json blob that you got from the API and you see realize that you need to save it in your database somewhere. Maybe you're importing a file to CSV.

Maybe you're generating report or you have some data that you need us wash down and get an average something like that. Cool. Do that in mind. you know stock was inspired from multiple instances during my career code that I've written so that other people have written and and improving that code by bringing some of these concepts of what is difficult to change between the two Styles and it's really out of really out a lot of value solved a lot of pains and I kind of distilled a recommendation for the face of those experiences that I like

to share with you here. So given that methods are used to add an object-oriented programming as where data is easy to add in functional programming. If we ask how we expect requirements to change before beginning a given task specifically asked that question based off of the context of their business whatever which want whatever problem we're trying to solve whatever value and add particularly considering what users might want in the future. You know, that's a hard question to an answer. If we do that and then choose our style based off of what we think there are a lot of good

things will happen. Recommendations so I made some pretty strong assertions about what is easy and not easy in the different pair of the different paradigms. I'd like to illustrate why I think that is with a story. The way it's going to work is I came up with this fictional company with this fictional set of feature requirements. And then I saw them all with an object-oriented approach and then I kind of turned back to dial in South mall again with a functional approach went down a different branch of us what a choose-your-own-adventure story. So

that's what we're going to go through and it will compare and contrast the results at the end of that and see if there's any Lessons Learned From that narrative Additionally there going to be a lot of code and I'm going to be going through it really fast. So I'm going to encourage you not to read it in deeper than like a squint test anything that is important to highlight. But if you're trying to reach 100% comprehension it probably going too fast for that to be reasonable to expect of yourself, but said I have all of this code up on GitHub repo Australia flight at the end. So if you do want to

go through it line by line later that's available to you after the time like for everyone to imagine a rails app. This is a typical sort of rails monolith. It's a products for a business medium size would say there's a developer's on the team. There is a product manager of the practicing agile. There's a sales team the nature of product doesn't matter too much but for the sake of the story, let's make a concrete in my head. I'm imagining a company. That's me to be there their application allows for small businesses to come in. The product upload

some inventory that they have that they can present a user's so users can come or potential customers. Excuse me. So customers can come and review it by their products to the shopping cart of some sort. I'm imagining like his Craigslist and product hunt had a baby something like that. So here's where we starting currently users can come to a products index. I can fill out the product at the care about using a typical rails form. That's a couple things have value in this case rails to the value of over 9000.

And awesome. You just think Ray products and that's great. We're having tremendous business success. We're bringing on new clients. All the time sales team is currently in negotiation with new clients biggest one we've ever had their so big. In fact, they have so many products that they have a concern that I need to upload some new products that manually entering all of these is going to be unfeasible and it changes every month. It's not going to work. So they asked the sales team is like it we have this infernal CSV that we use for tracking or inventory, just like put that up on an

exit to do server and you guys can kind of import that somehow and the sales team says, yes, we can do that. So they set a deadline for when this is going to be done and then they come bring it back to the company give it to the product manager gets put on the road map. It gets put in the Sprints the developers start work out of Sprint goes well and they're successful they end up with the pr gets up through code review get submerged in the Avenue commit. Our first committee are allowing users to upload to see if your products a quick look at the code on

this company practices tdd. So we'll start with our high-level feature spec a user visits a root path. They attach a file my own escape the fixture of products in CSV The Click upload file and then we make it some sort of expectation on count. I will have a route for this Imports. Where will hit a method on a product model or passing the file again will start with us back again. Don't don't need to read everything. I'm into fine. If you tell us more about the story will start off by stubbing out to CSV product held in Fort Worth Final Fantasy when they can expectation and here's the

implementation. All we're going to be doing is it raining over each row of the CSV massaging the data a little bit whatever. That means say, we're getting a string for a date. When you to convert that to a date time, idolize the product title something of that nature and then we'll leverage active record to save the store Davis. Life is good here is where we ended up with. We have an Imports controller. We added to a product model for aspects. We added features back attitude long spec me a picture. And life is good. There's a gift of kind of way. We ended up with.

We're demoing. It's to our brand new clients and they are ecstatic who knew that uploading csbs could be so wonderful to new computers can be so amazing. So I took a few weeks ago by everyone's happy people are selling the products before making money life is good sales team is a negotiation with a new clients. This one's even bigger even more exciting for the company. But this client here they don't use CSV is internally they do everything with Excel. So there has two tails team is like well as you guys can upload

CSV is what about Excel files and the sales team is like, yes, we can do that. So they said the deadline to bring it back to the company they get in the roadmap to get it into the next Sprint developer start work. We're going to start off going down or object-oriented pat. First thing we noticed is that there's some opportunistic factoring that we should probably do. It doesn't make too much sense to have the Imports in the product model. We're going to introduce service object to handle. This concern will introduce a product data importer in a

very similar spec except this time instead of calling import on product or products Ada importer. We're going to instantiate it with passing in the file path to the Constructor will call him for it and we'll make an expectation of the output from the Tatian very similar to before his can I move this logic elsewhere now, we have art instructor with our file path. The implementation of reading through the files the same now or controller is going to do then Sensational, and put on the Importer life is good. We also noticed that there is some separation of concerns that we can introduce we

can pull out the formatting portion of the important portion here. So we introduce a new service object to handle that product ate it for matter. This one is filled the date of hash from the CSV wrong so that we can I build a product out of it. There's life is good. Here is the info mentation gold lamp to CSV processing the data. We need to returning that data life is good. So now we've done that hard work of doing that were factoring to make a change. We want to make it easy. So we go ahead and have a nice place to put this new Excel logic will start again with her spec instead of this time

will step out an Excel file as opposed to CSV easy enough to do. Here's the invitation will just case on the file extension in 1 Import. Whatever type we need to think a notice here. Is that the initializing around my pants when composing with the format or so we can swap it out later for other formats if we need to down the line and that feels good. We get that ships. We have a lot of units in our history develop reproductive. Everything's working. The client likes it and we move on to the next client the next this client doesn't even matter if they do

CSV or external, but they have a different currency formats that we need to be able to handle whatever reason they put dollar signs in front of all their prices as opposed to using floats and not to each their own. So but we need to be able to handle it if we want to be able to import their data. So again, will you start up we start work? We know some opportunities for factoring. So we're going to introduce some separation of concerns of make a lot of sense for the Excel and the CSM important. I live in the same file. We can put those in their own places for maintainability make them easier

to understand. So we'll go ahead and do that before this time will step out a CSV implementation is almost the same. What is a similarity for the Excel file this time? We'll stop at the Xcel instead and then we'll pull this implementation out here. We noticed that there is a lot of kind of duplication between the Steam from the station to Willits tracks class for them to inherit from a flat file and folder. We will in Spanish Island Porter this one all we do is make sure that someone over rights to import method that

we provided is an invitation and now we can share that code among Steve fell in Porter in the CSV and Porter and life is good. What do something similar with the building up of the data, you know, there's a similar amount of separation of concerns that we can introduce year will start with the product a to fill their which to CSV and Excel won't import Initialize the formatter builds live R-Spec hear what we're trading has two products data. Well and Century the Builder passing in the four matter will build up to see a stereo using a

dildo implementations nice and simple easy to understand he's going to test because of this test-driven will be something similar with the Xcel Bill are similar implementation. Who's on all of our dreams? We've done all of our peanut puffer coats and now we can come in we can introduce the new currency into our 4matic. So that's what we'll do with respect when the currency has a dollar sign in front splitter wall strip to the dollar sign from it will start with some sample data that has a dollar signs and

she had a formatter call format on that data make an expectation that were saving it for converting it properly into an integer. And here's the invitation. Why the helper message when I am currently passing the data on this G7 out life is good and we ship that get it in a new plan on boards and so on and so forth this continues for the life of the projects. We're always adding new clients on updating our code requirements of future requirements, and she was kind of where we ended up with over those couple of Sprints. When should use plenty of service objects to sort of

handle the separation of concerns because we did we have sex for all those as well. So we're well tested we have nice test coverage there were protected from regression tests in addition to the definition and other good benefits are testing. You know, everything works clients are on board and everyone's happy the code is working. But let's take a step back. Let's reset the clock to the beginning and go down the functional path. Let's explore this other Universe where perhaps in this scenario the developers recently

attempted railsconf where they saw talk where someone was talking about. Well, if you have you no changes and data requirements email functional approach might be beneficial and they think about it for a moment before starting work and they say it's like, well you have a new client can have a different set of data, but the behavior is always going to be the same roads going to be importing a CSV Excel whatever whatever and we're going to be sitting in the data somewhere that behavior never changes but the data will change. So let's let's try the functional pathan and see how we like it.

So you are first requirement for our first new client was they want to be able to handle Excel? Similarly to the object-oriented approach. We are going to introduce a service but instead of this time it being a service object were going to introduce just a regular service will use a class but I'll will do is expose a single function could use a module or whatever to be similar but totally different because we will be using a fixture as opposed to stepping out something out or CSV file. So we'll import the fixture once and Sharon Porter to get access that function will

call in for passing in the file name and it would make our expectation on the products that we made that there are correct. We'll start by pulling out the existing code from the product model in here just to remind ourselves is kind of what we're working with cool. Then we'll immediately introduce a data pipeline welder factor that code since we were factoring the sex when you change it all we can just do the code that long so I can splint test the thing I noticed here is that we have a single height a single public function available to us importing the file path and a

bunch of private methods in support of that. I don't blow that up to look at it a little bit more closely. Local here. We have her import function and across the state of function. And this is our sprinkle of functional programming so few lines, let's go over it real quick start with reading the file passing in the file path. This is just going to return an array of data. We're going to enter a over that or a process passing the data into our process data function will not over that and create products based off of that product process data. Wanting to know on this

important functions at the top here is that I've separated the io from the data processing functional programming teaches us to do that teaches us to separate our side effects from our peer functions and that allows me to have this nice clean data pipeline for process data where it's easy to understand if you detest going to start my processing the dates and then I will use Ruby's then method to chain on the next processing function that I need. If you haven't come across a vignette it was introduced me to 6 basically all it's doing is taking the

results from whatever you're calling it on passing them to the block that you provide and then using the results of that block. So this is sort of rubies answer to convenient datapoints and it works really well and we should all be using it a lot more. Dustin so now it's a darn you change we want to be able to add the ability to read from Excel as well as his feet wide and his back is going to be exactly the same as the old Speck except this time our fixtures going to be in Excel. But the format of the stack is exactly the same where we just

have an input we run our function of meat make an ex expectation on the output. Here's the invitation because I've separated the reading from the processing of the data. It's very easy to just kind of slipped Us in here and I need to change an existing code. All I need to do is add the ability to read that file again will case on the file extension and then I thought data into that the process data function in so long as I maintain the same if you are that is returning a Rave theater. Nothing else will need to change. And I said we should that these are can use Excel and then our next

client comes along who needs the ability to add dollar sign to their prices. So we will add an extra minutes for my in the currency from CSV. All we need to do is update or fixtures such that includes the date of the different formats that we want. So it's pretty easy just open a bar CSU fixtures, and we add a new date of that. We need to be able to handle. Implementation of that is similarly pretty straightforward. All we need to do is add a new function at the end of our data pipeline

passing and then processing the currency similar solution. We're just going to strip a guy using d-sub passing in the data. So on and so forth and that's it like this good time moves on there was much rejoicing and success people are making money. So a quick recap of where we started and ended we started with the initial to see in Porter then we had a new requirement and then a new requirement and then so on and so forth as all projects. I do. So this is like I mentioned earlier the stock was inspired by some real life events

and improving things. It was really couched in noticing that overtime. The real important part was the things I need to be able to change and so I knew that introducing some of these ideas let you a lot of benefits in the code bases I was working with but it was really nice to kind of go through this talk and kind of build up this experiment which she really started out as much as an experiment. I didn't quite know exactly the extent of how beneficial One path over the other would be nice to be able to kind of do this where I can kind of we can compare and contrast the results

without the noise from other things happening in the project. And so if you are a few of the things that I noticed specifically first off the code was a lot clearer if you go back and look at the object-oriented solution where we ended up with all those just relatively few features added we ended up with a lot of stuff here. This was particular. Difficult for me to load all this up in my head at one given time to understand what was going on. Imagine coming back to this and six months and then you spend a lot of time to respond up Emily. We had all these specs that we needed to do to

maintain aspect coverage for all of those the similar supportive added complexity to our test Suite compare that to the functional style where we didn't add any models. We added a single product data importer with one input one sort of output and that was it or tests were similarly. More compact we have more fixtures because a relatively easy just open them up and look at them notices. They're significantly less code in the functional approach. Here's the total dip. So the total

the total code added at the end of the day from our starting point about a factor of 4 in terms of added code. Which is interesting to see but I think more importantly is the accumulated if I noticed was significantly higher. So this is the total added difference for each commit at it up. So for example, if you have to commence the first one switch has two lines in the second one ton does those two lines the totaled if there would be zero cuz nothing change but these she might have difficulty + 2 - 2 cuz it was + 1 - 1 twice. That's what I mean and dumb

ass was just relatively small set of features. Imagine over the life of this project. If we continue adding more clients to our narrative this would just grow and grow so that I thought was interesting tidbit. Does Thanos says there's less maintenance. If you consider the number of public apis of the object-oriented approach added there was eight as opposed to functionalists 1 all of these are going to need test. These are going to need to be taken ownership over the life of the Project's anything could rely on these in the future and we need to pay attention to that moving forward to

maintain that they are still useful and accurate Auto Center code. The finest thing probably the most important one to me that all the other ones are divided into you is for significantly higher development faucet e it took me about a day to do the object-oriented approach has it took me about an hour to accomplish the functional style. I had that one features back from the very beginning covering me the whole time and the functionality was exactly the same. So this is this is cash money. This is your development time that translates directly into

dollars and how productive you can be as an individual contributor or how productive your team could be coming after you if you start off on this path, choosing the right paradigm closings RI noticed I'm going through this Exercise Works in paradise house. I thought they were pretty interesting. The first of which was there's a lot of something or classes here. You know, we have to build her we have the Importer. We have the other building be at the format. The other in Porter I do to keep going maybe you even want to add a

validator something of that nature something or class to me reads a verb that I've forced into being a noun if you think about it for a moment, there is no concept of a builder or for matter in the domain Logic for this application. These are Plantation details that are masquerading as as nouns in our system. They don't actually exist or not useful to anybody but reading is at a glance you might get confused and I think this is one of the biggest reasons why it took me longer do the all different style. I didn't have a real world Concepts to

reason about to make a mental model of the world. These didn't have anything like that. So Need to get kind of confusing lost even over from a couple commits ago. These are all the classes I added model diagram ended up being a linked list. If you follow the data through the system that I made a little hard to see as you're adding a single commit single PR here and there but if you look at it holistically from the from the end, we start up the Imports controller with passes to the Importer, which delegates do at a subset of the

importers Astro Builder validator formatter ultimately riding the database. I basically built if a data pipeline anyways, it just is spread across eight different files now, I'll talk about some takeaways high-level lessons from from our story the first which of which is its useful to be to consider how requirements night might change. I think that's the bell peppers. It's really easy to just get a task and just start doing things cuz it's fun. We like programming like I'm I'm a hobbyist on my side I do this for fun. So I got started. I like I'm

betraying the programming it's feels very productive and it's easy to just get going. But if I'm not considering how my code requirements my change and they will iPad cost for that. 2nd which is sprinkles a little of this goes a long way in two ways. The first of which is it if you go home and think of the message from this talk was to completely rewrite your happy do everything a functional style. That is not it if you if you look at the amount of kind of functional Kota attitude just a handful of lines. You could come up with

a similar sort of example where you forced a functional Paradigm into a task that really lends itself to object-oriented programming and you would find similar results in like the opposite way in terms of mist benefits of taking out a user resource for example, and kind of put that into a service for the interact with your system is is a challenge and would be a good idea. The second bit I mean by sprinkles is that you don't need to necessarily learn Lambda calculus. You don't need to be an expert in a school to introduce some of

these ideas into your the only practice. There's some really easy to approach Concepts there that you can go off and learn and bring into your Redevelopment right away and don't need to get too much farther than that. Finally, I think be conscientious of Business Schools before starting work similarly to kind of thinking about what might change in the future I think. considering the needs of others before you just start doing things goes a long way and goes to be much more productive and I think one of the

things of the talk that I'm coming away with that sort of underwriting everything that I'm I've been thinking about is to really avoid Audiology, you know how to pick the right topic for the task and when you get it and consider how that might affect the business in the line your peers down the line. An action item something to take home with you and before beginning your next task asked how you might expect requirements to change and if it's day to consider a functional style if it's Behavior considered an object-oriented style, she ceases to round us off Ruby's

multi Paradigm language different paradigms on themselves a different task and we should be choosing our Style by PSY. There's one thing that I look like for you to take away from this. I'll talk it's this three lines here. Like I mentioned earlier if you're interested in getting a little bit more and functional programming is some great resources out there. Gary Bernhardt has a wonderful talk lesson online functional core imperative Shelly. Just Google that. Buy our blog we have a lot of great resources from our developers Hibbett Sports some of these ideas and made some wonderful blog

posts, and then there's another nice talk by mr. Swanky on for blending functional programming in Ruby. Here's the repo if you're interested in looking at the code and more detail from the examples of functional programming. App. And that is the end of my presentation. We have a few more Moana. If anyone has any questions. Or you just call it a day. Thank you all very much.

Cackle comments for the website

Buy this talk

Access to the talk “RailsConf 2019 - Sprinkles of Functional Programming by John Schoeman”
Available
In cart
Free
Free
Free
Free
Free
Free
Free
Free

Access to all the recordings of the event

Get access to all videos “RailsConf 2019”
Available
In cart
Free
Free
Free
Free
Free
Free
Free
Free
Ticket

Interested in topic “IT & Technology”?

You might be interested in videos from this event

September 28, 2018
Moscow
16
173
app store, apps, development, google play, mobile, soft

Similar talks

Craig Buchek
Senior Software Engineer at Weedmaps
Available
In cart
Free
Free
Free
Free
Free
Free
Free
Free
Betsy Haibel
Technical Coach & Software Engineer at Cohere, LLC
Available
In cart
Free
Free
Free
Free
Free
Free
Free
Free
Jordan Raine
Software Engineer at GitHub
Available
In cart
Free
Free
Free
Free
Free
Free
Free
Free

Buy this video

Video

Access to the talk “RailsConf 2019 - Sprinkles of Functional Programming by John Schoeman”
Available
In cart
Free
Free
Free
Free
Free
Free
Free
Free

Conference Cast

With ConferenceCast.tv, you get access to our library of the world's best conference talks.

Conference Cast
644 conferences
26393 speakers
9799 hours of content