Simplicity: Not Just For Beginners (or How To Write Simpler Code)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what I wanted to talk to you about this morning is what I've been doing for the last few years about how do you write simple code how do you design things to be simple it's it's a word that I've been using but I realized that I needed to back up a bit and actually explain what I mean by simple because it's a deceptive word and different people think it means different things so there's more than one way to keep things simple I teach C++ as a thing like intro to C++ C++ fundamentals but I also teach in groups and one on one individual pieces right here's a new thing that we just got here's how it works and why I want you to use it from now on and no matter what you're teaching when you are teaching something you tend to start very simple you deliberately leave things out we should be making sure that this number you know is even or positive or a number in the first place but we're not going to do that because I want to focus on something so if I'm trying to teach someone what the modulo operator is in C++ a whole pile of stuff about how you can't take it of a string it's not helping anyone right we're focusing on that one thing and so we tend to assume our inputs are reasonable and work we certainly assume they're not malicious talks about buffer overflow attacks and those sorts of things are wonderful but they don't really belong in how do I call a standard function to parse a string into an integer very often an algorithm for getting something done will work in two directions here's what you do if the two elements you want to move around in the collection one is before the other and here's how you do it if one is after the other and we will often only show half the work and that I guess we are doing to keep it simple that is not the simple I'm here to talk to you about today we don't do those things by the way because we're stupid or bad or lazy we do them for very good reasons we are not trying to teach the universe we're trying to teach this one little grain of sand and so we show this one little grain of sand and we let the learner concentrate on that one thing if every time we taught anything we surrounded it with all of the error checking and malice checking and unit testing and best practices there would be no room for the thing the person supposed to be trying to learn I'm a Canadian Marshall McLuhan was the Canadian he said the medium is the message this is a true thing we write samples that will fit on a slide we write samples that will fit on a single page of the IDE using whatever screen you're likely using when you're teaching the person that's what the whole we're only gonna do one Direction thing tends to come from and it's not wrong that's what I really want you to understand all of these things come from a good place we're trying to lower the cognitive burden on the person who's trying to learn what we're teaching them even scrolling can be a cognitive burden so when you're talking to a beginner when you're talking to a newbie you do a certain kind of simplification to ease their learning process and I'm not here to say that that's bad okay the other reason that we do some of these things in samples like this is because they are completely imaginary it's also why the variable names are so terrible you have a vector of integers called V because it's only a vector it's it's not the unfulfilled purchase orders right because that's not what you're doing you're not writing an order management system you're showing people how to sort a vector and so you're a vector and ends up called V but in real life after someone has received that kind of training life is more complicated than that in real life you have to check you have to make sure that you got the sort of input you expected you have to do the calculations forwards and backwards up and back before and after so of course the code gets bigger it gets more complicated it has to be more complicated but unfortunately some developers maybe even almost all developers they start to internalize something we're not beginners so we don't want simple real life is complicated and look at me look what I can do right like this wooden carving I don't know how long that took but that's amazing right I will point out to you it's behind glass because it's so brittle that if someone were to touch it it would break have you not ever once said half and joke as my mother would say and whole in earnest if it was hard to write it should be hard to read if it was easy anyone could do it we have a little of that in our hearts and that's what I want to address when I talk about simplicity this is a word cloud from a survey that the foundation did of C++ developers now to be fair the question specifically asked about difficulties so the fact that you see the word difficulty in big letters it wasn't like they said what do you think about C++ they said tell us about your difficulties and so we got these words but hard to understand difficult to understand impossible and my favorite nope look for keywords there's context / there's references which might mean the ampersand thing or r-value references but couldn't mean books and tutorials right we don't know what that word means without the context I don't see Otto I don't see no except right people didn't say key words when they said what they didn't what they found difficult but they sure did find things difficult so what I want to advocate for today is simple code as defined by this list of adjectives not short code not using small words code right Nazi Jane run code what I call simple code is code that explains itself when you read it you know what it does you understand it it says find unfulfilled orders ship ready orders update order lists it's got words in it it's almost like reading a story you understand it and you understand it on the first try code that surprises you where you go wait what oh oh that's a bitwise or okay fine I don't want that that's not simple code that fools you the first time through called code that needs a comment to explain what it really does as opposed to what it looks like it does is not simple transparent code you know has nothing to hide I'm not against encapsulation in fact encapsulation is one of the best ways to achieve simplicity but obscuration is a different game I've had pushback from my last bullet on this slide that code that meets all these things that lays itself out in front of you tells you what it does hides nothing does what you think it does becomes pleasant that you could actually enjoy working in that code base and people have said things like if it was fun they wouldn't pay you to do it so let me tell you a secret it can be fun and they will still pay you to do it because they needed done and if you're doing it well it really is fun ok I'm going to say that simpler is better it's like spoiler alert yes but you know I'm pretty active on Stack Overflow and all the other Stack Exchange sites and they have a hate on for subjective questions so if you go to the travel site you're not allowed to ask which is better to go on vacation Italy or Switzerland because that's not a question with an answer that can be correct or incorrect and that's the problem with is simpler better first of all better than what but also define better so let me ask some slightly more detailed questions might be better because you can write it faster it might be better because it has less bucks it might be better because it's more performance it might be better because it's easier to read or easier to change or as I mentioned more fun so let's take a look at those is it faster to write simple code no no no no no here's another wooden sculpture very different from the previous one but was that like an afternoon's work for someone no right making things smooth and even making things match up can be just as hard as making things ornate and complicated it takes work in fact there's that famous quote I'm sorry this letter is so long but I didn't have time to write you a short one the first time I wanted to use this quote in a talk I went to the Internet to confirm who wrote this talk this quote opinions vary Mark Twain if you're an American you probably think Mark Twain wrote this Blaise Pascal gets a lot of credit and Samuel Johnson gets a lot of credit so apparently you just pick an off there I'm gonna pick Margaret Atwood as Margaret I would famously said but the thing is it is more work to write a shorter letter it is more work to write simpler code you need to build new habits you need to look at code that works right you ran the tests it's good it said seven you're like yes I was going for seven but you're not done because you're going to review it you're going to revisit it you're maybe going to refactor it so that it goes from being code that works to code that works and everybody can see why that's effort but maybe it's effort for a purpose because it turns out that usually when you make this code simpler it is also more correct someone writes something that is complicated across many axes it's very long it's maybe spaghetti code the variable names are horrible there's no functions there's no classes nothing is explained it's riddled with comments in the first couple of comments you read aren't correct they say sorts but there's no sign of any sorting that kind of thing that code often has bugs in it really simple example ra íí- it's wednesday so we've got 2 full days behind us and two in a bit days in front of us and I have heard someone say embrace ra íí- at least five times and I will hear it another five right and it's not a new concept those are still people who aren't when your cleanup is in the destructor you can't forget to clean up that means using our AI I makes your programs more correct is that why most of us do it I see no hands is it cuz it's way easier to write that way yeah right it's simpler for us put the cleanup in the destructor and carry on about our business the destructor will be called when the magical closed brace occurs or the exceptions thrown or the return statement or whatever so that's simpler code no one has to read through the six different clean up blocks scattered throughout your long function but there's no bug of that sometimes we don't flush the file thing that happens when you're doing all your cleanup by hand and that's not just a one off against our AII this way of writing code this way of saying yeah it works but now I need to make sure that it shows that it works actually some bugs disappear as you're doing that because you thought it worked but maybe it didn't quite I really advocate and I will have more tips about how to be simple but you can see I'm mushing them in with the benefits I really really advocate look for places where you're setting up future inconsistencies so if you have two functions that are very similar they perhaps take a different number of parameters in the future every time there's a change we have to change both of those functions and they can become inconsistent if you write one function this doesn't always work but if you can write one function and give a default value to one of the parameters of that function well now tautologically there's only one function which means there's only one place you have to make the future changes which you can't get out of sync so you stay correct going forward into the future and also it's simpler for everyone I've been on those projects I remember once we were in a language that didn't have a mechanism for us to do the kind of overloading we needed to do so we were doing copy and paste inheritance and they wanted a super simple change let's say it was a wording change it wasn't but it could have been and I said I have to make the change in 18 places this is how many developer hours it's going to cost you to make the change in 18 places make the 18 commits do the 18 tests and I like it's not worth it if we get a change in one place they would have done it so anytime you're taking advantage of you know it being the 21st century you're going to take away those efforts to keep things in sync later on the problem with copy and paste inheritance or even just copy and pasting the same 50 lines of code everywhere is those 50 lines of code should stay the same and they don't so you make a function that gets called then you only have to change the function you can't get in consider and the I'll say embrace templates if no one else does but I think a few other people have if you've got a bunch of functions that are very similar but take different types there's no inheritance involved you can still write a template at function and again now you just have to change the template add function instead of all the similar functions it's more work right you're writing the shorter letter you copy and pasted your way to a bunch of functions that look a lot of like each other but they're great but if you close the door and move on what are you setting up for when there's a change in the future and here's a weirdness and I noticed it first with REI but it happens elsewhere when you have all kinds of complexity all over the page and you decide to do some encapsulation you invent some kind of an abstraction and you move this five lines and these eleven lines and these 27 lines into functions maybe destructors but it works for anything obviously the calling code gets shorter it also gets simpler in the sense of being expressive and transparent because the functions have names which is amazing so you can read now in the calling code instead of reading 400 lines of code you're reading words from your business domain that talk about orders or employees and that talk about shipping and updating and pricing and refunding that's great but you know we've only swept it under the carpet right well no weirdly when you go into the class the class ends are pretty simple let's go at five member functions some are five lines long some are thirty lines long they've got good names they've got parameters with names it all makes sense and you're loved kind of looking around where did all the complication go and I have to tell you I see it evaporate that's a gift what the heck we'll take it I'm also going to plug other people's code who likes other people's code it's very early in the morning but I'm not getting many hands at all maybe a fifth and some of them were slow like wait maybe I should say I like other people's code I love other people's coat we'll start with this reason they already tested it okay especially if it's a standard library I probably have at least one maintainer in the room they tested it they've thought about what if you're assigning to yourself and all that stuff did you forget to check for and they have more correctness than you simply because they've started it before you did what what faster wouldn't it be great if it was fun and maintainable and readable and you were proud of it and it was also magically faster probably not compare these two lines the simpler one is like hey let's just use Auto alright Auto is great thank you love it embrace Auto almost always Auto but whatever Appy is presumably some kind of person object if it's Anna collection of people maybe it's expensive to copy maybe not this might be a dinky little loop this might not matter but it's not faster to do it by value right it's close enough to the same or it's slower so in order to get the benefit you have to know something and you also have to be able to retrieve something right at that moment so right while you're writing the loop you have to you say to yourself mm maybe a reference and that level of knowledge it's not just knowing it but having it pump up and tell you at the exact right moment to use it is non-trivial to achieve so the absolutely naive aspersion of most code is not as fast as the version where you come back and make it perform in the same way as the naive aspersion of most code is not as simple as when you come back and make it more readable more expressive more transparent I am never going to advocate that you choose simplicity over performance but you will notice that the word if is in bolt if a real choice exists go with performance but that's a big if compilers are amazing optimizers are amazing if you get the brilliant idea that like oh this variable in the side this loop never changes I should move it out of the loop yeah you are like little baby says the optimizer and guaranteed they're better than you if you haven't measured yet guaranteed okay don't measure your debug build come on measure your release build see if you even have an issue and if you do have an issue then go for performance in that case but not before and hey let's mention libraries again guess who might be faster than you right again because it's their job and it's because what they do but also because they know a little bit about how the rest of the library is implemented so in any given situation they may be able to write something that you could not I don't want you to think that writing the way I want you to write is nothing but a gift to the Future yesterday I got a lot of Twitter traction by asking you to imagine that your code will be maintained by your own child when they're a grown-up how would you write differently then but it's not just that you're going to be in this code again this afternoon right you as soon as you finish typing it you read it over to see if it's correct or not and then you test it and if you get a surprise you're going through in the debugger so from the moment the code has left your fingertips you benefit from it being this kind of code I did some work once in Perl and I once watched other people working APL which uses a lot of Greek letters and we used to joke that these were right only languages and some C++ kind of has that right only feel to it as well but you are the very first reader of your own code and you do it like microseconds after you've finished writing it so be good to you as well as to your imaginary successor and of course there's there's you in ten seconds and there's you tomorrow and there's you in six months that super clever trick that you pulled you may really regret it in January you may really really regret it in 2020 and when you've changed laptops and you don't have the document anymore that you wrote about how the trick worked then you're really really sorry I come back to this because I get argued about it you can really enjoy reading things you can read over code and going to make a change and say oh this is wonderful I just go into the sales tax section and I make this change and I think that's all I need to do is there any better feeling than I think that's all I need to do because we don't really believe it whatever we've been tasked with we up we are like I'm going into the dragon now the government changed the rules I may be some time and then you know oh I just have to change the ANU okay that's fun embrace that try to write code that gives you that because it's probably you do it for yourself and I've mentioned other people's code a couple times now I've told you reasons to like it it's tested it's well designed they thought of the edge cases it's faster it's already done you don't have to do it but I got to tell you something that you're probably not going to like other people's code can be beautiful hands up if you've ever written beautiful code lots of hints but you're not me all a beautiful code maybe more than one person can write beautiful code why is the canoe here just one of the few pictures is my photo credit instead of something Creative Commons II it's my picture of my canoe and this canoe is famously slightly older than James McNellis it's beautiful right it's insanely simple it has no moving parts we say that a lot metaphorically that's true literally and if you know anything about boats when you look at it you see where it can go and where it can't go and what it can do I can carry a lot of stuff you wouldn't take it down Rapids and it can float in very shallow water a C++ programmer famously asked me you made this canoe well yes with my partner we made this can did you cut the wood into the little thin strips no I did not I went to the wood store like a heathen and I just bought wood and I made a canoe and you can go to the library store like a heathen and buy a vector or find if okay and you can make a beautiful program because other people's code is not just some ugly junk that you have to put up with because it has benefits it can actually be beautiful and when you embrace that and don't think that you're the only one who can write anything good you are making better code you're getting all those other benefits too so I come into businesses these days they very often have a legacy that they are not thinking of as a gift from the past it's not like they just inherited a diamond necklace from a great aunt they didn't know they have they have legacy code I hear albatross and usually the only person who understands it is long gone and they need to do something and it's not clear what this something is and I say what the something is is we need to take your giant wooden statue that has to be behind glass because no one can touch it and turn it into something that's very smooth very polished and very strong that doesn't have a lot of scraps and scratches and pits in the surface and that you can work with from now on it's not fragile and that is heart this is not play-doh right this is hard work you have to know an awful lot to make code simpler or even to evaluate the lissa t the readability and the expressive 'ti of code whether you wrote it or whether somebody 20 years wrote it and you're picking it up now you have to know this language have to know what's changed recently or 25 years ago you have to know the libraries if you don't know that there's a function in algorithm called any of which returns true or false depending on whether any of the elements in a collection meet some predicate then you're going to write the loop to do that instead of calling any of and you have to know our idioms whether that's if P equals single equals some function that returns a pointer it's not a mistake right we're simultaneously calling the function and testing if we got an unknown pointer back you know some people come in from other languages and they don't understand that line of code at all should you take it away should you say first we'll get P and then we'll test P you have to know the idioms that everyone around you is using which is tricky if you're a team of one the kind of simplicity that is complete and elegant and readable is nothing at all like I left that out to keep it simple right we're using the same word but it's a whole different concept so we're going for this polished piece of metal simple which is hard to do so perhaps I've convinced you you know my speaker notes for this slide say wah-ha-ha-ha I'll give you some things you can do there they're actually a lot harder than they sound simple but not easy the first thing to do is to gain an appreciation for this metric of evaluating code this code looks simple this code does not that's an actual step in the process and if you begin to know what simple code looks like then you will move towards writing simple code from the get-go but you will also notice when you have somehow accidentally created that trees and doors and people and whatnot wouldn't statue behind the glass and think about how can I make this simpler how can I take a moment and shorten up our letter here do some refactoring do some renaming do some encapsulating and make it back into something that's expressive and transparent and fun and as I mentioned earlier one important way to do that is by taking away opportunities to be inconsistent this is not lego do you see this is LEGO DUPLO Interop that's a thing and how is LEGO DUPLO Interop achieved right even Lego Lego Interop how is that achieved how can you take a 4 and a 2 and use them together because of total and utter consistency right they're all consistent on the tops and on the bottoms and even between the different sizes so they will work together and if someone's just like ah for simplicity I felt like making bigger holes on this one that would not be okay so valuing consistency is a big part of what I want you to start doing one really entry level behavior names and I find names in comments here's a comment here's some code you're not beginners they say a consultant is someone who will borrow your watch to tell you what time it is here's what the consultant does right you said right there I'm going to make a total then you called it I what's wrong with you now what may be wrong with you not this person because they used arranged for but you know we used to have to type our variables like every letter of them ourselves it's true all sets of walk to school uphill both ways in the snow and I had to type my whole variable name instead of typing a couple of letters in my variable name and having the autocomplete help me out so names help here's another thing that helps this is solved problem right good news boss I solved the adding up the numbers in the vector problem Wow that's been intractable for decades functions have names that's why we say don't write raw loops it's not for perfor security is because the loop doesn't have a name it gets a comment sort the collection or we could call sort just saying but there's more to it than this when you replace a bunch of magic numbers within a numbe I'll get names I numa's if you can please when you make a constant constant X / whatever just please not a macro again you gave the number a name and now people are reading it if price is greater than approval limits stuff that happens when you need approval like it's obvious whereas if price is greater than 472 or X 3 I don't know it's a me because it's so easy to do it's amazing what it does to your code variable names single letter variable names here's the problem with single letter variable names we put a two in our terms you build a lookup table you say to yourself Amy is this I means that d2 means this d7 means that and four pages later you are looking up in your lookup table let us save an indirection okay we're all in favor of saving in directions let's eliminate that take a look here there's a comment you can all be consultants after this top couple thousand lines later the variable gets a value that's a different peeve right wall of variables at the top like literally 50 lines of variables being declared and then we'll start using them why didn't we go double D 3 equals get gross receipts because we didn't another couple thousand lines later if I don't know whatever apparently we're gonna take five percent off d3 do you still remember what d3 is in real life if you're not on a slide if you are wandering in around in a multi tens of thousands of lines file or if d3 is greater than D seven now you have to look two things up in your little mental lookup table tools do this okay I don't even have to do this the tool will do this double total revenue notice I can now drop the comment and now a thousand lines later when it says total revenue equals get gross receipts it's telling me a story I'm agreeing with it it's open it's obvious there's no lookup table I move right along later if whatever total revenue is you know two x 0.95 if total revenue is greater than old revenue I mean there's now a story that was not there even if you could remember that d3 was total revenue it didn't lay out as a story now it does and no this seems like it couldn't possibly really help it really helps and you can charge a lot of money for it I want your functions to be short oh yes 15,000 line file oh yes actual chat conversation with someone else on the team if you go to line 8750 - you see what it does there it's a real thing in Visual Studio by the way ctrl G to go to a particular line number important information in my life but I don't want your function short so you can print them who printed a page this decade very small number of hands this year pretty much the same hands we got some recalcitrant printers I don't print things anymore I used to print things when they were seven pages long when they're half a page long I don't need to print them the only reason I'm printing them is to not to scroll but I don't this isn't about printing I want your functions to be short so they can have a name you cannot give a good name to five thousand lines of code unless it's called do all the work or process everything or run the business if you can't name it maybe it isn't it okay I'm not saying you can't have and in your function names cuz sometimes you do but I'm saying if you don't have a name for it maybe it is two functions or seven and this is a good place to mention what I call emotionally short functions and I've mentioned emotionally short functions in a couple of different contexts and I have said I don't know how long standard accumulate is and every time I do that someone's in the room who wrote standard accumulate and who tells me but I don't know how long Center accumulate is I don't know how long find if is I don't care I never step into it come on do you ever step into it it's zero lines as far as we're concerned so we're not responsible that's fantastic that's the shortest possible function it's a magic function that you don't need to know about and it doesn't have to be something from the standard library I work on a project where they load stuff from disk up into a ridiculous data structure that I'm not going to describe to you and then they work in the data structure but there are certain things that happen that require you the easiest thing to do is to just flush that data structure and reload from disk because it's gonna be calculated differently and this function is called update database and there are these places in the code where people and it's almost like an invocation wait before I do this we'll just call update database that may or may not be right but here's the point I've never stepped in to update database it was literally written in the last century and I don't know how it works I know what it does I've never stepped through it as far as I'm concerned it is zero lines long it might really be 10,000 lines long it's a good chance that it is but it hasn't changed it doesn't need to be maintained it just is if you have stuff like that in your universe and I bet you do those are also short functions and leave them alone don't get in there and simplify them they're already simple by being invisible that's that's as simple as you can get okay so don't assume that I want everything 10 lines long only the things that we all have to read and step through and understand and modify and maintain and the new stuff please do not write a 10,000 line function this week this is real code are you having fun no sir pleasant is this Pleasant I don't think this is pleasant is it unsurprising oh no it is not unsurprising it is trying if you can't tell to parse a command line okay there's something there called LP command line Hungarian notation other people's code string stream now we'll parse it out you know what this does right I'm taking that command line and I am getting driver name and pipe name out of it I threw Hungarian under the water under the bus and I also switched to strings I say if the driver name is still blank or the pipe name is still Mike that's when we do not have a happy path otherwise I do some decorating to the pipe name which if you haven't had to do named pipes on windows pay no attention to that then I returned to these aren't quite identical code this version writes a space into the middle of the input string sorry R it's a null into the middle of the input string so that it can use stir copy which will stop when it gets to the null and then it puts the space back which means you can't give it a constant string because you're changing it which means it's very hard to mock and test that's how I came to change this code this is not simple code you puzzle your weight why are you suddenly writing a null into the middle of the string well it's a hack so that you can use copy this fails on a lot of a lot of points this code is simpler it is shorter but that's really not the deal right requires you to know what a string stream is also requires you to deal with the person in the coffee-room who gets on the streams are slow hobbyhorse I am parsing two strings out of a command line for a server that runs for weeks remember don't choose simplicity over performance if that's really the issue it's more simple things you can do long long lists of parameters 10 parameters 20 parameters especially when they're all the same type that's fun isn't it here I really feel it's about abstraction if this thing takes seven bowls make a struct with seven bulls in it that have names and pass an instance of that struct and you can set the struct up before the call everybody can see what's happening so you're setting verbose to true you're setting Auto print to false and so on rather than oh look they called false false false true but they should have called false false false false that's an easy bug to spot it's all the more so if your abstraction actually has meaning the number of rectangles oriented functions that take four integers that I have seen is well about a hundred more than anyone should be asked to see and what do the integers mean right are they x1 y1 x2 y2 or are they x1 y1 width height or height width or whatever they're lots of possible X x1 x2 y1 y2 like you do not know right and you have to pray for good parameter names if there are any at all or go and read the code those are both awful but if I change this function now so that it takes a rectangle and that's I know it's kicking the can down the road but someone's defined rectangle for me or so that it takes two points now this function is easier to call almost impossible to call wrong for the rest of time three strings and a float what is that in your world is that a person is that some business object like an order or an invoice or a policy make that and I literally advocate if you're maintaining old code if you're writing it you should be writing it right from you shouldn't be what are you doing typing bull bull bull bull bull stop it these things tend to grow the function doesn't take any parameters then it gets one bull and gets another one 20 years is a long time it gets seven rules the first three aren't used anymore but when you go into this code for the first time in 15 years and you gain the understanding say of what these four integers are I actually advocate for recording that understanding immediately by refactoring and just right then and there as soon as you get oh it's two points make it be two points because you have put in ninety ninety five percent of the effort by figuring out it was two points the actual changing the signature we have tools right the actual changing the signature is almost nothing almost as quick as typing the comment and then it's done forever sometimes the reason you have so many parameters is because like the function that couldn't come up with a good name it isn't really one function the top third of the function uses three of the parameters the bottom third uses the other you know like it's really independent of each other and sometimes I will advocate for breaking it up and I don't mean that you have the big 10 per M function calling the three smaller functions I mean you actually have the three smaller functions and the call site calls all three of them now I know if there are multiple call sites and they all have to remember the phone to call all three maybe I'm setting you up to be inconsistent someone could drop one of the three calls hey these rules contradict themselves judgment and experience still count for something there are times when you do it this way there are times when you do it that way I didn't say this was going to be easy the other way to get rid of a ton of parameters I know all the cool kids are all free functions these days but member functions and encapsulation do serve a purpose if this is taking especially multiple properties of some individual object maybe it should be a member function of that object and this may be a multi-step thing it may start by taking you know six strings and then you may decide to do some encapsulation elsewhere and so then when you get to this function it's like a dot first name dot last name eat a department name and you're like wait if this was a member function of the e object we would have a lot less junk to pass back and forth it doesn't always happen but look for it be open to it this is arrow code and I know some of you are going to try to read it and I can't make it smaller so please stop trying to read it I will read it to you okay it's called calculate and it has three tests in it it says is X less than the limit okay good we can keep going down at the bottom there's an else where we set an error code and return bull turn false because it was bad assuming X was less than the limit we say well is y positive is it greater than or equal to zero nonnegative good we'll keep going are we shipping excellent and here's where the actual magic happens you notice in order to fit this on the screen I couldn't have any magic but there's magic and we return true and then everything else is else's this code is not simple imagine that you are a junior developer you are new to the project and we have a fourth rule and it is your job to put the fourth rule into this code I'm pretty sure you're going to put your else in the wrong place on your first try it's also hard to read it's hard to understand you can very clearly see that we only do the magic if X is under the limit if Y is non-negative and if we are shipping but the rest of it can be a little hard to follow this is the exact same logic I did not change the signature I always get someone is like well you shouldn't return bool what about expected bla bla bla in the most simple refactorings you don't you're not changing the signature so the behavior is unchanged we still return a bool we still set this member variable error but now you notice the font got bigger you notice there's a lot less lines of code on the screen and the magic is here at the margin rather than before way over to the side and that's important finding the good stuff easily but also if you were the person to add the fourth test right nothing to that put it anywhere because that's part of the promise like well I want to test after X but before why because optimization and you can do that here anywhere you want the errors are exactly with the conditions the conditions by the way are flipped right so I was before I was like if X is less than the limit now I'm saying the badness if X is greater than or equal to the limit so you do have to do that and it is a possible bug so tests will help you but now your code is more readable and it's telling a story you're clearly checking all your preconditions and if we're still here now we're gonna do it and that's why it got shorter yeah I don't need an elf's when you return the if and that's the only thing that took away lines of code I made the font bigger is not having to have else's but it's also what eliminated all that sideways scrolling I'm a big fan of XS constant as an exploration technique so I don't mean conness I really I consider that to be the price of admission okay if your code is not constant correct make your code cost correct but this is going beyond that so you just literally you get constant your clipboard buffer and you go punk punk punk punk punk all the local variables all the parameters the ends of all the member functions everything and then you build no thinking just build and of course it's gonna fail right some of those things are not cost and you're like that's fine I'll take those off but some will stay especially in a long calculation that came from a paper process or a spreadsheet process there's all these like intermediate things so they say here's the total revenue and there's a big long expression and here's the total population there's another big long expression and then they're like so the ratio is and they divide them and they never change those variables again they're got names to lead someone through the calculation so marking them Const like it's not preventing a bug or enabling optimization or all the reasons we tell you to Const but when I come into this code 15 years from now I'm gonna say oh you have ten variables but you don't really only two of them continue to change after their first value and so as I read through the next thousand lines I only have to have my little alert table keeping track of just those two the others are just numbers with names they're not constants in the sense of an a new more a compiled time expression but they don't change once they get a value I have less to keep track of my cognitive burden goes down and it's not a hard thing to do because I don't think just paste paste paste paste paste build and then delete delete delete till the compiler is happy it's like you're back in first year again this hurts hard when you have out params and in out prints right in fact some people may have been mumbling that to themselves like reasonable point until you have an out print you know what I'm going to say yeah don't have a no parameter what I'm going to say it I've considered a feature that this makes it painful to have out params because you slam the constant ons everything and then suddenly it's not concentrated and all you're doing is passing that's what that's also why I say don't think okay because you see it being passed to a function don't stop and figure out if the function changes that the compiler will tell you this is a good opportunity to discover in out params and out params and to perhaps replace them if you're if you're able to change the signature of the function that's being called so that it returns something useful and you can return some encapsulation of your own devising a struct or a class you can return stood optional and yes you can even return a tuple here's how I tend to return two bowls first the function returns nothing at all just does something then it returns an int then it needs to return two intz then it needs to return to instant a string so I use a tuple and eventually I give up and I encapsulate something sensible that if you get all of that all at once you'll probably just go straight to the struct and again maybe this should be a member function of that in out thing so if you have an update employee info that takes an employee by reference what why isn't that the employees update info member function which can be non constant not objecting to non constant functions so you know a lot of times out params are kind of a sign that maybe we're not as encapsulated as we should be you're all here so you already want to keep up with what's happening in our world you need to spread the word to everyone that there is no substitute for keeping up I did a talk here last year about the core guidelines one of them is like don't use Const cast I'll turn it to cons cast the mutable keyword a bunch of people afterwards on Twitter that mutable thing looks kind of interesting I should try that I wonder when that came into the language it was a difficult question to ask it turns out I had a 24 year old at the time and mutable is older than him okay not a new concept sorry idea if you're gonna use loops can you use arranged for I know your fingers do the other four like without you thinking right you go loop and it comes out but can you use arranged for can you reprogram your fingers I still meet private constructors and there's some times correct right you got some kind of factory thing singleton boo hiss where there is actually a friend or a member function that's calling the constructor that constructor should be private but when I go looking and I can't find any code that calls the constructor I'm puzzled why is why did they write this constructor then you're oh of course they're suppressing this constructor right but we have delete for that when you don't say delete when you make it private I go looking to see who calls it when you say delete mystery over so it's a simple little change but it's communicating to me compiler probably couldn't care less which of the two you do but I would prefer you make them deleted non-static member initializers not particularly new yet still not being used I don't know why they are easier and faster and you can't forget when you add another constructor and you probably won't forget when you add another member variable so for default values of member variables used on static memory initializers can you you'd be grateful that you have them oops the library I didn't say keep up with the language I said keep up with the library stood optional great stood takes did is great things are happening people are writing things so that you don't have to if you think you should write a simple wrapper that please stop and use the library if it's not in the library and you and you know it's also not on its way and you can't get it in some sort of experimental version then maybe you will but honestly anything you can think of in 15 seconds is probably not that unique and original so the library keeps changing keep knowing that the library is changing when I was very young I've been paid to program since 1979 and I didn't learn to program on that in that job I already knew I had a great uncle who I didn't see very often is the way of great uncles and he said oh look at you you've grown up you're an adult what are you doing I'm like oh I'm a programmer oh you were such a creative little girl what I think he felt it was like being maybe an operator you know that was mounting tapes and putting card decks into card readers and things huh as creative as as possible to be because I'd make worlds out of the skin of my fingertips right and we all do and I think we all have learned that programming is a creative activity now I want to convince you that programming is a social activity it's asynchronous but you are communicating you are making code and leaving behind code and it speaks it's not the immediacy of yelling at someone in slack but it is communication and I'd like you to consider a constant felon from other people who quoted to me Rico Mariani called the pit of success you want your people to fall into the pit of success what I mean by that what he means by that it's a wonderful analogy the most obvious thing the no-brainer choice the zero effort behavior they win for whatever definition of win you want so if you have people working for you and you would like them all to start coming to conferences you make it so they all go to conferences and they have to go to a lot of trouble not to go to conferences if you have people working for you and you would like them to show leadership abilities and lead things and make decisions you set things up so that's what they're doing and they have to go to some trouble not to when you leave code behind you can leave behind a pit of success for the person after you to fall into you set up defaults and if they follow right along and don't think the goodness will happen all right that's what you're setting up and not just next chronologically it can also be next sitting at the next chair think about what you're saying to people with what you write I've railed a couple times about being inconsistent about setting up opportunities to be inconsistent when you leave that behind you're not leaving behind a pity yes they have to climb like a mountain of success by changing it in all the places it needs to be changed if there's only one thing they can't be inconsistent when they do the obvious thing which has changed the single function they're done they win they succeed it you set that up for them same with non-static remember initializers right when they add another constructor they're not going to add an inconsistent default value all of these things set them up to succeed if you've got good encapsulation and you've put your clean up in the destructor they don't have to remember to clean up when someone later adds a throw that didn't use to be there the bug of like oh yeah so I need to clean up in the catch is never going to happen you set that up who's played chase the Const these are not happy hands you know sometimes you ask people questions they're like yeah I do that I love that and that was not what those hands said if you start Const correct nobody will ever have to play chase the Const and swear at you but also they'll probably follow along right when they see member variable member functions marked cost when they write a new class they're going to stop and think about whether they should mark their member functions cost when they see parameters being taken by Const ref they're going to almost think that that's the boilerplate that they should be following so you're setting them up to be right you write good names you write short functions that's what we do here you write a to be 7 X 3 they'll be right behind you with a 3 and B 8 and X 4 now I do sometimes get pushed back because I'm telling you how to write telling you how to write for yourself I'm telling you how to write for the people after you telling you to set things up like they were babies who need to be led and people say we don't need guidelines we don't need advice we can read 50 lines of code we're big boys and girls so I want to show you this picture I bet you think this is a picture of a river it's not I mean the rivers in the picture that's not why I took it two blocks of lots pictures of this river I took a picture of this guide rail this guardrail astonished me by existing you see the day before I took this picture I took this picture it's a volcano down where you can't see is lava every 15 or 20 seconds it starts to make a noise and the noise gets louder and louder and it reeks you wouldn't believe how it reeks and then lava comes out there's blobs they look like rocks between me and the man I don't know there drops with lava in fact Shirley left it took this picture a lady in flip-flops came by and told me that I needed to move a little further up the mountain because some lava had landed where I was standing two weeks before and she wouldn't want me to hit me hit by lava there's a very nice of her there's no fence right you stand as close to the lava as you feel like and if mr. raincoat wanted to jump over the edge none of us could have stopped him but he's a big adult and he didn't jump over the edge nobody jumped over you you see people gone higher so after this experience when I was walking up this river I'm like this is the only guardrail in the entire country I'm taking a picture of it if you look really closely there's a woman in the river okay this doesn't keep you out of the river it keeps you from falling into the river I would have thought maybe keeping you from falling into the volcano would have been higher up the priority list but whatever it keeps you from falling into the river later you end up in the river anyway if you want to walk in the river walk in the river Johnston on the edge of the volcano stand on the edge of the volcano but I kind of liked having the fence because it kept me from falling accidentally right that's the deal when you're saying follow this rule follow that rule have short functions give good names this isn't a wall this isn't a 10-foot higher barbed wire thing it's just some wood it just keeps me from falling accidentally and I welcomed it I wanted it I took a picture of it and when I'm in some of your code bases I'm begging for something I can hold on to you like a little wooden rickety fence so when you go in and you refactor and you encapsulate you're not trying to lock people out of things that aren't good you're just trying to make it the natural easy thing to do things that are good just a little bit of a guide in which spirit I'd like to plead with you not to do this I will confess that I don't really know what this does I found it on the Internet but you can tell an architect made it it says in an abstract and concrete and there's dotted lines and inheritance it's probably a lot of work whatever it is is it simple can you see what it does you cannot I found a blog post about abusing design patterns and my slides are going to be available and there's a link in the slides and I took it and I converted it all to C++ and it works okay here's what it does first you you need a factory pointer which of course you call about getting factory after calling get instance on the factory maker and then you can create a subject and then you can create an observer and attach the observer to the subject then you can set up a command because the factory will also create you a command and then you can finally execute the command whereupon the program prints out hello world and exits now what's wrong with this code is there's only one kind of factory not passing any parameters to get factory there's only one kind of subject there's only one kind of observer and there's only one command all this flexibility not being used and we can laugh but we have all lived this we have all been in systems that could work for four different database vendors two of whom are out of business and no one's ever ever changed database vendors I worked for a while with a client that had written something using all Microsoft stuff so it's dotnet sequel server everything was done that is you name it and their sales people got some pushback and said we would never buy this unless the supported Oracle so the developers had to go back and change every spec of that program so that I worked with Oracle or sequel spoiler that deal didn't close anyway and nobody ever wanted Oracle again ever and that's not unusual that's our life if you write flexibility before you need it you maintain that flexibility for the rest of time and nobody really knows what anything does you can't tell that this prints hello world for what if you need it you need it you get a benefit but if you don't need it you don't get the benefit you just saw this cool diagram on the internet and wanted to be an architect please don't but that leads me to a paradox because I told you that abstraction was good told you that short functions were good splitting things up was good giving things names was good but then I'm like oh this has too many layers of indirection well again experience and judgment count this isn't a mechanical process that will do all of your thinking for you and the paradox is that every single thing that you can do to make code simpler that same behavior can make the code more complicated if you want to run a loop from zero to number of items in the collection or if you want to say if outstanding blahblah is greater than zero should zero perhaps be in some sort of Anna Neumann sex / Zed ero so that we all know it's zero not have a magic number like that's not making our code simpler it was great when it was 472 it's not so great at zero so every single thing that can make code simpler can also make it more complicated and I cannot give you the simple rules for writing simple code all the rules will say usually maybe a lot not many unless you have a good reason and that's not a flaw in C++ it's not a flaw in software development it's a law of the universe have you taught someone to drive how fast should you go well the speed limit you just ran into someone going less than the speed limit oh the speed limit or whatever the person in front of you is going whichever is less that's good a dog right out on the road okay the speed limit speed of the person in front of you whichever is less or slow down if you see obstacles okay we're going the speed limit and it's a very sharp corner and the road went that way but you did not okay you also sometimes have to slow down for corners I haven't done the weather yet right and that's just the first question have you played what Lane should you be in with a nervous driver I'm a new grandparent very proud of being a grandparent but if my daughter would say to me the baby is crying what is my simple answer for what to do about that huh questions can be simple but they don't have simple answers it's true about what Lane you should be in it's true about the crying baby the answer book to the crying baby by the way step 0 anyway is pick them up okay it's after that that it diverges should you use exceptions how long should a function be is this a good variable name tell me how I would know if a variable name was good or not there's simple questions they don't have simple answers they can't have simple answers it's not like well if we keep working at this we will be able to prove that no functions should be more than 43 lines long we will never have that rule but if you have the value if you want your code to be expressive transparent understandable reassuring then you will answer not the general question how long should a function be but the specific question how long should this function be is answerable so let's do something harder because giving things good names and keeping things short and all of that you get some judgment and you get judgment from using bad judgment cuz that's what gives you experience I hope you write like that from the get-go but you can bring it in that's not the whole thing you want big gains you change your team here's an example someone gave me obviously written by a very smart person because it's using a special integer type so they must be very clever unfortunately getsize returns a different special integer type that's 16 bits long so some people when they see this say Wow C++ it's so complicated you have all these different integer types I have to keep track of which ones are 8 bits and which ones are 16 bits so which ones are signed and which ones are unsigned I want some Plato now I don't want all this complexity and I'm like that's not the problem the problem in this code was that I and getsize have nothing to do with each other right they have no relationship getsize is a free function I don't know what it looks at to figure out the sizes of things and I is just a local variable if we had a real collection we could iterate over the collection in a variety of ways and we wouldn't need to memorize integer types so when you meet a little complexity sometimes you're tempted to haul a bunch more complexity out especially because you're smart and you're creating that wooden thing with the sculptures and the doors and then has to be behind glass you step back and say actually what's really going on is a different thing those two are different because they're unrelated fixing them to be the same but it's still coincidentally the same that's not really fixing it to really fix it your code reflects the relationship they truly have well that comes up to a real hard thing you can learn to recognize things arranged for I'm touching every element in the collection I should use arranged for Shaun's famous line from five years ago that I love to quote this is obviously a rotate to pages of code that we're not obviously anything but you can learn and you can recognize things from the standard library you can recognize arranged for you can recognize all kinds of things and plunk them in instead you know standard library has a stack do not need you to write a stack do not need you to write a jsonparser this weekend come on hands up yeah got some confessions or a logger write or something to go get over HTTP these are solved problems my friends but then can we go too far who's heard of and immediately initialized no immediately invoked initializing lambda expression yeah you see this is a crowd third a third of you have heard which is a ton right if I went anywhere else I would not get one third of you having heard of it it's a way cool thing though right you have some variable you'd like it to be confidential izing is super applicated so you can initialize it by calling a function that's obvious but that refactoring is hard you have to figure out what the parameters are to the function if you just slam a lambda in there with a reference capture you can just you literally just put the braces and stuff around the code that's already there and then you stick a pair of parentheses out the end of the lambda to invoke it and it's magic and the variable can be Const and people who don't see those parentheses do not know what you did and and I love this idiom for this reason it's right on the border it's not arranged for we all know what arranged for us but a lot of people don't necessarily know what this is so if you use it are you making your code simpler or are you surprising people which I said not to do because that's totally a surprise like wait it's being invoked oh cool but Wow can I have my last half-hour back you need to know where the things you want to use exist it's not simple to surprise people so it's not enough that you know it I want you to replace your complicated things not just with idioms but with familiar idioms right that express your intent with well-known library classes that others will recognize hopefully everyone's going to recognize all of algorithm and all of numeric and if they don't we have CPP reference but there are other things that are maybe less well-known you want to introduce appropriate abstractions in your code so that people say oh that's a rectangle I know what a rectangle is that's a purchase order cool right but not something that hides what's going on because while you're doing all this obviously we're not omitting we're not going back to Plato we're not like oh we only do forward to keep it simple we all are needed capabilities are still there the core information the guts of what this thing does is on display that's the point is expressive and transparent so you don't hide everything behind a wall of injectors and adapters and factories and whatnots and you don't prevent future changes and I really want to talk about that as its own thing everyone says that Einstein says that things should be as simple as possible but no simpler and then I learned from Phil Nash that he actually said something more complicated and someone else paraphrased it down to this which could not be more perfect your simplicity needs to live in this larger context which is time' where it's simpler now to just type 472 isn't it then to go set up some kind of constants or some in neumes or something but later it will be much simpler to have the constant so what are you gonna do you're gonna do the right thing when you get down to the end of a long chain of function calls and realize you need something at the top of the chain nose but which is not in the parameters don't you just say like I could have a global right and you might even tell yourself well it's not global mutable state today it's not it will be that's the problem with Global's the right thing to do you already know it's not always the faster thing to do it's not always the easier thing to do I'm asking you to take the time to write the shorter letter the really the hardest of all you have crafted some gorgeous code I was once part of a team that took a main loop the big engine of the whole app it was pages and pages long it had go twos had multiple caches it was almost impossible to see what it did like you literally needed to print it and take a highlighter to it and we made it fit on a page and it read like English you know while not canceled that kind of thing it was gorgeous we were so pleased with ourselves and someone said I thought this was a hard problem is that is that what you got that was tough and I have to tell you when you make something look easy and obvious and transparent and expressive someone can say why did that take you a week and that's hard I thought you were an architect right but you don't have a impenetrable UML diagram for me you have to know you're doing it right and you have to know you're not leaving anything out you have to know you've achieved elegant valuable beautiful simplicity but you worried you're nervous is this simple didn't think it through I don't know it looks like simple didn't think it through I'm pretty sure I made simple brilliant I was totally going for simple brilliant but now I have to stand up in front of everyone and say this is simple brilliance and someone's gonna say is that all you got you know your language in your library but are the people around you going to say that's not simple at all I have no idea what any of that is you just architected it up with your stood optional and your no accept but here's another one people ask me if I write code that anyone can read anyone can maintain what happens to my job oh you're gonna be on a lot of projects you're not going anywhere you know you're gonna save the company a ton of money because juniors can maintain your beautiful simple wonderful code and juniors will be led into the right ways by using your code as an example you're not going anywhere except to this other project that really needs you right you will have job security and if there's not enough projects where you are anyone else will be happy to have you please don't ever write gross code so they can't fire you write code that stands up for you because you are leaving behind communications to the future and does that reflect you does that show who you are does that show what you know that's what I want you to do how far have you come from a beginner so what do you need to do you need to learn you need to learn our language you need to learn the library you need to learn what other people know you need to know what's faster you need to know how to measure what's faster you need to know what your optimizers do you need to know so much you need to read other people's code because that's how you find out what kind of code is readable you need to care to care about yourself tomorrow don't just slam it in to get it done so you can go home care about yourself tomorrow and yes the mythical future maintainer as well you need to test things is this faster than that do all the people in my department know what an immediately invoked initializing lambda is don't just guess test it's easy for me I asked for a show of hands somewhat harder for you but do it and you need to communicate you need to communicate with your code but you also need to communicate about your code at code review time why did I do it this way or to someone else why did you do it that way did you consider this other way do you think it would be more expressive if it could be as simple as does this loop touch everything in the collection perhaps we could consider arranged for and that kind of communication brings everyone's code onto this simple brilliant side of the line and when you are consistently doing that for yourself and for everyone around you you have very definitely not a beginner thank you [Applause]
Info
Channel: Coding Tech
Views: 32,079
Rating: undefined out of 5
Keywords: software development, programming, c++, coding, simple code
Id: W2Thd9nKqmU
Channel Id: undefined
Length: 79min 6sec (4746 seconds)
Published: Thu Sep 27 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.