 Okay, great. So let's get going with our next talk. This is one of the longer talks 45 minutes Which will go by a blinding speed because our next speaker is you who the cats the man who needs no introduction So take it away. Thank you So today I'm going to be talking about as you might have guessed the idea behind cruft So yesterday Sandy gave a really great talk about the reasons that we get less satisfied with our projects over time her talk mostly focused on the ways that Using better object models using better object orientation would avoid that decline that steep decline in satisfaction over time And I thought that that was I liked it a lot I felt like to the extent that the problem is poor object design poor Structure, I thought her talk really provided some good tools that you can use to help avoid declining satisfaction over time My talk is about situations where we cannot avoid this declining satisfaction simply by doing a better job ahead of time Sandy told you how to contain the mess today. I'm going to talk about how and when to clean it up This talk is basically about the declining value of code over time when you write a piece of code for the first time It feels great because what the code does matches perfectly with the assumptions made by the code But over time those assumptions change subtly at first and then faster and faster and faster This takes years often and my projects this always takes a long number of years but the graph the gap doesn't grow linearly the gap between The assumptions that were true when you started building your application and the assumptions that are true years later actually grows faster and faster and Year-over-year you're gonna write the same amount of code people write Lines of code that are the same year-over-year But the weight of those mismatch assumptions the gap between the assumptions that you made when you first wrote the code and the reality years Later consumes more and more development time here I have just a projection of the previous slide if you assume that you're getting accelerating more and more and more Assumption mismatch over time You're able to write more code, but the assumptions that were incorrect that were correct in the beginning But are incorrect now eventually catch up with you This sounds a lot like classic technical debt, but there's a big difference you take on technical debt on purpose With enough discipline you imagine that you can eliminate it altogether By thinking about technical debt in sort of in the way Sandy talked about yesterday Or you imagine that you can pay it down you take it on on purpose and imagine that you will pay it down The problem I'm talking about today is more like buying a bunch of rim stock in 2008 and never adjusting it when the company tank and Unlike technical debt Technical obsolescence will build up no matter how hard you try to avoid it. The question isn't how to eliminate it It's how to plan for it So today since I do so much work with open source I'm going to give some examples from the open source ecosystem And I think one of the reasons it's very In sharp relief with open source is that open source works on solving problems very generically And so if a problem is tricky often that gap becomes a chasm very quickly as the generic the assumptions made early on Rapidly fall out of favor. I've given a couple of talks like about things being hard and You might want to watch this just to get a sense of sort of what's going on behind the scenes I think this would be a decent companion talk but the basic idea here is For everything that seems straightforward it seems like I say render and then I render a bunch of stuff on the screen Obviously, it's relatively straightforward. There's a lot more going on behind the scenes There's a lot more assumptions that are building up and that's true not only about applications that It's not only true about open source projects like jQuery or rails But it's also true about your own applications often applications can take on the characteristics of frameworks or libraries over a long period of time So a good example of this sort of thing is jQuery's DOM readiness API and DOM readiness is something where Solving the part problems generically basically means that there's an assumption for every scenario and every use case So it's not just one assumption You know the assumption would be the browser does not provide a way to find out DOM readiness Therefore we will do this hack that would be one assumption and one outcome but actually there are many many different browsers and many many different use cases that people are using this API for which Means that there are some assumptions that state true for a long time like in IE six There is no way to find out DOM readiness without hacks But there are other assumptions that drift over time like in Chrome. There is no way to find out DOM readiness, right? So you end up with a situation where Technical obsolescence basically creeps up on you because for a long time one of the anchoring assumptions of your API Stays the same but the other anchoring assumptions are slowly drifting away So the gap is growing, but there's really nothing you can do about it for a while Rails had some examples of this Security in general almost all this rails assumptions that it made about security the first time we ever built anything with security Just turned out to be wrong, but again these assumptions creep up on you There was a pretty giant CSRF example a few a couple years ago where basically just it turned out that the entire Assumption core that rails was using was just wrong and so obviously when that happens It's sort of game over but there's obviously gaps that start to build up over time in coatings right in Ruby 1.8 there was no coding support and Ruby 1.9 shipped encoding So now the assumptions have changed, but as more and more people move to Ruby 1.9 the possibility of us using the change assumptions to do anything I Guess sort of the the the assumption gap grows But the ability of us to do something about it doesn't necessarily Snap into relief until for some time In ember we have this is sort of my I'm early on I'm early on in that big one in that Big gap so there's things that we're doing like data bindings or how you should build your application structure where today The code that we're writing is still very much in line with the debt with the Assumptions that we're making right so data bindings well, there's no data binding support in the browser There's no object observation in the browser So we're gonna use set and get and so far that's true And it's very difficult for anybody to come up with alternatives But over time that gap is gonna grow chrome is gonna ship object that observes right and we may not necessarily be able to do anything about it right away But the fact of the matter is that the very clean very clear assumptions that we have today which are we have no choice We have to do everything ourselves that feels good today And is a good reason for a whole bunch of architecture decisions that we're making will slowly slowly drift and Again in open source It's especially bad because he really can't you have to wait until they drift where it till you get this giant Chasm before you can actually do anything about it in your app You might be in a better place and that's just a couple of examples There's just a ton of things that every project does that are based on assumptions That's really the core of my talk today is that there are assumptions underlying every decision that you make and the constraints that underlie Those assumptions while they may be perfectly true today and following those constraints will make you happy as a programmer today Once when those assumptions go out of style and those assumptions are no longer true That's one of the main reasons why you as a developer become less happy with the code that you write And I think another interesting thing about open source is that this problem is because worse with really good solutions with great solutions Right with good solutions you can get away with having sort of blah bland assumptions You're a you essentially offload a lot of the assumptions onto your your users So you don't really have to change a lot There's not a lot of the effect of the code that of the library that you wrote that really changes because the user is Responsible for keeping all that up to date But when you have a really great solution something that really takes shoulders a lot of the burden for yourself Something like rails or something like I think ember The end result of that is that changes in assumptions have rapid effects on the ability on that gap right so in rails if it turns out that HTML rendering on the server is no is a bad assumption Then it's not it's not simply going to be oh no problem. You can sort of tweak around the edges It's gonna be it's a it would be a big problem I think rails took some steps years ago to help mitigate this but basically if you or if it turns out client side development It's a bad idea. Nobody is going to do that embers basically game over because we basically took such a big bet and this is sort of a Side point, but a lot of times people don't notice the difference between how much Between a partial and a full solution until the solution itself starts to break down You end up with sort of checkbox oriented featured feature assessments or you're like oh, let me look at this library doesn't have any of these features and There's sort of the reason I bring this up is that I think Understanding the idea behind technical obsolescence is an important part in deciding What you're gonna pick so if you have a project that's gonna be on around for a very long time You need to really plan for technical obsolescence and I think people when they do checkbox oriented feature Analysis, they're not really thinking a lot about okay, so there's this routing feature or there's this data binding feature What assumptions underlie it now? There's sort of I think a big a big objection to a lot of the things that I'm saying here and a lot of my philosophy in general which is you can basically avoid all software problems and actually I Think Sandy's argument is A weak version of this straw man You can basically avoid all software problems by writing one writing programs that do one thing and do it well and Then if something changes if some assumption changes no problem Just remove the little tiny piece of your program that has the violated assumption replace it with something that has better assumptions And no problem that will be great And I think writing good decoupled object oriented software is gonna be a way that you deal with certain problems It's gonna be a way that you deal with some problems But I think that this kind misses some of the mark and I think the reason is that this Sort of this sort of thinking simply moves the complexity to rapidly evolving public API So instead of having the complexity inside of private API is what? Sandy called the Omega mess you end up with a very public and unstable mess and Unfortunately No matter how hard we try we usually don't get these interfaces perfect And so this the idea that don't build any Omega messes ever instead move everything to public APIs and public Interfaces and write one thing that does it well I'm not saying that this is what Sandy said, but this is deaf. This is the straw man objection What this ends up doing is it ends up creating all these public APIs that people who are using the system have to understand So it moves the complexity essentially from edge cases that are inside a self-contained component to edge cases that are now in between all these components And in many cases this problem pushes the integration tax onto the user So the user instead of the user saying I'm just gonna use rails. I'm gonna type render. I don't really care what render does I want to make sure I get something onto the screen Now the user is responsible for saying where do my templates live? How do I decide what template engine to use when I render a template with a partial? How does it know where to find it right? So you may have a very very good interface you may have a path-resolving interface that lets you explain to the to the Template system how to find other templates, but that doesn't mean that there isn't an integration tax that is being placed on the user I also want to point out something that I find interesting people almost never say the entire Unix philosophy And I think it's because it undermines the the point that they're trying to make there over some Overly simplistic point the original Unix philosophy was this is the Unix philosophy write programs that do one thing and do it Well write programs to work together write programs to handle text streams because that is universal interface, and I'm not saying Ha ha I got you node is not about text streams game over what I'm saying is what I'm saying is There has to be the idea of a well understood Well stable public interface in order for the idea of writing small things that do things and do things well to work If you're in a situation where you're in the middle of building something you're in the middle of deciding what your domain is You're in the middle of figuring out what it is that you're building and you try to build these little things that do things well And talk to each other you're gonna end up spending more time thinking about the interfaces between these products and actually figuring out your Domain and early on in a project in the unstable part of the spectrum It's actually very important that you figure out that you make your way to stability Okay, I agree So here's an example so the Unix philosophy works really well when you're working with simple text formats But in this case Even though it works it would be better if there was just an answer in get and in fact That's how get has moved get started off with a very Unix philosophy oriented There's a bunch of text that gets dumped out feel free to do whatever you want with it You can run all these commands But at the end of the day once you get to a more stable understanding of what it is that you're building Having interfaces that say I would like to know give me my branch or whatever works great And I think another point that I would make about this slide is that it also relies on the idea that When you say text of the universal interface, there's actually something implicit there Which is people are you using tab delimited or space delimited or some kind of sensible delimited output If you have something like get which just dumps user-friendly output onto the screen in a lot of cases in order to get information You're not necessarily going to be able to use the Unix philosophy to get what get done what you want to get And so I was thinking about this a lot and one of the I sort of found an analogy in the idea of supply chains and supply chain management So early on in the in the stage of building a car. That's not a real car But early on in the stage in the in the 19th century when they first started building cars people didn't really know what a car was yet and so initially The idea of vertically integrated supply chains the idea of I'm just going to do all the parts myself Ended up being very effective. So it isn't necessarily how it started out But vertical integration really won it won the story early on in the process of building Cars because of the fact that there's the idea of a transaction tax And basically the idea is that when you're not sure when you're not really sure What's happening in between all the steps in between all the pieces of the puzzle? There's a high tax communicating between all the different pieces of the supply chain So don't pay the tax just do it yourself and you could you don't have to worry about Standardizing things you don't have to worry about figuring out how the parts guys are going to talk to the assembly guy You're going to have the Ford specific version of that and then don't worry about having the everyone specific version But over time vertical integration actually does give way to distribute systems this this happens in economics and But when does that happen and the answer is that it happens in response to more standardized ways of thinking about things and a more reliable supply chain, so How does this fit in with software? so when you build Components in software components connect to each other very promiscuously You can be careful about this But the end result especially in an unstable system is that you have a lot of components that connect to each other promiscuously and The point that I'm making here is that every link in this in this diagram represents a transaction cost and Typically the cost early on in a system The burden of this cost is on the end developer right so you end up with you have Sinatra and you have What's that the shotgun and you have? Eurubus as a separate library and whose job it is who ends up being the person that pays the transaction costs for getting all These things together why that that's Ford Motor Company. That's you that's the person that actually puts it all together so What happens over time though is that a lot of these? Connections fade away. We understand more what it means to build a car. We understand more what it means to build a web app we understand more how you want to integrate between a template engine and Rails itself and so a lot of the transaction costs become much much cheaper So instead of there being large transaction costs the cost of thinking about okay How do I integrate rails with Eurubus initially? It's very expensive. You have to think about it a lot eventually becomes rather clear In sort of the way that it became rather clear how you integrate template engine in JavaScript There's a function it takes a context returns a string right that's how it works in JavaScript Eventually that sort of happens on its own everyone understands what's going on and integration gets cheaper But integration only gets cheaper some of the time and I think that's one of the main points that I'm trying to get across here, which is Even though integration gets cheaper it doesn't always get cheaper Which means that if you start off with the idea of why don't we just front-load the whole thing? Why don't we just build standards for every single link on this chain? We'll just say what every single thing is we'll say how you look up templates will say how you can talk to templates We'll say how you render things will say how you respond You're gonna have turned out spending a whole bunch of time building a bunch of Standards that don't end up mattering that don't end up really reducing transaction costs it ends up being Cheaper to not have bothered now rack is a really good example of sort of this life cycle so Early on in the days of rails Basically, this is what an architecture diagram looked like there was rails. It had a bunch of stuff in it and Then there was mongrel which had mongrel rails inside of it and those are basically the same thing So it was basically one giant thing. It was a vertically integrated Supply chain, but why did we do this? I think in retrospect it seems fairly obvious. Why would you not have rack? Why would you not have some sort of standard Java did it Python did it before much before Ruby did it So why in the beginning of this process did rails decide not to do that? and The answer is that the early on in the process the costs of building the standards of thought costs of integrating with third parties Ends up being bore and ends up being bared heavily on the big player So rails would have to essentially build the marketplace so rails have to choose between figuring out what was going on what does it mean to render what does it mean to return a response in Ruby we have to choose between that I mean I wasn't part of it rails have to choose between that and spending a whole bunch of time to build a marketplace of third-party components Now what ends up happening is that there's usually small players So murb was an example of this although murb ended up being a pretty big player There's usually small players that realize it's annoying as a little guy It's annoying as Sinatra for you to have to actually build server connectors to every single thing so one of the sort of side effects that happens early on is that This happened to rack is that people say look there's a de facto standard you rails, please integrate with this de facto standard and This is actually a pretty good bludgeon against an integrated solution So when you start off in the beginning You really want to just go get stuff done build an integrated solution Figure out figure out what the domain is and don't bother to try to figure out what all the integration pieces are But it's very easy and open source for a third party to say hey There's this standard you should really implement it So what happens after that so it's very hard to actually fight back against that So what usually ends up happening is that you have now a ton of standards, right? So a mongrel points the rails entry point points the session middleware points HB security controller actions These are all standards. Everything's a standard and Unfortunately even when interfaces are standardized They're still integration costs and what basically ends up happening at the end if you look at where rails is today is There are some parts of the system Where you really want standards you really want the rails router to be able to route to a synod trap That's a really important thing and so the idea of rack is essentially Very standardized the the cost of adding a new rack like component to rails got very cheap This ended up being a big win But there's other things like how sessions work in rails where rails really pulled back rails said We don't really think that it's a good idea for us to spend significant amounts of time Working with the community to figure out a general session interface because it's costing us and our users a lot in terms of Oh, we realize there's a bug in our session system now We need to go through the entire process of getting a new standard So there's still parts of what rails does that even though Theoretically you can imagine that it could be standardized Doesn't really turn out to be the case And I guess the question that I would have you ask about all this is who pays the integration costs and the answer is never Nobody pays them. They're free. You build a standard and it's free Hopefully in a good world the integration costs are spread out across a lot of users But the short version of what I'm saying here is in rapidly evolving spaces tighter integration improves robustness and That is a contrast to everything should be standardized and I think one thing that's interesting about the whole unix question Is actually it turns out that unix didn't build itself as a thousand people building one tool that happens that happens to work Actually, most of unix's tools are were built by atnt and we're obviously built to work together by people who were who themselves work together Okay, so that's that was sort of a sideline. What does this all mean for software? So what it means for software is Cruft is inevitable when you build something in the beginning You don't know the whole story yet. You don't know what the domain is I think this is as true and open source as it is true in your own personal applications Maybe more in your applications than it is in something like ember or rails So you don't really know what's happening yet And so the cruft is not there because you're not it sometimes it's there because you're not good enough at object-oriented programming yet But often it's not there not because you don't know enough about object-oriented programming But because you don't really know what you're building yet The real world is a messy place There's a lot of assumptions that go into the things that you're building Whether you're supporting ie 6 7 and 8. Are you supporting ruby 1.8? Are you supporting rails 2 3 etc? All these all these assumptions and those are just assumptions about platforms There's assumptions about your own projects as well, right? Maybe you're building a construction management tool Maybe congress passes a whole new construction management regulation and that changes everything Maybe that happens slowly over time and the gap grows Maybe everyone starts using computers instead of using fax machines So in in fact Solutions that you build as part of the projects that you're building are often ugly But again, they're not ugly because you're writing software poorly They're ugly because the assumptions the the people that actually power the solutions that you're building Are ugly. They're crafty Didn't mean to say that people are ugly see previous talk and the cruft that you're building Is cruft that becomes obsolete over time, but it reflects the current reality of the ugliness of the underlying problem Now here's a really sad thing about all this which is that Early on early on When you add cruft you're adding cruft for a good reason jQuery added a lot of stuff early on because ie 6 demanded it But People often respond to cruft in a sort of knee jerk fashion So early on if you're writing a project and you have to deal with some ugly underlying problem You are going to get really defensive every single time someone says that code looks ugly. What are you doing? That's crazy. Couldn't you do something way simpler? You're going to get really defensive about that and the really really sad part is that over time in a project Especially as you have personnel turnover The idea that the cruft is just there because it has to be there becomes received wisdom And if you remember in my first diagram, I showed that that gap grows slowly So in the first two years, this is the right thing to do Everybody should say if there's cruft is probably there for a reason Everybody should say don't touch that. It's probably there for a reason. We knew what we were doing But as years and years go come along You end up with people doing a couple of steps that make the situation even worse So you have in the in the good in a good world Somebody goes and they says what is this cruft? This is crazy. This is stupid. They go and remove it They spend a day refactoring and then they get a test failure And they say ah in fact this received wisdom everybody says don't touch that they knew what they were talking about There's a test failure. Aha and in a bad case Which has even worse has even worse reinforcing behavior. You remove the cruft everything passes you go and ship a release Everybody freaks out And now you say oh my god after avert and again that just reinforces it reinforces the idea that everybody has that The problems are every code a piece of code is there for a reason the cruft is there for a reason And projects end up developing immune systems if somebody says hey, I want can I spend a day or a week Refactoring this piece of code everybody remembers the last 10 times somebody touched that and they say no Don't touch that code leave that code And this is basically this is what rails 2 3 was like Rails 2 3 was basically a lot of code was there for a good reason But it was there was so much code and there were so many assumptions that built up over the years That were sort of implicit that everyone said don't touch that It's probably there for a reason don't touch that but Over time assumptions change over time The three there's a lot of code in rails 2 3 that was there for ruby 1.8.2 There's a lot of code in rails 3. That's there for ruby 1.8 There's a lot of code that's in jQuery for ie 6 7 and 8 And there's probably a lot of code that's in your app That was there because of some assumption that somebody made good or bad really early in the project that doesn't apply anymore So here's an example from jQuery. We have a dom node and you want to put some data on it Turns out ie is stupid ie has a memory leak that obviously will never be fixed in ie 6 That if you put some data on the dom node and remove the dom node the gc never collects it so So here we try to remove the node. We have a memory leak that sucks So what does jQuery do jQuery says okay, we can put a number on the dom node numbers are don't cause garbage And then we will go and we will create a separate cache that puts a data in that number And then we will make sure that when we go remove the node you always go through jQuery when you remove the node We will make sure to clear it And that actually turns out to be a really good solution if one of your core assumptions is we cannot put data on nodes But it's actually a lot of code right and this is I think this I think Uh, it reinforces sort of what I what I'm saying, which is it's easy to imagine Oh, it's an ie hack. It's probably like three lines of code sometimes Sometimes the assumptions that you make in your code either Old ie ruby 18 or whatever the assumptions are in your personal code in your application Sometimes the assumptions really drive the entire architecture of your application your application the first project I worked on involved microsoft project and a lot of the assumptions that we made had to do with things that microsoft project Did in the first version but years later nobody used that version anymore And really it behooved us to go back and think about whether the architecture or our entire application even made sense anymore so The interesting thing is as long as we support old ie We're going to need this code as long as we supported that old version of microsoft project We're going to need that code and this is this sort of explains that gap That gap in technical obsolescence right as long the the gap grows slowly the gap creeps up on you because for a long time The assumptions that you made they may be becoming less and less relevant, but they're not irrelevant So as long as you require old ie You're going to need this code which means you're going to build up an immune system because people You know zepto is going to come out and zepto is going to say hey jQuery you suck Why do you have this crazy code? You should remove this code and jQuery people are going to say ah little do you know but if you do that You're going to have a memory leak in ie. I don't care Right But what happens when old ie becomes less relevant? And the answer I think is what jQuery did Uh about a year ago jQuery did a full analysis of basically the entire code base to try to figure out We didn't do a good job of tracking our assumptions over time But we did an analysis of the entire code base to figure out what assumptions were in the code base based on earlier browsers And by keeping track of the reasons in the months and a year ahead and analyzing that We were able to determine what the cost of removing old ie was right So I think there was we've been receiving a lot of complaints over the years Hey, you should just remove all ie and there'll be thousands of lines of code you could remove And for a long time we just had this general feeling the project had received wisdom that There just wasn't that much of a win and in fact it turns out in retrospect that that received wisdom was true But only until ie eight after ie eight. There's a lot of code So what's the life cycle? What's the life cycle of a project the life cycle of a project is in the beginning the cruft Is a real solution the cruft matches one to one with the assumption that goes into it Over time you develop cruft defensiveness you say I don't know. I don't know why we put that there But it was probably there for a reason or or hopefully better yet. That's there for ie. That's ie fix But over time a gap appears and unfortunately The gap usually grows before it really becomes pressing and important that you deal with it So you get you you get back into a crouching position. You you Man the fourth you say I am sure that this is a real thing. I the the ecosystem becomes Circles the wagons Right the ecosystem circles the wagons around and said anytime anybody complains this happened I think with jQuery and zepto right zepto came out zepto said hey you guys suck look we can do the whole thing in One cave code We said hey, you're missing a whole bunch of stuff. You're not doing all this stuff and it wasn't just ie right it's a whole bunch of stuff and So over time The received wisdom gets consolidated and more and more no matter how big the gap gets you always as a project have an excuse For why this is happening But eventually what happens is some new person comes into the project your application Some new person releases an open source competitor where it turns out that the gap got so wide that there was a lot of wind That could be gained simply by readjusting the assumptions starting the assumptions from scratch And because of the fact that the normal mode of operation is consolidate retrench You usually miss it. You miss the opportunity to fix the problem So what's a better way to deal with this? What's a better life cycle? I think people should track their cruft Maybe in cruft.txt Maybe cruft.markdown I think people should when they build when they write some code. That's not optimal when they write a mess They should write down somewhere not in line in the code but somewhere what the assumption that went into that code is and to allow future people to say This assumption does not is not valid anymore. We are going to remove that code And I think this is especially important the more parts of your code base it touches Again, I don't think it's ever possible to fully isolate these assumptions. You have to build code You have to ship software the assumptions are real But it actually is very important for you as a part of your project life cycle to periodically say that assumption that we made Is that true anymore? Ember is already starting to do this. We're only a couple years in and we're already starting to say Did things that came out over the past few years affect our original assumptions? Does the fact that older versions of ie that es5 is becoming a more valid thing for us to care about? Does this affect our decisions and in fact it has In fact, even in just a couple of years There's things that we can do to radically improve our architecture just by taking advantage of the fact that One of our assumptions, which is we have to support old ie is slowly fading Maybe we can't fully solve it. Maybe we can't drop ie support, but we can really start thinking about how to how to move for Now on the flip side of that it is okay For a for you to be the dom library for ie6 users if you had a construction management app that supported some old version of Microsoft project it is okay if you as a project decide We're going to be the construction management app for Microsoft project 98 That's totally fine. That might be an assumption that is still valid for your project And I think that is that is a valid conclusion that you can make when you're reevaluating your assumptions And this whole discussion is not even just about the support matrix I sort of I've covered this but there's a lot of assumptions. There's a lot of inputs that go into the decisions that you make and I think So a good a good example of this would be rails right so rails I think Is based around the assumption of rendering server side html in large part I think there's a lot of really good things that rails does for json apis I use it for json apis But I think there's definitely a world in which the gap continues to grow right now the gap is rather small But I think there's a world in which the gap continues to grow And so there's assumptions that enter into things like rails and jQuery But also your own applications that really don't have to do I don't want you to take away from here Oh, I should think about whether I still have to support ie6 That's definitely one large set of assumptions that goes into how we write our code But there's a whole other set that are basically based on the human beings that use our products So what do I want you to do? I want you to keep track of the edge cases in your code I want you to keep track of the assumptions that enter your code I want you to keep track of What the reasons that might might cause technical obsolescence And I want you to think about how those impact your architecture So don't just don't just say I need to support ie6. That is an assumption I want you to really think about What how much of your architecture is based upon these particular assumptions I want you to periodically review the decisions that you're making As a result of these assumptions and I want you to make your choices More intentional when you think about Whether or not you're going to do something or not I want you to really think about what assumptions are going into that and I want you to document that I want you to help contributors To your project or to an open source project make decisions without fear that they're walking on a grave Thank you very much Josh, do I have time for questions? My clock says 30 something minutes We do have time for questions and I'm going to start Okay How about the test suite as a place to track cruft? Uh Someone else asked me the question the last time I gave this spiel So I think the test test suite is a good place to track cruft and I think for every piece of cruft that you have There should be a test However, I think the the point that I'm trying to make is there should be a place where that's the only thing that that's Things job is right. So there should be a file where the job is Here is a list of assumptions and how they affect architecture and not I am a new user I'm going to run the test and see if they fail right. I think that's important It's important that if there is ie6 needs to be supported that you have tests that check for these ie6 bugs very important So I can think of more than one occasion where I've been writing code to work around a bug or something like that That I knew would eventually get fixed and I wrote a test to Make sure the bug was still happening. Yeah, I think that's when it didn't happen It would fail and tell me take this code out. Yeah, so I think actually that's a really good strategy for things like ie6 bugs Less of a good strategy for my users happen to use some version of microsoft project that has this bug We don't necessarily always test all those things. Maybe if we could test all of them, it would be great But yeah, I think there's you could sort of break what I said into two chunks There's assumptions that are essentially code assumptions there ie6 does this weird thing or Ruby 1 8 does this weird thing and then you can I think you could really nail those with tests And then there's a whole other set of assumptions which are just human assumptions things that my people my Like in my first project the fact that everybody's all the contractors still use fax machines Right. I can't really write a test about that, but it is a core assumption. We had a lot of fax code Okay, good good points. So other people questions I always got to work out at these things so there There are some Parts of your talk particularly early on that sound a lot like overfitting training data in machine learning Is that a thing you've thought about is related to this? Do you? Do you deny the connection or accept it or? Uh, can you say more sure so in machine learning you have I know what overfitting means okay draw the yeah, okay, so In machine learning the overfitting is you take some training data and your solution is too perfect to that training data so then when you try it on a Extension set a real set of data. It is no longer valid And when you put your graph up at the beginning of when you draw when you write the code event at first The cruft is exactly a one-to-one fit to the current model of the universe, but that model changes over time so maybe In machine learning what you want to do is take like a slightly worse hit on on training right write a less than perfect solution Is that something that could help us write code like accept a slightly imperfect solution as a longer term more stable solution? Yeah, I think especially so interesting connection I think especially in so far as We're talking about things where the trajectory is predictable People will use less ie six over time right Turns out to be true People will use less of some current browser over time You can perhaps be less perfect although in a lot of those cases you are forced to solve the bug for ie But perhaps you can isolate it better. You can project. I think I think that's a good solution I think the tricky bit though is that it's not that it's too perfect For some set of data. It's perfect for now, right? So you actually do want to write code that's Perfect for now if there's a trade-off between Perfect for now and good enough for later definitely take the good enough for later trade-off Sometimes it's just like does it work at all right now? And I think to the extent that that's an important question I think we should solve the problems that we have today, but we should make sure we understand What that's going to mean tomorrow if this assumption is no longer true. How does that affect the code that I just wrote? There's somebody all the way up there Uh, so like you said, uh, some of the things assumptions get too outdated And since we are all operating in the open source world and not as big as apple Uh, and like apple said, we are not going to allow any flash play on iphone So when do you make that kind of a jump by saying that now ie6 is no longer a feasible option? Or the gap is too huge that it's going to take more Work to support ie6. And when do you make that? Sort of a judgment call and remove the old assumptions that are no longer valid And the second part of the question is how do you measure? And bring come out with this data of how big the gap is so that somebody can make the decision of removing that support So I didn't really understand the first part of your question. Um, I can answer the second one So I think thinking about measuring the gap is not Right, I think the the point that I'm trying to make is there are some assumptions and you could intuit You can understand that there is a gap that grows between the assumptions that you made when you wrote the code in the first place And the reality sometimes things don't change a lot, but in the fields that we're in things usually do change a lot So in fact depending on how On how close the solution you wrote was to specific assumptions There's going to be a different amount of gap. So I think it's it's more of a human question, right? So human you haven't usually usually the answer is a new guy came into your project And he's asking some uncomfortable questions, right? So someone came into your project and he says, why are you doing it like this? That's a pretty good time to say Okay, we did it like that because we supported some old there was a bug in some old version of flash that we needed support Is that still valid? There's a there's a some code in rails that I think might still be there It's like safari 2 didn't strip out Spaces at the end or something and like adds a null byte, right? So it's not those cases aren't urgent But presumably every time when someone new comes in and goes through that code They may notice it and it's good to know what the answer is, right? So the point I'm making is if you don't know the answer to why you're doing something the answer is going to be Please don't touch that um Hopefully the lesson takeaway from here is try not to have the answer ever be. Please don't touch that Try to have the answer be Here's the reason why it is and the assumption is still valid or it's not valid anymore Are you are you leaning by example in this case and uh doing this on ember Or some other project where we can look at how it works out in reality? Yeah, good question. So, um I don't have a cruft.txt, but we do have um architecture files that talk about the architecture and the reason for them After writing this talk if I have some more concrete specific things to do and I definitely think that this is a good idea And people should do it I um the The lesson came from jQuery where I saw the amount of work that it took to reverse engineer what should have been cruft.txt and um I think that's always possible and that's what you should do five years in if you're stuck But I yeah, I mean definitely gonna I'm definitely going to be a lot clear in the architecture Files about what the reasons are for doing specific things going forward Uh, that's it for now. Thank you very much. Thank you