Declarative thinking, declarative practice - Kevlin Henney - Meeting C++ 2017

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so I oughta talk about declarative thinking declarative practice my name's Kevin Henny which is sufficiently internet unique it's quite easy to find quite easy to get wrong as well let me think things that are relevant I've been heavily into patents software architecture all this kind of stuff very much into the code edited this book a few years back but it seems these days I seem to be better known and this makes sense of the slide that you ents put up yesterday yesterday morning I seem to be better known as a brand for failure which I'm not entirely sure how I feel about I was asked this the other week how does it feel to be identified with software failure because I from many years ago I I started collecting photos and screenshots of software and system failures in public places and thanks to the joy of Twitter people send me more and I retweet them and then last year somebody actually turned me into a word I saw a Kevin Harry screen and I've noticed that oh yeah that's a Kevin Harry so so yeah this seems to be happening but it got to a really good point about a year ago there was a conference agile in the city in in Bristol where I live in the UK and the conference organizer came up to me John Clapham said Kevin there's a Kevin any screen downstairs I need to take a photograph of you standing in front of it so that you can so I can tweet it and then you can retweet it and then this year because the conference was last week we did this again so we've got this kind of Heflin section thing going now I will talk a little bit later about this part of my motivation this is is testing but the main goal of my talk here is not testing all of that will be used as an example later it is about the idea that we often focus on language features and many years ago I was a columnist for C++ report and then C C++ users Journal and so on and a number of other magazines magazines on a great paper who remembers that so the thing is that the column that I had in C++ report and cuj was entitled from mechanism to method because at that point my IDE started noticing people were always myself included focusing on language features focusing on cool bits of technical stuff and that's great up to a point but you end up with people wandering around going hey I've got a language feature where do I use it which is kind of the wrong question okay it's that classic you know I've got a hammer question you know whose thumb can I hit that is always the question people are asking they just don't know it or this screw can I use this hammer on it no it's the wrong way around what are you trying to build I'm trying to build IKEA furniture okay if you're trying to build IKEA furniture a hammer is probably the wrong thing let's actually solve the real problem here so I was focused on this idea of moving from the idea of the mechanism out to the method why are we doing this what is it you're trying to actually do and in many cases it's ultimately a quest that is familiar to many people in life it's a quest for meaning what are we what does this mean in fact that is actually the biggest challenge when you come to a code base what does this mean okay it's like yeah I can tell when somebody helpfully explains to you that this argument is past of that you can get yeah yeah I can see that but what does it mean oh it's calling this yes I can see that but what does it mean that's that's the greatest challenge that we have in a code base and a code base should be a system of meaning so what I'm interested here is this idea of being able to be more intentional to communicate your intention and there's a lot of guidelines about naming and so on I'm not going to touch mostly I'm not going to touch on those I will touch on those briefly a little bit later but one side of that very large story is this idea of a declarative approach and declarative approaches are contrasted with imperative approaches an imperative approach is all about state change it's about modifying stuff a subset of declarative approaches is functional programming they're not directly equivalent one is the superset of the other and so declarative declarative programming contains functional programming just as imperative programming contains procedural programming but let's not get distracted by the idea that it's to do with declarations that's not really what it is there are perfectly good sessions on type systems and all the rest of it and type systems do inform or can inform a declarative approach but they are not necessary and that's not the whole story so how long have we been obsessed with this idea of declarative approaches well for a very very very long time and I love this quote from Tim berners-lee Computer Science in the 1960s to 80s spent a lot of effort making languages which are as powerful as possible he wrote this in the early 90s it's still true we are obsessed with making things more powerful much as you know I love I really like languages that give me more power I'm always fat but there's a little part of me that goes now you don't want this yeah or rather there's a bit of me that says you don't need this my wife is always emphasizing to me that there is a difference between want and need she's been working at this for nearly 30 years I think I may have just understood but I'm not sure I want power raw power give me the Iron Throne of C++ yeah get me close the metal yeah but at the same time I like a lot of other languages and sometimes they don't give you that power and they're just fine in fact some of them are a massively minimal nowadays we have to appreciate the reasons for picking not the most powerful solution but the least powerful the reason for this is the less powerful language the more you can do with the data share stored in our language if you can write it in a simple declarative form anyone can write a program and analyze it in many ways the problem that we have is the subtlety of state change and the subtlety of do this do that and it's all about the do this and do that and you change one small assumption one small tweak and suddenly it's gone it's a lot for a human to understand that can also be quite surprising in terms of its results it's very brittle requires a great deal of intellectual effort in the worst cases clearly declarative programming is not a new idea it's also not an obscure idea at all so as the sync of all human knowledge Wikipedia observes the make file language is similar to declarative programming this class of language in which necessary end conditions are described but the order in which actions are to be taken is not important as something sometimes confusing to programs used to imperative programming actually there's a bit more to declarative programming than is suggested there and it's not always about the end conditions sometimes what you're doing is you're describing relationships and the minute you are able to even so much as declare an array the world opens up and in these terms but it's about organizing relationships so what we're doing here is moving a little bit beyond Niklaus births book on structured programming from the early 1970s I'm sure he must have really frustrated the publishers in algorithms plus data structures equals programs this is a very unconventional title I mean these days we're expecting emoji to appear in titles but this is like the early 70s and is his his publishers master's got what were you doing what are these symbols doing in the title no sir so um anyway I'm gonna simplify it I'm gonna get rid of one there you go what we're looking at here is really the idea that data structures are programs okay how much can i express through that and the organizational data I'm gonna pick an example adapted from 97 things every programmer should know there's a piece by book half Naugle it's entitled the type of there's two things about this article that are brilliant one is the example he uses and two is is the title and the advice put the mouse down a step away from the keyboard this is great there's this whole notion that sometimes your problem-solving and you are busy problem solving and you are problem solving more and you're doing the same thing but now harder and with more effort and you're getting the same problem just more of it you're getting more frustrated there's this whole idea that you cannot solve a problem at the level at which it was found you need to do something different so I normally offer this as a piece of advice but I also offer other pieces of advice the idea is if you are stuck in a situation then do the opposite if you are sitting down stand up okay if you've been drinking lots of coffee you've been mainlining caffeine now's a good time for a herbal tea if you're not a coffee drinker now is a great time for a coffee yeah be do something different if you've been listening to music stop if you hadn't been star in other words do something that changes the way that you are thinking or being now Burke's example was taking some Java and I thought actually I'm gonna rewrite the premise of his example he didn't show the whole example I thought okay using using the style that he has done I'm gonna rewrite the example that he was dealing with when he decided to put the mouse down and step away from the keyboard the example that he was dealing with I thought I'd have a go rewriting in C++ people paid to write this kind of stuff so what I love about this is that it turns out a discovery I made at a client site a few years ago it turns out that it's incredibly easy to write bad code yeah now I mean that in the sense that if you ask somebody's write bad code they struggle but if you but it turns out bad code is not arbitrary all code code that we consider bad code that we consider good comes from a system and it turns out that you only have to say I want you to do it in this style I want you to do it in these ways and before you and I did it was with this client I said here's three assumptions and I wasn't really sure how it's going to come out but I was so surprised when the three assumptions that I made and I said now what we're going to do is we're going to do a network connection using your style and suddenly I recreated their architecture it was coming out before me code that we consider pause not arbitrary it's systematic so I followed the style Burke had in his article and here magnificently we are trying to parse a time string a 12-hour time string that has the meridiem of a.m. or p.m. we could simplify this and turn to the one true clock 24-hour time but actually that only gets rid of a couple of lines so this classifies whether or not a string is formatted to give a valid time it's a small matter it's not it's not the biggest code you're ever going to find it's not probably not the worst I wish it was the worst but in its own little way it's its own masterpiece so Burke kind of put the mouse down stepped away from the keyboard came back let's reframe it we go now sometimes people joke aha regular expressions I had a problem I solved it with regular expressions now I have two problems or I have star problems now funny as that is the thing is I can explain this to my kids and I want to point out that's a tweenager in a teenager they have a fixed budget of attention okay they're like you know it's like you turn the clock and the sand start running through okay and to explain this to suck this this is the thing about declarative approaches it turns out the declarative approaches are very easy to explain they are easily talked through you know this shows you know a couple of things but perhaps not the right things but to explain this and walk through this is just insane I can explain this to somebody who is relatively non-technical and has a short attention span very very easily so one of the goals here in terms of trying to take this is not simply commoditizing and wrapping code up it's actually changing the way of thinking finding a model of description that changes the signal-to-noise ratio okay and that's what we find in legacy code and we get a lot of irrelevant data and a lot of noise in this code so can we do this kind of can we do other things in C++ that are of a declarative nature well pretty much most functional programming falls into this and the source of all functional wisdom is the if you believe them is Haskell of course they say that but there's actually quite a good definition many programming languages support programming both functionally imperative styles so I've done a number of talks on functional programming in C++ and in other languages that I do not have a functional core and do not have a functional history each one feels slightly different they have different strengths different weaknesses different areas of support both functional imperative star but the syntax and facilities of a language are typically optimized for only one of these styles and social factors like coding conventions and libraries often force the programmer towards one of those stars and that's quite an important consideration it's almost irrelevant what a language supports it's what the culture supports is what the people around it are prepared to support it is quite interesting having seen languages evolve over many years seeing which communities grasp the new features and actually change what they consider to be their core style and which do not I was actually fascinated in the 1990s when somebody told me that COBOL was going to get objects it's just like yeah nobody will notice the culture will not care that is not a culture there's actually you know that's what a culture is asking for revolution and evolution and then that that's not the culture that's going to embrace it the problem is that when we have languages with this kind of spread we have the problem of legacy and so on so let's take something that is brutally imperative I almost use a goat but I dunno I couldn't bring myself to do it but I've got I've got a fairly crappy wild loop here so a problem that I've used for a number of years very simple toy problem let's let's let's generate let's sort of show the degree of imperative thinking or its effect classical imperative thinking going on here now I've commoditized I've switched out all the namespaces and everything you'll see why later in this particular example but what I've got here is the mechanics what have I got I've got an accumulation of state I've got squares this is where I'm going to hold my the squares of the first hundred numbers okay so one through a hundred inclusive or once or 101 exclusive I've got to set up a counter variable okay and then I am going to have a condition condition has no side effects glorious then I'm going to push to the back of squares then I'm going to change some state so I've got two state changes in the loop I've had to establish two things now with a lot of experience which everybody in this room has you kind of see what's going on but I'm just kind of looking at the number of lines there and what's really going on you get so used to seeing you don't realize how broken this kind of thinking is you see Kevin's obviously missed the for loop no Kevin is not mister for loop what does the for loop do for loop it's one of those crappy statements okay I mean I've some people think it's a great innovation no it's not an innovation is the kind of is for each loop okay this prevented language is evolving for years you know is see put this in and it was just like everybody said oh this is great no it isn't I mean it jumped from language like a bad like bad disease popping from gene pool to gene pool preventing people from saying you know why do we actually loop yeah just putting the mechanics on one line I mean it's kind of nice it brings things together yes some things are easier to see but really that's just a rearrangement of that okay yeah and it has some modest effect and that's great but it's exactly as procedural and imperative as the previous example okay so I'm going to borrow from Eric neighbors Rangers proposal this is why and this is why I'm you doing all the using Danes bases we have to give up this namespace obsession because otherwise you just end up with code all I see when I look at so much C++ there are reasons we do some things but such orthodoxy I see colons everywhere there's just dots in front of my eyes okay and when you start digging down into these namespaces it's just oh this is insane so I wanted to present this in a way that made it look fare against other languages so okay what I'm gonna do is I'm just gonna oh I've now got what I've now done is I've actually effectively reduced the amount of state that either program or control the for loop has become a properly declarative construct in other words yeah there's stuff going on we recognize the state change but it's not our problem I is bound I is a parameter of the loop if you reason about it like that this makes a lot more sense there is the range it is a player it's not the mechanics it's not a question of oh okay you start here and I'm going to initialize something here and then I'm going to set and I'm going to manually write the condition that is all taken away from you we can do better than this the next thing is we're going to take that and now what we've got is a sensible relationship what we've actually done here is we said okay I'm gonna take the integers from 1 to 101 exclusive and I'm gonna transform them and square them ok so that actually looks like what our goal is which is to produce the squares the first hundred numbers the previous ones there is no visible state change here that we care about of course the state change going on but that's just mechanics that's bookkeeping it's not your job to do bookkeeping ok it's not your job to write loops has anybody do you think you've written all the loops you ever need I think I have I don't think there's a single loop that is a I have to write in my life that will be different from any of the ones I've written before to the point you can monetize them in your brain and we often talk about writing no raw loops but let's really actually look at this from another point of view part of the reason for that and also other cases is the amount of state that we end up just managing and creates noise it is more intentional in fact it is also more intentional yeah English is great because these two words mean something different okay now sometimes people say you know English spelling it's a mess it's not logical I don't know no they're wrong there are about six or seven different kinds of logic in English spelling and they are all simultaneous okay that's the problem it's not the lacs logic it has far too many systems of logic and this kind of intentional is slightly different what we're talking about here is a way of characterizing a set of things or indeed we can apply it to a sequence allow sense of expression that determines its reference so it's determination of a reference rather than using an extension so intention of prime numbers may be having non trivial integral factors whereas it's extension would be two three five seven keep on going okay so an extensional approach is to make something explicit in the intentional approach is to describe the rule that characterizes these and what we find is that if I wanted to do a set of the squares of the first hundred numbers and I sort of rendered it using mathematical notation the set builder notation then this comes out as being surprisingly familiar it turns out that we've seen this before in code as well and that's the basis of a list comprehension now unfortunately C++ doesn't quite get there but it does a pretty good job so this idea of the set builder or set intention list comprehensions the way most people encounter in languages you see in Python which is rather nice and short very very similar kind of approach the job here what we see is that the emphasis is on the squares of X for X in the range there's no sense of mechanics there's no sense of I am the programmer and suddenly I have to juggle state the point there is is direct Haskell wins this one with a somewhat briefer approach but then there's the joy there's something else about declarative approach declarative thinking in many different ways allows you to deal with stuff like this I want the squares X taken from natural numbers where X is greater than or equal to one now that's quite a big set it turns out it's not it's not small that's just like and at this point is we need to manage that no we don't there you go just leave off the right hand side and it just goes on forever this is fantastic now this disturbs a number of people because they're kind of looking to go oh no this is infinite we don't do that in computing you know I've got 16 gig on this laptop but you know next year maybe 32 but that's a bit bigger people get scared of infinity you know it's like physicists and singularities they don't like them but it turns out you can deal with infinity as long as you don't look at it all at once you have to be really really careful do not look into the abyss okay just look at one item at a time if you do that you're good okay it turns out the balance the way that we think about it from a declarative point of view is that I'm not gonna tell you how I'm gonna do it I'm gonna tell you how I might do it this is how I would like to do this so it turns out lazy evaluation is very much at the heart of this when we look at iterators they are a rare occasion they're a a way of making laziness explicit but if we can wrap them up further then as we have here this is the equivalent and notice I've kind of switched from doing vector that will take a long time it turns out what I've got here is an expression that describes how you get the squares of all the numbers it doesn't get the squares of all the numbers a declarative approach is a way of saying one of the aspects of declarative thinking is here's what it would look like if I were to do it are you doing it no I'm not okay and so this is the big cheat that some functional programming does is how they do IO in a number of languages yeah I'm not doing IO but what's that expression I'm telling you how I would do i oh if I were to do it yeah but what's that oh yeah I'm not doing that you want to do ioq give it to the runtime system but I'm pure okay that's that's basically monads in 30 seconds so the point there is it's what if things actually happen when you make a commitment this is how I would do it give me the first hundred okay now things happen things start getting allocated CPU starts cycling and all the rest of it and again we can do exactly the same thing here all we need we don't even have to allocate space for this beyond what is needed to describe this we can just shove that straight into a loop and walk through it so we are describing what it is that we want we are not describing by the way you're gonna need a variable you're gonna need some intermediate storage now you're gonna need to run up a loop and do all of these things we know this stuff we've done this stuff we can let somebody else do that so there is this kind of style of thinking that is particularly helpful but is becoming more real from a C++ perspective we see from that that there is something else going on here simple filters that can be arbitrarily chained and what easily reused and more robust than any almost any other kind of code point here is composability the STL almost managed it but not quite it managed a certain degree of functional elegance in its classic form but composability is about being able to take the out of something and put it to the end of something else and pipelines dataflow architectures functions that actually return stuff that you can then put on the input of something else these are all part of composability and unfortunately sometimes we stopped short of that so that idea is quite an old one very few ideas are very new this is Doug McIlroy's original memo 1964 we should have some way of coupling programs like garden hoses screwing in another segment when it becomes necessary to manage data in another way and this is the way of i/o also this is the invention of the UNIX pipe it turns out it took six or seven years before somebody found the pipe symbol on the keyboard okay but the idea was there's what simple should we use whenever people say oh yeah just arguing over notation just remember six or seven years you know from the time from the time it took him to come up with this memo to the time Ken Thompson said dammit I'm gonna use the pipe symbol people had landed on the moon okay so yeah never worry about your frogadier project being too late there there's always somebody slower than you okay what about what our ancient harvested wisdom okay the book that everybody should read and actually the anniversary edition it's got some really nice stuff but there's and I read the original and then I read the anniversary edition both the anniversary editions got some extra material there some really great stuff but there's a really good point that Fred Brooks makes it's a classic for a reason and here's part of the classic representation is the essence of programming show me your flow charts or your you know your control flow and conceal your tables and I shall continue to be mystified show me your tables and I won't usually need your flow charts they'll be obvious this classic idea of if I can understand your data structures if I can see your data structures and your data structures are well expressed clearly named and their relationships are clear then it becomes kind of obvious how the control will flow through them that becomes a secondary detail if it if that doesn't make sense and you have a world of integers and strings then perhaps I'm going to need an awful lot more work to go through your control flow okay and there is a tendency these days for people to make a lot of string lis type systems which are particularly frustrating but these types their names their concepts their relationships make it really really clear and let the data structure do as much work on your behalf as possible and this applies to a number of things including I'll talk a little bit about threading later so but obviously not everything that is so the basic idea here is that data structures and I'll focus on tables for a moment very powerful I think it's always quite humbling when somebody points this one out excel was the world's most popular function language so when you're sitting there going right yeah I got like cool functional C++ just remember those people who crunching the numbers in your organization's been doing way more FP than you have okay so every programming paradigm comes in different shapes and sizes what we find is that they they all have their positive and negative manifestations so um let's have a look at let's have a look at very a simple toy example to sort of look at just the the tabular way of thinking and then also another declarative approach just to say that I I have an interest as well as photographing books I do enjoy photographing books they are so much easier than photographing people I I kind of enjoy language and words and I have this Facebook page word Friday where every Friday and that would be today and I still haven't done it yet I post an unusual word the rest of week I post other language and linguistic stuff but one of the words I managed to sneak in a while back bike winery coded decimal now I know if somebody somebody contacted me on Twitter and says I often try and use your word Friday in a conversation over the weekend okay it's like they set it up as a personal challenge if you can just drop this into a conversation at some point then you know credit to you yeah I I have not been able to find a domestic situation in which bike winery coded decimal makes any kind of sense but I invite your thoughts on this okay by Quantico decimal system of representing numbers based on counting in fives I have no idea how that happened with an additional indicator to show whether the count is in the first or the second half of the decimal range so we're talking 0 2 4 5 to 9 or 1 to 5 6 to 10 system is found in many abacus systems not the abacus systems you give you to your kids which have 10 beads but proper abacus systems they have 5 - 5 - it's also used in the Colossus computer that actually a number of early computers Electrical and even a couple of electromechanical ones tended to use this before everybody said worked out you know what binary is a lot easier yeah are you sure yes no ok we're done that's it so perhaps one of the classic ones is the Roman numeral system now there is ace there is there is a there's a lot of stories and ideas about the origin of Roman numerals and there's one that I want to be true but I know is not or most likely not and that's the idea that it works the Roman numerals work well across a marketplace where you have to communicate with your hands and say 1 2 3 that works nicely ok that's five that's ten I've got I'm gonna give you 50 here or a hundred okay I want that to be true it probably isn't but in these in these kind of like post true theories maybe let's go for it it is true I've just told you a true fact might be a little alternative but one of the classic ways one of the classic little coding Carter's people like to get involved in is convert a number into a Roman numeral okay they normally bound themselves actually but normally the problem is bounded up to about four thousand one to four thousand and here is one of those enterprise masterpieces let's read let's refocus I mean yeah the normal response you get when you point out to somebody this feels strangely repetitive is it works yeah it's software you can ultimately make anything work given enough time and enough effort that's not that's that's nothing to brag about but yeah this is all nice and enterprise-e but there's a more elegant solution that we can do in terms of taking inverting the problem separating it out there is a bit of control flow here I leave it as an exercise for you you can actually do this with accumulates you can turn it into reduce so you end up with no control state at all what I've done is I've isolated all the control state to the end and now the problem has actually reversed and we can actually see that it's quite simple if you didn't know what this was doing to figure out what it was doing it is a what we've done is we've structured it with the minimum of control flow we're trying to get the data to do as much work as possible so from the humblest beginnings of just looking at look-up tables and you more lookup structures replacing explicit selections with an understanding what are the relationships between the values and the consequences do these relate to actions or do they relate to further values what you're doing is creating a very different mindset of programming you're no longer shuffling bits around which is sometimes what it feels like even at the higher levels but of course you know you can take this problem even further and there's a different way of solving the problem I always used to consider the problem to be an arithmetic problem but a friend of mine John jacker found a solution online and came over to my house one day and we kind of coded it up in Ruby and I think it was originally an f-sharp coded it up in Ruby then I promptly recode it in Python I prefer pison and then I promptly recode it in a number of different languages C++ is such a pain in the backside for this come on string handling people we've got to get sorted so but it turns out that there is a very elegant way of solving this I thought you know what I recommend there it is so it turns out it's not an arithmetic problem at all it's actually a symbolic problem what you do is you the guys who decided bike Winery was too much let's go to binary they did not stop soon enough unary unary is the fundamental counting system of the universe okay one planet to planet three planets four planets how do you represent a thousand planets with a thousand planets it's that simple okay so what have we got if I give you five then that's iiiii ten twice that okay so what we do is we do a simple unary conversion by the way I make no claims for the efficiency of this but damn the elegance look at the elegance people okay and then you have this very simple reduction again funnily enough a different style but a declarative form nonetheless what I've done is I've defined the relationship there's no wiles here there's a kind of an idea of again this one is easy to explain in fact this is the easiest of all the ones I've just shown to explain to my kids because they don't have to know said they don't have to know reg X's but it can be explained and there's a natural progression there it turns out that human beings like sequences okay we reasoned through sequences when we explicitly formulate our reasoning that other thing that you do intuition and all that stuff that's not you know that's not sequential but bit you do afterwards when you try and make it sound as if you were thinking in sequentially and reasonably is sequential okay it turns out that we like sequences which is why imperative programming is so popular sequential classic programming but there are other kinds of sequence and the idea of a sequential flow of other things other than control the relationships of data this goes within this goes within this and so on these are also appealing and simple now while we're on the subject of Romans did occur to me given that you know there are guidelines don't hard-code numbers I tweeted this the other day it's already got quite a few retweets first Roman programmer months 7 8 9 and 10 don't have names which we call them second Roman programmer I just number them first Roman programmer is there bad practice to hard code numbers second programmer it's fine they'll never change right September October November December it is that if you've never thought about why the number why the months have those names this is why yeah somebody changed it will always change things okay anyway enough of that let's go back to the heart of FP so there's another point here programs are executed by evaluating expressions in contrast with imperative programming where programs are composed of statements which changed global state when executed just to clarify when they're talking about global state here they're not talking about global variables or a global scope they are talking about a state that is accessible and visible to other parts of the program potentially obtainable by other parts of the program shareable state if you like functional programming typically avoids using mutable state now this matters in a number of cases first of all that whole reasoning thing this is your bottleneck in software development it turns out what you can understand here it says that one of the things we're not very good at is understanding threading and Bartosz Milewski had this lovely lovely description of how to think about you know threaded programming in most systems shared memories like a canvas where threads collaborate in painting images except that they stand on the opposite sides of the canvas and use guns rather than brushes here okay you know he spent some time in America they only avoid killing each other if they shout duck before opening fire somewhere there's a good guy with a gun but we don't know where if only we could find them now this is completely the wrong way of approaching the problem because this leads to a very very clear way of doing things and I want to position all declarative programming and this kind of thinking in a particular space because I want to emphasize the relationships between things we can draw up a very simple quadrant diagram our state is mutable or immutable and it is either shared or not shared between threads okay at any given point in time we can say yes this is in one thread or no this is actually shared between two threads and so the only places we need explicit synchronization I want to say that there is synchronization going on obviously the CPU level and potentially in libraries and through intermediate things like hues and so on what I'm focusing on here is the stuff that's going to affect scalability and the stuff that's gonna that you can get wrong if I give you more control you can screw up okay if you don't believe me I refer you to the British referendum okay so what we understand here is it turns out that there are four quadrants I've given you a choice of four places you can program four places okay one of them is really bad if you're not sure which one it is it's it's it's this one here the synchronization quadrant okay I'm gonna adopt here red is the color of danger that works in most most in most of nature you know it's the color of blood this is what people spill when they try and solve deadlock problems race conditions and so on yeah there is blood on the coat okay in the Far East is also the color of celebration and that's for the consultants who have to deal with this coat that's the hard bit now I always wonder you know look three quarters of this stuff's really easy yeah yeah doctor doctor every time I change state it hurts we'll stop changing state it really is that simple doctor doctor every time I share state and try to change it you know don't you can change it but don't share it you can share it but don't change it okay it's really simple yeah if you're feeling particularly paranoid don't share don't change okay but there's but we are attracted to this like moths to a flame how do we get there why do we end up why is the imperative paradigm so Donnan evenly even it's sort of in our basic thinking well it turns out that this is relatively easily explained historically speaking we all programmed on the left-hand side because until you had threads you weren't really sharing anything but to provide by default you were unshared and so it turns out you had a free choice and it turns out that because of constraints because of assembly because of whatever it turns out that the top left was the more natural one but now most of these things I'm not going to say they don't matter there are environments in which they matter but I was describing and I had the experience I described it to my older boy but I actually had a description I had a chat with my younger with my youngest son we were I don't know we were talking yeah yeah what are you studying in science at the moment biology dad okay so we had a big chat what are you doing oh we did some stuff on the genome okay and so we talked about that and we talked about DNA and things like that and I said you know when your brother said you know RNA is not a proper life form all this kind of stuff you know viruses so we had a chat about this stuff yeah he asked me the question how much stuff is in DNA know how much you know I said this is the plan for creating a human being and I said well I once worked it out and I said it's around 3 gigabytes and he said that's not very much is it and it's like if you told somebody that 20 years ago the height of the human genome project three gigabytes oh my goodness Wow gigabytes I didn't even know that was a prefix for bite you know it's like wow but now it's just like three gigabytes yeah okay I've got you know my collection of cat pictures is bigger than that so so the point here is this stuff is is is are trivial so what we find is that our sense of what is small or what is large has changed but we have discovered that we have enough slack in most systems to accommodate a very different model of thinking I so unfortunately what happened is we took that kind of thinking which was very grounded in state change and we said things to people we said don't do the global variable thing don't do that don't do that and everybody went yeah Global's yeah maximal state change all the rest of it and then you throw in threads and if you don't know what you're doing already you really won't know afterwards in fact the only thing you know you'll do is panic so we have this problem the declarative mindset looks to take us away from this you know there are some other benefits by the way the old classic observation you know I love it when people sort of say yeah we're putting locks in Wow wait why you put why you putting locks in for safety okay so why are you doing threading at for performance you see these two these two are not comfortable together okay they lock based thinking is the anti threat okay it's not composable it doesn't scale now that doesn't mean we can't describe systems okay it's a previous session and when the early sessions was on this I've seen Shawn present this approach this is kind of where we want to go people but also I want to focus on the humble value my favorite article title from last year from communications of the ACM from Pat Helland mutability changes everything so when we're talking about that I'm gonna go right back to a very very simple class I always roll out the date class because it's worth characterizing and then taking a bit further because there's some ideas here if I take this from a slightly different perspective I want to bring out to two or three little points here so I'm gonna default yeah I'm going to default a bunch of copy assignment and so a copy construction and copy assignment and other things are defaulted as well and this is how a lot of people might approach creating a date glass because apparently it's really difficult to create simple date classes abstractions as most libraries demonstrate and people have this knack of creating false symmetries they kind of put in they are right I'm gonna get something and then I'm gonna set it I'm gonna get something I'm gonna set it and they think oh this is a beautiful balance I brought balance to the force it's like no no no you don't have to have one and then the other people often even automate this in their IDs yeah this whole idea of you can do the IDs allow you to do the wrong thing faster it's just like yeah yeah I'm gonna there's something I don't get right okay I now can make it do it I can do it faster now yeah it's the wrong obsession so let's just get rid of that okay the other thing to observe is often we unify we often don't change things individually because there's a really challenging problem here and this is and this is the very key a very key in subtle point although this has the word public there and there is a suggestion that word private is somewhere here all that has the word class there in many cases people do not focus on this as a system of meaning there are valid dates and there are invalid dates there are arrangements of year month and day that are not valid the idea that I might want to arbitrarily just set a year or set a month randomly without any other relationship to the others these are there's an invariant that this thing has to respect at the very least I should be setting them together and so that gives us today now it turns out that we are actually doing the same job as something that already exists it turns out that we don't need that because that job is already being done by the constructor the validation is being done there if it's nice and inlined oh it's nice some inlinable this becomes easier and you get a lot of syntactic levity as well the whole notion here is that let's just just describe the thing as a system it is a system of meaning so now what I've got is dates are properly values okay there's this idea of it represents a value the only way of changing that value is by rebinding it via the assignment operator now if we are so can intent on this idea of talking about things having properties and we want to get away from imperative thinking then I want to draw you to draw your attention to one thing here people often use the word get as a prefix it makes them feel kind of comfortable and this kind of pops up in a lot of code I've asked people about this and normally it's kind of like the responses my kids give me it's just like while he's doing it I'm doing that because she's doing that it's like yeah I'm sure we've got more compelling reasons to be able to do something just saying the other kids at school are doing it it's not enough and then while it makes it clear that it's a it's a you know it's clear what it means isn't it it's is it I just saw okay I said I was a bit of a word nerd I have a copy of the Oxford English Dictionary on my laptop because physically printed out they actually stopped physically printing it out because it's just ridiculous amounts of tree and it as a dictionary if you are interested in usage how do I use this word this dictionary is almost completely useless okay it sucks at this if on the other hand you want to know what is the history of this word it's the last thousand years this is the dictionary okay and here is this word going back and we see its cognate forms in in in Swedish a middle Dutch and old Frisian you know this is you know this is nerdgasm central so but really what I want to draw your attention to is the fact that the scroll bar is proportionate and I want to draw your attention to the fact that on the left hand side there are four head entries it turns out that when printed out get covers about 30 pages its definition oh yeah that's a simple though it is one of the two longest definitions in the OED the other one is yes indeed set they were destined to go together weren't they and people our way you know is sense like the opposite you know getting set they're like opposites no the opposite is set is either reset or unset it's not get it really it isn't so let's let's also remember something else than in default English usage to get something is to change state it is it's an imperative okay when I get money from a cash machine disappointingly it has a side effect on my bank account okay this is a big one my favorite example is to get married big state change yeah okay the word get by default means change states that's what it's default meaning is if you're trying to get people to think about the values don't focus on the mechanics it's not imperative here so let's switch tidy up the naming here okay so now we're getting this is all good this is all fine we might want to say well sometimes I do want to qualify the year or the month of the day but to do it as a projection from an existing value I want some convenience there okay well there's already a style that people often adopt sort of build alike style to do this and you can just sort of reconstruct everything with you or you can actually optimize out it was actually the same year you don't need to do revalidation and you can continue this so the idea is to think of your values like this as a series of relationships I can define a date not and we will see that this actually scales up into other data flow approaches what you're doing here is saying well here is today and then I'm going to with a different month I'm going to maybe I'm going to move through the year but the idea is you define this with respect to this you don't change this you define this with respect to this and that relationship is is immutable it is constant and invariant okay that's all very well but a lot of people are very familiar with some of that but sometimes they miss out that little Eddy but what about containers what about containers because obviously passing around copies of things is quite expensive and return value optimizations and I save you every time move optimizations are not going to save you every time if you take a million things and you add one to them there will be a cost so there is this idea right how do I do this and so I want to focus on objects there is a pile of books that are all about objects curiously it turns out that psychotherapists psychotherapists are utterly obsessed with actually they're just utterly obsessed my mother's my mother was a psychotherapist and it hasn't affected me in the slightest no explains everything but they are at your object relations shadow the object Celsius it's a slight internal objects revisited yeah I've seen that code actually what I'm interested in here is stack this stack of books so let's talk about the lab rat of computer science okay how far can we get with this one and we're gonna use that to demonstrate a number of points I'm going to characterize it in terms of for operations pushpop depth and top death being the size and I'm just gonna focus in it like that and then we're throwing a default construction cuz I want to be able to talk about it and we're going to make it a pure pop in that sense just like the STL in other words it doesn't return anything as a side-effect so we have this question if we are pursuing a system of meaning how do we understand what this is supposed to do and there is a very useful idea the earliest I've been able to date the contract metaphor is but the lamp sense paper in the early 80s 1983 hints for computer system design and interfaces a contract to deliver a certain amount of service clients of the interface depend on the contract which is usually documented in the interface specification I think it's wonderful and sweet and shows a certain optimism that perhaps people had at the early 80s is usually documented know is occasionally document yeah usually suggests a frequency that is well I've got experienced it so but really a lot of people tend to focus when they talk about contrast they tend to focus on Bertrand Myers exposition of this in object-oriented software construction and the Eiffel language which has this kind of concept of pre and post conditions integrated into its core and I was very very strongly influenced by this when I read this book it was only years later I discovered all of the deficiencies in both his way of thinking about objects and indeed in the way that he frames contracts through pre and post conditions so we can have a go at this when you construct it post condition the depth is zero ok push ok well let's make a note of the depth the post condition when you after a push is that the depth is whatever it was plus one the old death plus one and the top is the new top and this seems ok pop precondition the depth is greater than zero the toast condition mmm well at this point it becomes obvious that there is something missing from our story the death is the old depth minus one can you tell me no more about it no can you tell me if it's empty well it depends I could but the expression actually becomes more complex than the implementation could you tell me what the top is no I couldn't not without adding an awful lot of extra weight so this is the truth but it is very very partial this is one of the things that people don't understand about pre and post conditions is they are very very weak form of specification when it comes to actual languages debt this is a truism what can you tell me about the debt well it'll be zero or more well I could tell that from size T okay can you tell me nothing else about it no tell me what platform you're running on I'm running on a 64-bit platforms well it's one of two to the 64 values geez thanks you've really narrowed it down that was a contract worth having top precondition the depth is greater than zero can you tell me anything else absolutely nothing wow this is really limited I mean nothing up there is false and if you actually switch if you look at the the contracts proposal for a c-plus plus twenty you don't even get this much you get even less debt 0 you get debts is greater that's all good and then down here we start looking at well I don't even get to talk well there's what you get is is I think the word trivial okay I don't want to be too dismissive of it but it's it's really edge cases it just doesn't get out what I understand is a stack so although this is declarative it doesn't seem to have taken us down the right road perhaps there's a different way of thinking about stacks well I offer you another red and white book from the similar era well actually earlier CSP I'm not going to talk about Toni halls communication sequential processes from the point of view of concurrency I'm going to talk about it from the point of view of thinking about behaviors and the way he reasoned I've sort of adapted notation little let's look at what you've got is a stack what I'm interested in is in a talk about it what what kind of vocabulary does have what is its alphabet what kind of noise is gonna make and I'm going to sort of objectify it slightly and say well you can do a push a pop a death and at all the really interesting bit is when you say and what conversations can I have with it give me a trace give me a list or give me rather a set of all the possible interactions I could ever have that are legal with a stack well the first one the empty trace is you can create it and then ignore it which is a bit harsh but I've seen code that does that you know you can create it and push on it you can create it and asking its debt you can create it and push and then pop you can create it and push and then ask for the top you'll see that there are no sequences there are no valid sequences of one or two that have pop is the first one or top is the first one so what you do is you are enumerated all of the possible sea sequences as you may guess there's a lot of detail hidden in the dot-dot-dot at the end if you have a junior programmer or an intern you know and you're not sure what to do with them getting to write this out okay keep them keeps them busy for a while don't tell them about state charts because that makes it a lot easier for them it turns out that this generates that model and it gives us an easy way of looking at it makes certain things explicit visual notations have fallen out of favor recently which i think is a shame because some of them can be wonderfully precise and the her al state chart notation is exactly this and what we're looking at here is very much a it's a it's a visualized declarative form in fact historically David Harrell actually created a calculus notation for this and then drew these diagrams by the side but he noticed that everybody was ignoring the calculus and looking at the diagrams so eventually kind of dropped the notation and went for this so we can actually discuss this much more reasonable level this is quite good okay so where does that take us well that takes us to the question of what are we going to do if we do actually try and do a top or a pop in the empty state we could leave it as undefined behavior which is unnecessarily exciting for this example so I'm going to recognize that when it comes to this question of what do you do when things go bad and this is a key observation Tolstoi it turns out was actually a programmer if you just think about the title war and peace for example I mean is that not about software and development just war and peace you have everything there and in the opening lines of Anna Karenina he talks about exceptions and failures he talks about this idea ought to be precise he talks about failures in the happy day scenario versus the rainy day scenario of code because when things work they just work and there is one way in which they work but when they go wrong there are so many exciting different ways so many dis functionality's just like families so I'm going to choose to say that in this case I'm going to say you we're gonna throw when we call top on an empty or pop on an empty and that's gonna be my mapping here now let's go back to this guy this is okay we started on this from a point of view of what do we do with immutable objects and I wanted to sort of explore some of the other declarative thinking around state change but I want to say no we can have a stack that is itself immutable and and moderately efficient so I'm just going and we can see that the implementation is trivial you can do this as a forward list there's lots of possibilities but I'm not interested in these I'm interested in what happens when I make it immutable in other words every member function is now Const and push and pop return a stack in other words in fact I'm going to change the name slightly push and pop for imperatives okay they they suggest state change but also in a codebase where you do have state change it's really unnecessarily confusing to have things that are named the same and tell people oh yeah this is a non modifying push to give it a different name don't give it a special oh it's the one that's Const no give it a different name so it's grapple yeah gret for non modify no that's not that's not gonna work okay so in other words I'm going to describe it as a relationship this is what happens once you pushed and this is the this is this popped in fact you could using the width terminology earlier on look at this as pushed is with top and popped is without top yeah it's what you're doing is say given this project it with this additional transformation and have a look at it from that point of view so we've got that now that would be expensively we were copying around a vector so there is a question here of implementation the way we're going to approach this there are far better sessions and far better articles on dealing with persistent data structures structures that give you the illusion that things are going on and that are remaining immutable when actually they're not but we take a very simple example if we take the the humble array we start off like that we start off like that if I can guarantee that none of the elements changes then it's okay to alias the representation you know it's trivial because apart from taking part from looking at non salient features such as the address of something there is nothing that I as a user can do with a properly construe that hey guess what we're sharing the representation we can't make that perfectly but every now and then I get people sort of saying well yeah but you can't make this guarantee perfectly it's just like no this is C++ I can use memset there is no guarantee in the face of a void pointer and memset okay you can have to give up the illusion that is the type system whatever you do I can ultimately bring it crashing down to bits and bytes so you know there has to be some tolerance I've got I've got the compiler on my side for most of this okay so we've got that so if I do a push if I say that C is a pot then that works nicely the aliasing still works not gonna work out so well for pushed okay so we changed to a link representation same story holds and we are able to maintain this illusion in fact this can tree off into memory rather rather beautifully we can share representation and so now we maintain the illusion that actually I am giving you a new stack okay so all of software has ultimately smoke mirrors and maintaining illusions and that's what we're doing here there's nothing new in this let me take you back to the late 1950s and that's my copy of the Lisp programmers manual point that I an umber of years ago I I wrote this in the cuj article number 15 Christ it's that long I still have a deep fondness for the list model it is simple elegant and something with which all developers should have an infatuation at least once in their programming life this is also an important lesson I told you earlier on do not hard code numbers if you're ever in the middle of if you are ever tempted to do this when you are writing a blog series do not number the parts okay do not do this I had loads of editors tell me do not do this and they would change all of my part one part two articles and give them unique names finally once I got my way it was with this one there never was a part two there is still a guy that works with the works of John John like us who asked me a few years ago came up to me you know I thought this was my dark past forgotten he comes up to me it's Lee a decade on he says Kevin Ware's part two so yeah yeah when I say don't hard-code numbers what I mean is don't hard-code numbers okay so I I had a data structure in that which I call lisped which I was very pleased with us a name but I'm just going to make this as part of a the stack and we can see there's a stack it's got a link and there's all kinds of stuff going on there and we've got things work create new links and so on it all does what it's supposed to and they'll does what it's supposed to we'll come back to how I know it does what it's supposed to in a bit but there's an interesting question here the interesting question concerns the representation it turns out that when we when we say you know there's a quote earlier on about Haskell and the idea that some languages help us with some things and they hinder us in others if you're working in C++ pursuing an idea of shared representation works really well up to a point the idea of using constants works really well up to a point there's a lot of stuff that really works well but there are certain weaknesses what is the weakness in this code as it stands assume that I have shown you all the rest that alls goat huh no no that's not a weakness did you did you see the Roman numeral solution I showed you earlier yeah well no there's no such thing as slow unless you have a context okay you can never say something is always slow with respect to something or fast with respect to something else yeah so that that's not its problem I haven't given you a context against which you can evaluate that what might be considered the problem here though no no it's not it's a linked list you've use linked lists before yeah good yeah it actually the point here is that you are paying one allocation for one allocation yeah yeah space-wise it's actually cheaper than something so if there's no there's no there's no there's no other stuff going on here you're not you're not having to you know I haven't I haven't optimized it for allocators or anything like that that's fine okay let's talk about memory let's talk about ah yeah let's talk about memory so Tolstoy was not the first programmer that neither was Shakespeare but Shakespeare was one of the earlier most prolific programmers that we know of but the absence of computers in the late 16th and early 17th century was a little bit of an obstacle it proved to be challenging for him so he had to encode he had to encode everything in play form okay he was a very big fan of the actor model of computation so he got in there centuries ahead of everybody else and he so if you look at his plays as sort of parables of software challenges and the questions then we find that the tragedy of Hamlet Prince of Denmark is in fact a it's a story about memory management you take its most famous line to be or not to be that is the question okay I've got an object is it still there is it valid yeah do we want it we're gonna get rid of what okay this is really a handler is really worried about this Oh philia she has a very particular approach she's kind of classic C++ old-school okay slight tis in my memory locked and you yourself shall keep the key of it god damnit you new and delete it Hamlet yeah but Hamlet's got other ideas he's just like well what about garbage collection man yeh from the table of my memory I'll wipe away all trivial fond records so Hamlet's advocating a garbage collected approach okay so you see this is the tension at the heart of the play yeah people don't understand this play yeah I'm here to help you now we have a little bit of a problem in C++ because SBR observes is FAQ garbage collection is not is optional in C++ that is a garbage collector is not a compulsory part for an implementation to say this makes it almost entirely useless as a feature hmm not much of an overstatement you get your GC if your point of safety is its strict if it's a preferred you get a little bit of something if it's it relaxed Wow it's just relaxed it just leaks the thing is my code was written my code was written assuming garbage collection so actually it works perfectly with no leaks in a garbage collect environment how do you write that portably you you can't in other words this is an almost entirely useless feature from the point of view of people writing portable code yeah I almost wish it didn't have it because it kind of gives people false promise hey come this way we've got garbage collection and then they get you in the door sometimes yeah oh god damn it's like a phishing scam so it's a case of why I can't write this reliably like that it's just ah that's kind of annoying so yeah this is this is frustrating so we're gonna have to do it the failures way yeah if you wanted inefficiency I've now given you give now you've got inefficiency yeah now we're gonna now we're actually going to do reference counting and all the rest of it but there is a problem here as well when it comes to simplicity and this is the probably the see fossil trips up in places we don't expect it to when we are trying to source a I've got these beautiful elegant data structures and so on so are the memory management is always a pain in the backside there's always a gotcha somewhere and what I've got here is I'm gonna do the squares thing and I'm going to just generate a lot of squares and I've got absolutely no problem doing that whatsoever everything works beautifully until the destructor it turns out on destruction deletion of the links is recursive through each link recursive that means that you will the destructors will fill up the stack and depends on what platform you're on but on my on that laptop using GCC it's just over 5,000 and then close up it's not that this is not a the thing is that I know when talking to C++ crowd everything I can solve that problem the problem is you have to solve that problem it should not be a problem that needs to be solved in other words doing simple stuff should not be this hard turns out there are lots of ways to solve this problem but just leaving the code as it is is not one of them they will all require explicit program or intervention which is frustrating because there's an awful lot here that's that's quite valuable ok so how do I know this stuff's working all right close today by talking a little bit about testing and I want to bring the declarative mindset to testing because we have sort of a sort of a challenge when it comes to thinking about what it is that we want from tests in for many people there is the sense when you say you know why are you testing your code no let me let me roll back are you testing your code that's the first question yeah you know and and be careful that you're having the same conversation with somebody because I've had the conversation where somebody says yeah I can pilot that's not the same thing yeah so there's this idea so it turns out that testing has come into fashion and [Music] you know there's a but there's a lovely piece from Todd Golding in better software magazine a number of years ago I'm using axiom generic term for various unit testing frameworks I was using mock objects so why did my testing more like necessary baggage instead of this glorious enabling approach now I decided to look more closely at what was inspiring all that unit testing euphoria as I dug deeper I found some major flaws have been fundamentally undermining my approach to unit testing first realization that jumped out at me was view of testing was simply too flat I looked at unit testing landscape and saw tools and technologies often we look at things go frameworks what framework you're using it's the fact that I historically always used to teach C++ unit testing starting from assert and then building up from that to demonstrate that as long as you have a simple way of saying this is true and this is not then that is your that's your ground level all the framework will do is extend your reach and your convenience but it will not change the possibility of the truth that you're able to reveal when we look at the functional aspect so the programmer me made unit testing more about applying and exercising frameworks yeah I'd reduce my concept unit testing to the mechanics again that term mechanics and general my mindset had me thinking far too narrow about what it meant to write good unit test and it's good unit test that I will emphasize good you test fortunately has a lovely abbreviation if it works very well particularly particularly Germany yeah that's it's good yeah yeah so you know you know tell me about your unit unit tests a good that's like cool great fantastic so actually the guts turn was properly coined by Alistair Coburn when just saying very many people say TDD test-driven development when they really mean I have good unit tests I have guts and modern programming professional having guts his interest here was test-driven development is a way of doing something but what is the thing you get at the end of it or what is the thing you can get or put in other ways what is the thing that you want to end up with no matter what way you took yeah this is there's journey versus destination and there is this idea that sometimes people use the term TDD and Ron Jeffries he was one of the original extreme programming crab because there's a lack of a catch word people often use the term TDD where they should really be talking about good unit tests there's lots of things that could qualify but in the context of this talk is I am interested in the communication of intent I want to make testing more declarative quite literally on it make it more of a data structure and the way a lot of people will go about testing the stack class is to have a function called tester that doesn't really tell us much how much does that communicate it communicates that we are testing the stack great that doesn't tell us very much at all okay we might refine our approach a bit and say well I'm going to test the stack constructor I'm going to test the stare the stack was pushed operation the stacked popped operation debt and the top well here we're getting somewhere but we could certainly improve on this naming let's actually structure things we nest things and group things stack tests we can get rid of the noise word test again I'm very keen on getting rid of certain noise words that we we happily I don't want I don't need my tests that have the word test plastered all over them normally it's very obvious from the context and if it's not then you're doing something wrong so what we've got stack test constructor pushed pot death top now if you look at this this is a one-for-one mapping of all the member functions in the class this approach to testing is obvious it's intuitive it's very common and it's also completely wrong I mean I could not be more wrong the only thing that is only slightly more wrong is if I name the test 1 test 2 test 3 test 4 test 5 and yes I have seen that yeah the only thing you the point is a test is an act of communication you want to give meaning to your code you don't simply want to say it works the challenge is not to show that something works is to show what it means when somebody says it works yeah but what are you expecting that's the deaths that it turns out that's the harder question it's like yeah it's green but what does that mean it means that whatever it was doing it's still doing great so when it said what was it doing the right thing we have no idea but it's still doing it and now it's red it's no longer doing it is that a good thing or a bad thing we have no idea yeah it's a limited form of communication what the whole point of this kind of thinking this approach is to say it's what is it supposed to do what do we believe it's supposed to do let's let's advertise that let's not hide it that's the wrong kind of information hiding ok so let's talk about it a new stack is empty yeah there's no kind of question of Kevin what do you mean by that yeah here you're testing the constructor what does that mean it also when I said this is completely wrong it also turns out to be surprisingly impossible how do you test a constructor what is it that you going to test about it you're going to test the state of the object after you've constructed it oh that means calling deaths up so you're testing the constructor and the depth operation so that should be called constructor and s and constructor and pushed and top and depth and kisara these are very poor names we actually have ways of talking about this a new stack is empty an empty stack throws when cleared for its top item an anti stack acquires death by retaining first in other words this is a description of what this does these are propositional statements ok these these are declarations that have truth value ya and truth value is in this case express through green or falsehood is expressed through red so I'm gonna take a small change there I'm also going to adopt some terminology from the BDD communities so yeah let's call this back you know just instead of just thinking about there think of it as a specification one of the reasons I found this kind of language shift is helpful sometimes is for many people they have existing ideas of what they think of as testing that are quite different and so sometimes the way to get people to do something is to say oh it's nothing like that at all oh these are not tests this is just a specification we're using examples to illustrate just describe what you're expecting to happen now this kind of thinking led me a number of years ago to come up with an approach where I wanted to really think of a much more complete approach because most C++ testing frameworks I've ever seen were very function oriented or inappropriately class oriented and I wanted a very different approach I wanted to say I want to focus on structure I want nesting I want I want to have this language of propositions I don't want to have people having to worry about identifier naming conventions and so on and this I dreamt this up it was just a prototype framework I gave a few talks on a few years ago it was called Heathrow because Heathrow Airport is the airport where I had the idea or to be precise it was on the approach path to Heathrow and then driving home from Heathrow so I worked out all of the details Shakespeare could do it in plays it turns out you can do some great programming in the car and on the approach path so these basic ideas here and Phil Nash saw saw me do one of the talks and that's what triggered catch it's that idea of a very strongly intentional form the idea is that you're not focused on test 1 test 2 you're not focused on the mechanics of this you are focused on the relationships and being able to express yourself as clearly as possible without the constraints of identifier naming a new stack is empty and empty stacks Rose when query for its top item and so on but actually what I was trying to do at the time was pre C++ 11 where the pre C++ 11 adoption what I was actually trying to do is something that I'd done in JavaScript and I'm often very rude about JavaScript there are reasons there are very good reasons I'm rude about JavaScript but the fact that in JavaScript I was able to come up with a few lines and a really simple testing framework that took advantage of an object to look up and just allowed me to have a simple ad hoc structure that had strong intention and I couldn't do that easily and C++ really frustrated me however and thanks to thanks to C++ 11 I can now do that trivially so therefore I get to realize that this goal is I don't want to think of my tests as functions I don't think of my that I want to my tests are a data structure okay what I want from a piece of code can be defined as a data structure and you can take it deeper but this is a fairly flat a simple flat one I've got a specification stacks back the new stack is empty code that does that an empty stack throws one crew for its top item and so on so you can see that the names are the first and foremost thing when a test passes then that is that is a truth about the code that you have got it's a contingent true so I mean you can still get the test wrong but it is it's a description of what we're expecting and when it fails you now know what it is that is not true it turns out you can you know sort of describe the whole of that stack quite quite straight quite easily and the implementation still actually fits on a slide which I'm always quite pleased with if I can get get that done we can also take this further the idea of looking at the looking at things from this point of view is to get people thinking oh it's that easy I could write tests for anything what if I'm dealing with a pure function what if I want to use more data in the previous example I was using single exemplars okay I've got a stack and I'm in each case I've got one example but if I want to deal with a leap here clearly I need to have a perhaps a few values that I care about so leap here I think it's shelter is that correct yep and just out of interest you're a smart ground when is a year a leap year in the Gregorian calendar I'm going to assume it's a proleptic Gregorian calendar if you don't know what that means don't worry about it it just means you don't have to worry about crazy stuff yes correct yes well done that's why humans can't remember it that's why I use it as a training example because it's just like you know humans struggle with you know humans struggle with rules and then he was struggle with exceptions to rules and if you throw an exception to all the exceptions that's that Stack Overflow and it turns out it's too in that case okay humans car you know I struggle if I if I get if I go to North America I always struggle when I Drive it's just like oh you can turn right on a red ok that's one exception to the rule oh except on a Tuesday when there's a full moon you know you know it's just that bump can't do it can't do it you know so the point here is that I think it's an interesting example because it's not to do with the implementation the challenge here is to demonstrate to the reader what's going on to talk to the reader I don't care about test is leap year I want to communicate what do we mean by leap you and let me give you some examples I want that to be as clear as possible I don't want to have loads of procedural code doing that so what I've got here again simple specification structure years not divisible by 4 not leap es years tube is by 4 but not by 100 are leap years divisible by 100 but not by 400 are not leap years and divisible by 400 are leap years Oh Kevin do you have any examples of that well absolutely yes look the value is 2017-19 not 1999 to 1988 and one they all result in false so you end up with this whole idea of thinking of your test approach much more richly and much more largely in this sense and again this is actually even less code than before it's to the point where you can feel free potentially to create ad hoc frameworks that illustrate what you're doing here is don't think of it as a framework in fact perhaps I shouldn't be using that term at all what you're doing is you're creating a data structure that describes something and that is the very bread-and-butter of most programming so when people say oh yeah but we've already got a testing framework that's nice but are you describing what you're doing well is that is that are you communicating the intent if I asked you to write a class for something in your system or rather I want a new behavior so while we don't have that behavior we're just gonna have to use vector and string everywhere it's just like no you can do better than that create your own abstractions so there's this whole idea that tests are first-class data structures when you look at it from that point of view and then you can do you know simple implementations or you can be crazy your colleagues will not thank you for this implementation but they will thank you for the fact that you put the tests in there because ultimately what we're looking at here and why in a non declarative language like C++ and indeed many mainstream languages we still have the challenge of meaning as being a quest but we can always do something to be more intentional and by looking at things from a declarative point of view there is this idea of framing things both the classic comparative perspective the idea of the data structure is doing the work the data destructure describes the relationships that are the most important sometimes it can be very sophisticated you can be setting up pipelines of computations in other cases it can be just as simple as using a lookup table sometimes it's shifting language or mode of description in other ways it's Reeth in other cases it's rethinking how you talk about your values um and I think ultimately that all this is driven by the advice of the author Elmore Leonard try to leave out the part the readers tend to skip I find this is very useful for code and for documentation and on that I think we have a couple of minutes for questions but yeah thank you very much for your time I hope that's been useful or inspiring I hope you haven't had to sleep you know that's later any questions [Applause] I don't think that qualifies as a question I think that's actually an action that's an imperative it has a huge great side effect in the room but thank you questions thoughts random desires for coffee okay we're gonna go with random desires for coffee and later beer thank you very much
Info
Channel: Meeting Cpp
Views: 5,887
Rating: undefined out of 5
Keywords: declarative, code, c++, cpp, cplusplus, meetingcpp, Meeting C++, Meeting C++ 2017, Kevlin Henney
Id: 1s-BGBA8Nqo
Channel Id: undefined
Length: 86min 36sec (5196 seconds)
Published: Tue Feb 20 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.