Functional Principles for Object-Oriented Developers
transcript
good morning jenra it's wonderful to be in Poland that this is my first time here and I'm very excited to be talking about functional principles today how many people have done any functional programming ooh a lot wow wow okay some of this you guys will already know then but that's okay because I'm not going to talk about functional programming today except that I'm going to talk about it a lot but what I'm not going to do is teach you how to do functional programming in a functional language instead I'm going to teach you what I learned from functional programming that I use in Java so this is all about how to think differently in ways that will help you write code in an objectoriented language so I've been writing Java for about 10 years and two years ago we had a project that my company swore this project was super important for a super important client and the project was called pricing engine and we spent about two months up at the front of this it was supposed to be four-month project um writing the UI and iterating through it and showing that to the client and then finally we got to the meat of the project the pricing engine itself whose job was to take all different kinds of inputs and all different kinds of prices and determine how much money the client could expect to make from this contract and management uh who had done the estimate and created the project plan for the pricing engine had given this portion the actual engine of the project four weeks and I looked at that estimate and laughed but you know we dug in and we did our best and fourman months later we had something that was functional that met the requirements we knew about thing is this was 2 years ago and if I had known then what I know now about functional programming I would not have laughed at four weeks I would have said this would be a lot easier in a functional language like Scala if we have to use Java maybe I need six or eight weeks just knowing how functional programming works Works would have cut the time for that portion of the project at least in half probably more so that's why I'm here today to tell you what I learned from functional programming and how I tie it back into my Java code so to start with let's go back to what we all love about object-oriented programming back when oo was new we thought we thought we would create all these objects and we would line them up and fit together and get beautiful complicated applications in an elegant architecture now and then it actually works that way but at other times other times I get a problem that doesn't seem very big and I apply my best objectoriented design principles do it and it comes out looking like this because objectoriented programming is wonderful and it has some great applications but it is not the best Paradigm for every single problem so there are lots of oh all right so functional programming will solve all our problems right no just like oo functional has a lot of problems that it is well suited for it just happens that a lot of the problems that functional is well suited for are problems that are more and more prevalent today concurrent programming lots of parallelism web programming works really well with a functional mindset whether in a functional language or not so there's lots of programming and uh Corey Drew who's one of my favorite conference attendees remarks that functional programming is just one Paradigm and any new tool or Paradigm you learn will help you in all of your code including this one so let's look at the different paradigms these are just a sampling of a couple different paradigms and there's one confusion that I want to point out when I first heard the term functional programming I said functional well that's stupid we've been writing functions forever why would we go backwards but I was thinking about procedural programming procedural programming is where we use functions to organize our code but all we ever do with a function is call it it returns we call in another one it Returns the difference between procedural and functional is that in a functional Paradigm we don't just call functions we pass them around we return functions from functions we compose functions lots of little functions into slightly bigger functions that do more so we break things down into a lot of little pieces that's just a good idea composition is a good idea in all cases so don't get functional confused with procedural I'm going to talk about six principles today and these These are principles most of these um these phrases are mine but not all of them so data in data out immutability these are crucial and we'll talk about all six of these and for each principle I've got six pieces the name of the principle what it is what the purpose of it is is how we already do it because all of these we use already in some form or other in Java and then I'll talk about what's the point why we why we should do this more and finally we'll see examples for most of them in Scala how many people know about Scala half good good good so Scala is a functional and objectoriented hybrid language on the jvm Scala I I get to use Scala in my day job now which is really exciting um Scola is more objectoriented than Java so you're not losing any oo switching to Scala or thinking about code in Scala but it adds the functional um Paradigm support and most importantly we'll see examples of how to use each of these principles in Java okay so First Data in data out and I think this is the most important and has the had the biggest impact on my code data in data Out means that most of your code most functions or methods should depend only on their parameters and should do nothing but produce output now if that's all any of our code did our applications would be very boring because a data in data out function always returns the same output for the same same input always and that as a whole would make for a boring program but it makes for a really testable program so the goal is to make 80 to 85% of our methods data in data out because they're extremely testable in a test you have complete control over the input you pass to the function and you have complete access to the output so there's no need to to set things up in the environment and create data in the database and then take it out in the tear down step you just create your input pass it in get your output back and do some assertions on it this is really good so the goal is to isolate the portions of our program that do need access to the environment or the database or user input or need to put something on the screen we isolate those so that most of our program is data in data out it's very testable and even more important than that it's easy to understand because if you have a function with a meaningful name that describes what it does and the parameters specify everything that this function needs and exactly what it needs and the output specifies everything that it gives you back then you rarely have to go down into the function to find out what it does and this can give us readable code the goal of all of my code is to have the main methods the application logic read like a lesson in the business domain we should be able to read what the code is doing and then the parts that we need to drill down and get more specific we can but we don't have to so how do we do data in data out to get more specific if you have a function that accepts some input and produces some output but in the meantime like Flash and something goes up on the screen that is not data in data out if your function accepts some input produces some output and also poops out some data the to the database that is not data in data out it's affecting the environment when we are affecting the environment we want to call that out specifically don't hide it six levels deep inside a function that says create return output make your database call specific your EnV access is specific I'm going to give three examples of how data in data out affects my code one very high level one a little lower and one extremely nitpicky so the good functions the data in data out ones they don't modify their input they don't access Global State and they don't change anything about the world around them and if your functions meet these three characteristics I should say if you have a method in a class that meets these three three characteristics make it a static method in some other utility class W and that's kind of treasonous because static methods are not objectoriented well no they're not but objectoriented isn't the end all and be all if your function is data in data out put it you can if it's helpful put it in a static method then it's a function then you have complete access to test it and please do test it because if you put it someplace where other people can use it they will um and that makes this is what makes a good static method note that there's a little subtlety like if your method logs something to the log output that's technically not data in data out because you're affecting the environment but that's one that I usually compromise on because now and then logs are useful but if you are writing a static utility method be careful with your logging because you don't want somebody to call it and logs to get big and fat when they weren't expecting that so that's a subtle one all right backing up we want to think about the data flow and I'm going to start from the very highlevel example and this is something just a few months ago um when I was working at a startup we had a task and the programming task was we've got these deposits and we've got these donations and we need to match them together and then record to the database which donation was funded by which deposit and it's quite tricky because not all of them qualify and we've got to match them in the right order and the amounts are not the same and we can match a partial deposit but not a partial donation there was a lot of business logic and before I learned about functional programming I would have solved that problem like this you come in you get the deposits you get the ations you Loop through them you create the links in the database you mark them done you check whether you're finished and then you loop back to the top but these arrows these strings are tying all the different parts of this little program together and that has disadvantages in fact several years ago working in retail I did exactly this when I was matching payments to items purchased and it was hideous and I said to myself I am not doing that again that was the nastiest code I ever wrote and at the time I thought well it's just really that complicated it has to be this messy but I was wrong so Having learned about functional programming this is how I wrote on the Whiteboard what we should do with those donations and the deposits at the top is where we're fetching information from the database at the bottom is where we're putting information in the database both dependent on the environment in between is data in data out and the data kind of it flows from where we retrieve the deposits in the donation and it's clear from the diagram the order doesn't matter on that but the important part is that matching logic that's the tricky stuff that's the important stuff the matching logic in the middle is data in data out so it becomes very testable and there's something else about this once I draw it out like I can tell you on each line in this diagram exactly what type of data and more specifics I could give you more specifics but I know when I draw this out exactly what should be on either side of that Matchbox I've specified requirements and then I draw some circles and each of these becomes a task and each of these tasks can be done by a different programmer in an agile project one of the goals is to take one feature and everybody work on it until that one's done and this lets you divide it up in the previous architecture in the old imperative style one person had to do that because that was all one messy method but now it's broken up and it's specified and it's testable especially the tricky part is isolated from any environment access so I liked this so much that I wrote it up in a blog post and the blog post was so popular it was my most popular blog post and someone translated it into Chinese so I went to that page and had Google translate it back into English and this is what I learned problem easier because we know each step of the way of data that's much better than I could have said it so when we start thinking about data flowing that's really where data in data out becomes really helpful because we're thinking about the data is moving through the program and at any point in that process we can stop it and we can test it we can check it all right so that's the highlevel example let's Zoom way in and get a little bit more realistic and say whatever this is a this is some web application and we want to create an account creating an account affects the database it affects the environment this method is not data in data out however we've done our best to narrow that down and be as specific as possible when we pass in this user DB service that has two functions it gives our method access to the environment but only a specific portion so we've been as specific as we can about what this method can do to the environment now hopefully this method does all its database access in itself but if it calls down into submethods and those methods are going to access the database it will pass this object to them and that way we know reading through the code which methods have access to the environment which ones might poop something out to the database and that's very useful it so it's not strictly data in data out but the environmental access is isolated and explicitly called out that's the realistic goal all right so to get much more narrow Focus methods like this this is just a tiny little private method and these have always bugged me when I've seen them in the code and at first I didn't know why but now I do so here this class has a couple fields and it has a private method for validating the password and it just uses those fields this is very normal but this is not data in data out as far as that method is concerned those class fields are Global State If instead we pass in the email and the pass password even though that method totally could access the fields when we do it this way we're being specific about what the method needs and that makes it easier when you're reading through the code you don't need to go into this method to see what criteria it's using to validate the password I mean you might if you need to be really specific but you can see that it uses the password in the email address and there might be 16 other fields in this class data in data out it's just more specific it makes your code easier to understand all right Dron immutability I hope I don't have to sell you too much on this how many of you already try to use immutable classes whenever you can good good good good immutability we already do it in a lot of ways the but the purpose is this this flows really well with your data in data out functions because one of those qualifications for data in data out was that you don't change the input and if your input is immutable well you won't change it because you can't and we already do this all the time whenever we use strings strings are immutable in Java I like this about them and Effective Java has like whole sections devoted to how to make your classes is immutable and that's a good thing because immutable classes are wonderful and um Changing State in the middle of your program makes it harder to understand but the bad thing is that it took multiple sections pages and pages to explain how to do this in Java it's hard in Java everything is mutable by default and default mutability is accidental complexity so we have to fight this all right first of all why do we care why would we want to go to the trouble to make our classes immutable the real reason is because the less State can change the less we have to think about it becomes much easier to follow where everything's coming from if if it can't change someplace that you didn't expect the excuse that you give your boss is concurrency because every immutable class is thread safe by definition so you don't have to worry about locking you don't have to worry about Deadlocks or things changing out from under you when everything's immutable but the real reason is because it's easier to think about for instance H this was last Friday so I work in Scala in a functional language right and we strive really hard to keep things immutable but I had to use this Library bio Java which is written in Java and I'm I don't know what I'm doing and the documentation is very poor so I try some stuff and I get a nullpointer exception and sure enough at least I have the source code I dig it in and I see that this accession getter return null and so I go and I look at that and sure enough in one of the super classes there's a field called accession and I'm like okay where is this supposed to be set public Setter only update this is supposed to be set anywhere in the world I have no idea where this is supposed to be set because it's mutable State and it's a public Setter so you might as well have made it a public field for all the encapsulation you're getting I was very frustrated so I got a old pointer exception in this case and it's really hard to figure out what I'm doing wrong because this class is mutable and could change anywhere anybody could be changing the state that's the negative of mutable classes one of them all right so immutability how do we do it in Scala it's trivial Scala has two ways to declare um a value or an identifier I should say Val gives you a value which is immutable and that's what you should use almost all the time and VAR gives you a variable that can be updated in our coloring scheme Within intell um any VAR is red red and angry because watch out you get used to that immutability and and you start to be able to rely on it and that's when you really get the paybacks that's when you realize you don't have to think about a lot of stuff that you have to worry about because that state can't change out from under you in Java okay the simple stuff is you just make all your Fields final and initial them in the constru structor that seems easy enough until you start having objects within your objects because any object that contains a mutable object is inherently mutable you may not be able to change the fields directly on your object but you can get the list out and add to it evil evil that's why that's why the default immutability or default mutability is accidental complexity so how do we deal with that well uh collections for instance uh we need to make a defensive copy anything that we get in in the Constructor that might be coming in in an in a mutable class and I say might be because if you're taking in an interface just because your interface like um unmodifiable collection for instance if you get an unmodifiable collection well you can't change it doesn't mean that implementation doesn't have mutability methods on it that somebody else might call after they pass it to you so we make a defensive copy um here I'm using immutable list which is part of guava guava is a library created by Google and it has some beautiful Tools in it guava gives us just a tiny bit of functional um methods in Java only going crazy with functional programming and Java gets hideous guava gives us just a little bit and immutable collections are a big part of that so guava is really easy to import I highly recommend it um immutable list. copy of is a really easy way to create a list that's really immutable you anybody you pass this list to cannot change it and neither can you and then what happens when you do want to change this class you want to add a phone number to this customer in this instance well you can't change the list of phone numbers in this customer because customer is immutable so instead you have to create a new customer and return that from your Setter that's called copy on mod copy on modification and in this case it's a little complicated because we have an immutable list of phones and we need to return a new customer with additional phones so I'm M using another guava class here or static method actually um to construct a new list with all the phones okay so next you say wow that's a lot of copying data that's going to be highly inefficient but in a functional language we do this at an item to the list we do this all day long list processing is a lot of what functional languages do all day long that they're the best problems that they solve so but they're not inefficient they don't reallocate a zillion objects every time they add something to the list so how do they do that in Scala or F or hll or any other functional language the default list implementation is an immutable linked list so a linked list has a bunch of elements and each each item in the list contains both the item is pointing to and a pointer to the next item in the list and in the case of a functional list the last item points to the empty list okay that's easy enough when we want to add to a list if we add the item to the end of the list then we have to change what the tiger is pointing to to the new item and then we have to change we have to copy the watermelon and have it point to that new tiger and so on we have to copy the entire list that would get really inefficient when you're doing this all day long but there's an easier way to do it little bit thinking differently and we just add something to the front of the list and that way we can put the Tomato we create one new list element with a tomato in it point it to the front of the banana list and we're good we didn't have to copy any of the existing list none of it all the only object we allocated was the new object we wanted and it requires thinking a little differently just getting used to putting things on the front of the list instead of the end but it's much more efficient and the reason we can do this is because the list is immutable our Our tomato list can count on the banana the strawberry the watermelon and the tiger never changing because that's immutable so this is a way that immutability makes immutability more efficient all right so in Scala this is how we would create the new customer uh this colon colon thing is called the cons operator for entirely historical reasons I don't like the word but it preens the new phone onto the front of the list and this is highly efficient and we're not making a copy of any of the phone numbers already in the list okay so how does that help you in Java yeah I don't know guava might be doing this under the covers but we can extend this kind of thinking to see that copy on mod is not as inefficient as you might at first think it is because our customer doesn't only have phone numbers he has all kinds of other classes and as long as all these other classes are immutable we're not going to do any deep copies we're going to go ahead and create the new customer with a new list of phones but the same name address birthday and all the cousins we can totally reuse from this class so immutability is awesome it's not inefficient really people worry about oh my God oh my God we're creating objects all over the place we're going to fill up the Heap you know what the jvm is really really good at allocating objects and garbage collecting them and um as long as we're we're careful to reuse the portions of our immutable classes that we can reuse it's not inefficient it's really a great idea and then from the benefit you get stuff that's easier to think about you don't those null pointer exceptions because if I need an accession I pass that accession in it works really well with data in data out oh it's time for the commercial commercial break this talk is brought to you today by the option type the purpose of the option never have a null pointer exception again option is a lot like the No Object pattern which is an honorary mention pattern in the gang of four wherein we have create an inheritance hierarchy and you can have either a thing that is a some thing with functionality or it is a null thing that does stuff but you never pass null and this way you never get a null po or exception option does all that work for you have an option of whatever type you like and you either get some of it or none of it but you never get null Scola uses this with the option type in guava it's implemented as op optional T and if you pass this back from your function somebody is explicitly required to check whether there's something in it instead of just dereferencing it and null pointer exception optional because null is not a valid object reference okay back to the regularly scheduled program verbs are people too all right Steve Yi has a great blog post complaining about how in Java only nouns have rights everything has to be a noun in Java and if you want to pass a verb into a function it has to be escorted by a noun so you can't pass run this you can only pass a runnable and this and it starts to get ridiculous when we wind up passing in the project manager Factor creators we keep wrapping our verbs inside of nouns in Java and Yi's complaint was that every verb has to be escorted by a noun just as in some countries every woman has to be escorted by a man I'm not okay with this verbs need to walk around on their own so verbs are people to means functions or values pass them around and this is the core principle of functional programming this is the one that makes a lot of the others possible so we already do this all over the place the strategy pattern the command pattern the template pattern are all ways for us to supply the how to a class that knows some other surrounding logic pass the how into the what instead of always passing the what for instance um in a a swing gooey or most any other gooey anytime you pass a method you wrap it in an onclick listener and you pass it to the button you're passing a verb you're passing a function and in Java that's that's not pretty but we still do it all the time and we should do it more even though it's not pretty passing around instructions is useful and you don't realize how useful it is until you start doing it more but in my pricing engine project this is exactly what I needed and this is what I would have done differently so this is what I really did in that pricing engine project two years ago um I had I I recognized that I needed functions of all these various inputs because they the values change over time and I needed to calculate totals over the whole of the contract so I implemented a function in time interface and a whole bunch of classes a whole bunch of classes because every variable had to be its own class so that it could implement this value at function differently but in Scola that would have been prettier I would have instead had one variable class and then I would pass in how to calculate it so in one I could pass in inflation as a function of time and we'll just take the power of it um and whereas the seasonal adjustment is actually implemented as an array of VAR closely specified values over time and we could pass that in to a different variable without having to create a class for every single one it would have been cleaner it would have been faster it would have been a lot easier to change but I could have done this in Java this is how I would do it in Java and as you can see it's not pretty because out of all this crof the only meaningful part of this particular particular cost inflation implementation is math.pow 1.15 input that tiny little piece of all this crft is Meaningful so in this presentation we're going to see a lot of cruft I'm okay with that I am okay with more lines of code if it means I can divide the code cleanly into application logic and craft and what the important part is that the application logic reads cleanly and we can see what we're doing in Java 8 look at that it all goes away the craft it's gone so this is another reason that we should be doing this way more because once we get Java 8 and we get lambdas it suddenly gets pretty it suddenly gets readable so for now I tend to just shift the cof off into a constant or utility class somewhere and in Java 8 everything will get beautiful so this is the future of java and we can use it now with some effort all right one of the things that being able to pass functions does for us is it helps us write in a declarative style and a declarative style means that we say what we're doing not how we're doing it we already do this in a lot of ways my favorite example ex Le is SQL SQL is a very declarative style I like SQL because of this because we're not talking about we're not telling the database how to get the rows we want we're not saying okay go to this file and retrieve every record and loop through them and see if they meet this condition no we're just saying okay give me the records that match this Condition it's declarative another great example of declarative Style is Excel Excel is entirely declarative you tell it the dependencies between each Cel but you don't tell it what order to calculate them in Excel just figures that out so leave the how out of it whenever you can and talk about the what make what it's doing clear and if you can make why it's doing that clear and the how let the compiler take care of that so the point is it makes our code more readable we tend to get smaller simpler pieces little one or two line methods with a name that states what they do but the important part is that familiar is not the same as readable a lot of people at my my last job where I was doing Java would look at my code and say oh I can't read that but what they really meant was that is unfamiliar to me so Rebecca talked about this morning she talked about fast and slow thinking the fast thinking is your gut reaction the fast thinking is when you just recognize something it matches a pattern that's already present in your brain familiar code you use fast thinking you just recognize immediately what it does and you don't have to think about it at all slow thinking is when you actually use your brain and think about what you're reading slow thinking is a lot less comfortable but when I'm writing code I'm not thinking okay okay I know my other team members and myself and I know that if I just write it this way they'll all recognize it and it'll be easy for them to read no I want it to be easy for anybody to read and fast thinking familiarity because it's a pattern match it depends entirely on your previous perspective but everybody can do slowth thinking with their brains people don't like to do it sometimes but everybody can so that's the kind of readability I'm targeting if you're thinking about it and you're using your brain then you can read this and you might get a lesson in the business domain this is familiar every Java programmer will glance at this Loop and know immediately what it's doing we're clearly pulling out the lines that start with bug from the input list I hate this code whenever I see a for loop I try to kill it try some of them it's just worth it but this one this one should die this is a perfect example of code that's extremely familiar and Java programmers are comfortable with this because we do it all day long this is what it should look like this is a declarative style this doesn't say how we're getting the items out of the list this just says we're filtering the list for everything that starts with bug and in Java we can do something very similar uh this is a guava method on the iterables class and we filter the list with a predicate a predicate is just a function that returns true or false called starts with and there we've got some cruft that predicate is not pretty so I put it in a constant somewhere and that's okay because now I don't have a hideous for Loop that if it weren't familiar to me I would have to step through and play compiler and figure out what it's doing so this is readable even if it's not familiar and I had to fight a little bit to to get this past the code reviews but once I taunted them enough about what are you afraid to learn something new then they calmed down and they use their slow thinking to understand and that it made perfect sense so another way that we get a declarative style is from strong typing I've talked a lot today about you should be able to look at the method call or the method declaration if you're going to use the method and tell exactly what it does and one ways we do we we get this is by being careful with our types strong typing is really huge in hascal and it's really a big deal in schala too we like to be super specific about their our types now what the goal is that we get a red underline instead of a runtime exception the goal is that we find more errors at compile time and fewer at runtime now here's some data that says that that in hll which is the strongest type language I know um we find almost all the errors at compile time and in Pearl it's completely hopeless I made this data up but the point is we're aiming for more errors at compile time in addition we get the declarative style so this is kind of my excuse really but the declarative style is more important to me so we already do this Rebecca talked a little bit about domain driven design today one of the tenants my favorite tenant of domain driven design is to come up with a universal vocabulary a project should have a glossery and the same words should be used by the customers the analysts the programmers and the testers and not just when they're talking about business Concepts but in the code itself the beginning of wisdom is to call Things by their right names and the more specific we can be then the more wise we are so jav is strongly typed obviously duh we use strong typing we don't even have a choice about that yeah we're lazy we don't really use strong typing we use it as much as we're required to but every time you create a a user for instance out of a first name that's a string a last name and a string and an email address that's a string lazy watch out for that we think it's strongly typed well it has to be a string well okay you didn't get an integer but did you get a first name what if the colar of your method switches the first name and last name you're not going to notice what if your email address has a invalid characters in it you're not going to notice so we can be a lot more specific about our types than we typically are that first name that first name is not inherently a string it's something a lot more specific than a string it happens to be stored as a string it's entered by the user as a string and it's stored in the database as a string that is not what it is that is an implementation detail so if you have a first name make it a first name so in schola that's easy you can do it this lazy way and just say hey I got a type called first name and it's a string you get a lot of the declarative style benefits out of this not so much the safety because any string that you pass in will be converted do a first name but at least your customer Constructor specifies that this parameter is a first name so you get a little bit more of the specific declarative style frees you up to name your um your input whatever you want because what it is is already specified in the type you can be a little more strict and um create a case class in Scola and this way you have to explicitly conver convert your string to a first name before you pass it in okay in Java um we can do this it's just really painful so you create your first name class you've got to implement two string and hash code and equals and blah blah it's a lot of craft push it off somewhere in a library and you can still do this for the record I do this sparingly in Java but when it's important then I really care um and then when you want to create the first name um I like to make a static method that does the construction just to make it as concise as possible on the other side of strong typing is the interface segregation principle and I'm not going to get into exactly what this means in Scala because I don't have time but I will point out this gen iterable parameter this this is a method on list so if we were writing this in Java we'd probably assume we're getting a list but Scala is being as general as possible and saying I just need anything I can iterate over and then I can tell you whether it has the same elements as me in Java we can do this so if we're checking a c whether a customer is valid but really all we check is the email address we can be more specific by passing in anything that has an email address and then we get some more cruft we get an interface and we have to implement it in customer but now our method is more generally useful so the excuse is oh look my method is useful in more places but the reason is my method is very specific about what it requires this way you know what it's validating without going into the method okay last principle lazy evaluation dang it and lazy evaluation means we delay the evaluation of an expression as long as we can this also would have helped me tremendously in my pricing engine project because I could have used it to not calculate the values of variables that I didn't need we already do this all the time whenever you pass around a provider or a factory you're delaying the instantiation of the object it creates SQL cursors are a beautiful example of lazy evaluation because when you get a SQL cursor when you pass that around you're not passing around all the data that it could ever retrieve you're passing around a how I'm giving you access to retrieve this data but we're not actually going to retrieve it until you need it I like that okay so what's the point well you may never even need it you may save some evaluations like I would have in pricing engine that's the excuse that you give your boss the real reason one of them is that you can separate what to do from when to stop and I'm going to show you what that means so here's some classic imperative Java that might be familiar to us and to figure out what this is doing first I'll just tell you so hypothetically we have some bug in the code and we need to gather data because it only happens in the production environment and it's intermittent so we added a log statement and this little program reads the log file until it finds the the output statement that we added and then it emails me when it finds one but but only up to 40 because I don't want it to spam me all day long after 40 I should have enough information okay but but I cheated I told you what it does really as a as a programmer who came in to modify this code to find out what it does you would have to play compiler you have to step through it and figure out what the compiler what the computer is going to do is it executes each line what it's going to change what's going to be different if you're reading code and playing compiler you're doing it wrong anybody can play compiler real developers work at a more abstract level a more declarative style okay so in this code this is the code that reads in the data from the file this is the code that decides which data is relevant this is the code that formats it so we can send it in the email and that's the code that decides when to stop okay I I'm using guava here and there's a bunch of crft that you don't see this this actually took more lines of code but here's the important part we get the data from the file in this code here's the code that decides what's relevant here's the code that formats it and here's the code that says when to stop I'm going to move so everybody can see it that is a separation of concerns that is single responsibility and single responsibility principle is our most important principle as a developer so I don't care if I had to write that random file iterable which is the stateful part and I I had to write a predicate in a transform function that's okay you can see what this is doing and this is possible because of lazy evaluation because in a guava iterable nothing is ever calculated until you need it so that random file iterable has the capability of retrieving files from um lines from a file indefinitely it'll just keep reading until something's added to the file and that filter never happens until this as immutable list will trigger the actual processing and because we have this limit 40 on there only 40 lines will ever um be drawn from the file be filtered be transformed have three minutes um so lazy evaluation of that iterable separated when to stop and that let us break out these different responsibilities okay that's all the principles we saw them all I want to end with alist Coburn's oath of non- Allegiance I promise not to exclude from consideration any idea based on its source but to consider ideas across schools and heritages and paradigms in order to find the ones that best suit the current situation it's all about which Paradigm which way of thinking solves the problem right in front of you so I would like to thank optional for sponsoring this presentation and don't forget to thank our real sponsors that actually made this presentation possible and I'm Jessica Care thank you thank you very much
- from
- Talks
- added
- 2026-10-10
- likes
- 0
Talks › Categories > Functional Programming: “by Jessica Kerr (JDD Conference 2013) [51:13]”