Code with Jason

318 - Adam Dawkins, CTO of Dragon Drop

Use Left/Right to seek, Home/End to jump to start or end. Hold shift to jump forward or backward.

0:00 | 52:59

In this episode I talk with Adam Dawkins, CTO of Dragon Drop, about building internal tools using Ruby on Rails, the challenges of growing codebases, and how to effectively manage design and technical debt. We explore abstractions, code quality, and the philosophy behind good testing practices.

Links:
- Dragon Drop
- adamdawkins.com
- Adam Dawkins on LinkedIn
- Nonsense Monthly

SPEAKER_01

Hey, it's Jason, host of the Code with Jason podcast. You're a developer. You like to listen to podcasts. You're listening to one right now. Maybe you like to read blogs and subscribe to email newsletters and stuff like that. Keep in touch. Email newsletters are a really nice way to keep on top of what's going on in the programming world. Except they're actually not. I don't know about you, but the last thing that I want to do after a long day of staring at the screen is sit there and stare at the screen some more. That's why I started a different kind of newsletter. It's a snail mail programming newsletter. That's right. I send an actual envelope in the mail containing a paper newsletter that you can hold in your hands. You can read it on your living room couch, at your kitchen table, in your bed, or in someone else's bed. And when they say, What are you doing in my bed? You can say, I'm reading Jason's newsletter. What does it look like? You might wonder what you might find in this snail mail programming newsletter. You can read about all kinds of programming topics like object-oriented programming, testing, DevOps, AI. Most of it's pretty technology agnostic. You can also read about other non-programming topics like philosophy, evolutionary theory, business, marketing, economics, psychology, music, cooking, history, geology, language, culture, robotics, and farming. The name of the newsletter is Nonsense Monthly. Here's what some of my readers are saying about it. Helmut Kobler from Los Angeles says, Thanks much for sending the newsletter. I got it about a week ago and read it on my sofa. It was a totally different experience than reading it on my computer or iPad. It felt more relaxed, more meaningful, something special and out of the ordinary. I'm sure that's what you were going for, so just wanted to let you know that you succeeded. Looking forward to more. Drew Bragg from Philadelphia says, Nonsense Monthly is the only newsletter I deliberately set aside time to read. I read a lot of great newsletters, but there's just something about receiving a piece of mail, physically opening it, and sitting down to read it on paper that is just so awesome. Feels like a lost luxury. Chris Sonnier from Dickinson, Texas says, just finished reading my first nonsense monthly snail mail newsletter and truly enjoyed it. Something about holding a physical piece of paper that just feels good. Thank you for this. Can't wait for the next one. Dear listener, if you would like to get letters in the mail from yours truly every month, you can go sign up at nonsense monthly dot com. That's nonsense monthly. I'll say it one more time nonsense monthly dot com. And now without further ado, here is today's episode. Hey, today I'm here with Adam Dawkins. Adam, welcome.

unknown

Hi.

SPEAKER_01

Tell us a bit about yourself.

SPEAKER_00

So I'm CTO at a company called Drag and Drop, based in the UK, and we build internal tools for clients, usually in Ruby on Rails. And I've been doing that for we started the company 10 years ago, so we've been doing that for 10 years now.

SPEAKER_01

And what exactly does that mean, internal tools?

SPEAKER_00

It means that the things we build are typically used by companies in-house rather than necessarily being customer-facing. So it's kind of like bespoke CRMs or full work platforms, like really trying to solve the nitty-gritty internal problems in a way that maybe SaaS can't.

SPEAKER_01

Yeah, that's interesting. Because I've worked on a lot of that kind of thing in my career. Um, but I'm not sure how one would like intentionally attract that kind of work. Is there a specific way that you get clients who are needing that kind of work done?

SPEAKER_00

It's interesting. For a while, we found that starting by helping people on an airtable was a really good place because they'd already started to explore the idea that maybe technology internally building our own thing could could help.

SPEAKER_01

Yeah, yeah. I um, you know, I tried to do this, I'm remembering now, maybe like ten years ago or something like that. I um I get I guess what the kids would call it today is catfishing. Uh I I did like a uh I started a a meetup for uh Excel users, thinking that I could attract people who are using Excel for business workflows, and then uh that could be automated using software. That scheme of mine totally didn't work, um, but it was a a similar objective.

SPEAKER_00

Yeah, Airtable had the advantage of it was the step beyond Excel, right? So they'd already started to try and sort of maybe think of relational databases or or something, and then get stuck in the limitations. We hit it at a good time. Airtable now has loads of UI tools and ways to try and keep you there. But at the time, I think around 2020, when we were sort of haunting the forums, they there was less of that. So as soon as you needed a nice form or something with a little bit more customization, you needed to branch beyond it.

SPEAKER_01

And you and I were talking pre-show about Ruby on Rails and how it is really helpful in the early days of a project, gives you a lot of leverage, but then once you get a ways in, I don't know what you'd call the milestone, like uh six months, a year, something like that. Once you get a ways in, it gets a bit harder. Um, the way that I usually characterize it is like Rails gives you these slots for you to put code in. Um it gives you controllers, models, etc. And in the beginning, it's very clear where to put things. But then as the project gets bigger and bigger, it becomes less clear where to put things, because just stuffing things in those existing slots works out less and less well. Does that characterization seem to match the way you think about it?

SPEAKER_00

Yeah, I think so. I think it's those models getting bigger and bigger and bigger, right? And I remember Gary Bernhardt once saying you have two choices. You have like fat model, skinny controller, or fat controller, skinny model, but it's the same problem.

SPEAKER_01

Interesting. I disagree with that framing, but I I think we can get into get into all that as we go. Um yeah, and and what I found is that a lot of people have have experienced this same feeling, even if people might express it different ways or they might not even consciously think about the fact that that is what they're happen that's what's happening. But the way that I look at it is like Rails as a framework gives you, again, places to put your code and it gives you leverage and stuff like that. But eventually you kind of run out of framework. People feel like they run out of framework, and so they want more framework. Uh, but to me, more framework is not the answer. What you need is design, and there's there's a whole that's a huge, huge rabbit hole that we could spend really a lifetime talking about. Um, but I just wanted to toss that out there. That's that's how I view it. Um but how how do you look at that? Like once you run out of framework, what do you do?

SPEAKER_00

I think Rails kind of has this problem where it's so opinionated as well, right? And the convention of a configuration that it's it's not only that you want more framework, it's kind of telling you to take more framework because it's not encouraging you to think about your design at all. It's saying just use this. It's ready to go, just scaffold it, you'll be fine. It's kind of the default. I know they always have the caveat of you can do whatever you want within Rails, it becomes a lot less, you lose a lot of the benefits very quickly when you when you do that. Um but yeah, so that's interesting is that I think that there's it's kind of this world of no design once you hit that limit. Whereas maybe in other frameworks, you already had to think of a design on the way in.

SPEAKER_01

Hmm, interesting, right? Yeah, and side note, what I encourage people to do sometimes, which I've done myself and I've found to be a really fascinating and helpful exercise, is to build a program in just Ruby. And not even a web application, just some kind of command line program or or whatever. No UI, it's just Ruby. That's literally all there is. No HTML, no JavaScript, no web, just Ruby, and that's all. And what that does is if your program lacks design, there's nowhere for that lack of design to hide. And so what what you made is all there is, and I think that could be a really uh educational exercise to go through.

SPEAKER_00

I agree, and I think the other I encourage people to do that, and the other um thing it shows is you you find out which parts of Ruby are actually Rails. Um because most people I would say come to Ruby through Rails nowadays, and you realize that oh, present isn't a thing that's available, or oh, atta readers are actually this thing, and they're different to Atta accessors and whatever it is. Things that and that might and that's how Rails is doing some of the stuff that it's doing with say columns on on models and things like that in a way that's just very hard to tell from the outside if you've only worked in in Rails.

SPEAKER_01

Right. Yep, yep. I've definitely had that same experience. Um, and then you know, you can take your learnings back to Rails and and give your application uh more design. Because I guess you know, it's maybe the problem is that most Rails applications, it's probably true of most applications in general, they're just not consciously designed. And you can get away with that for quite a while. Because it's like I have a form and it has these fields, blah blah blah. There's these uh uh what's the word associations between two models. There's kind of only one way to do it, you know. If if you have two associated models, you put a has many or whatever line in one of the models. It's kind of the one and only way to do it. There's not a lot of room to do it in a way that doesn't make sense. There's up you you you don't have to bring your own design. Um so you might work on an application for six months or a year with no design, and then this lack of design just continues indefinitely, and you have a a big ball of mud. And and that's not Rails' fault. Um but you you still need to uh confront it somehow and do something about it.

SPEAKER_00

Yeah, and I think something I've learned over the time of we've got these like growing applications that are getting bigger and bigger, is that it's not a bad thing that it ended up in this position. Because if I only needed that one form, it would have been crazy to think about all of the design and all of the problems we might have. And I like to think about why do we need design? And it really comes down to that we need to edit the code, right? Like if you were going to write an application that you are definitely just going to write once and never change, we could use go-to's. You could say go to line seven, and line seven would always be that line, so it's fine. So design comes through the passage of time, the increasing domain complexity, the increasing technical complexity, and also for us, for example, the size of the team. I need less design when it's just me, actually, because I hold the design in my head that might not be visible in the code. I may know that I have this section of the model, does this stuff in my mind, and I put the other stuff down here in a lower section of the code. But when you have six to eight developers on a project or maybe more, the design needs to become more formalized, I think. And we need to. And it's strange because it it can slow you down in the act of writing new code versus just generating another or just adding another column to the model. Let's just add more things to the model is is quicker, but it's only quicker for right now for writing that piece of code. We've actually made the overall progress harder. And so I think that context is quite important. When you ask about design, design isn't art, there has to be a reason for it. And so, what are we designing for? And I think for me, it's in some of our larger applications, it's designing for just trying to segment some of these huge conceptual contexts so that maybe I can work on this area without having to think about all of the areas, or we're designing to make things easier to edit in the future.

SPEAKER_01

Exactly. I I think you're hitting the nail right on the head. I I had Dave Farley on the podcast some time ago, the author of this book, uh Modern Software Engineering. Um, and I asked Dave a question that I like to ask people, and maybe before I tell you Dave's answer, uh I'll I'll ask you, Adam. Um the question I like to ask is what is good code? What's the difference between good code and bad code? What does it mean for code to be good?

SPEAKER_00

I think it's like Sandy Metz has this line, right, that your code's going to be read a thousand times more than it's written. So that readability and then the editability for me is the is the key. And I think what we've seen a lot is I kind of call it like the CSS efication of objects where it's if you remember the days of before Tailwind, I guess, of just writing CSS, you'd try and edit something, it wouldn't change it, so you'd just add your classes at the bottom, just keep adding more. My bit works, and I've added important, I've added loads of whatever it is, and I think there's a temptation to do the same is I don't know where to get into this thing, so I'm just going to add more stuff, and then nobody knows if the other stuff's still used or whatever. So I think it's that ability for it to be edited to sorry for a rambling answer. That would be my answer for good code.

SPEAKER_01

Well, that's exactly what Dave said. He used slightly different words. I asked him what's good code, and he immediately said it's easy to change. That's that's what good code is. My previous answer was code that's easy to understand and change, and Dave argued that uh saying that code that's it code is easy to change subsumes easy to understand. Like if it's it has to be easy to understand in order to be easy to change. So all you need to say is easy to change.

SPEAKER_00

Yes.

SPEAKER_01

Yeah. Um, and it's funny, like, programmers talk all the time about like good code and shitty code and stuff like that. But how often do you pe do you hear people talking about what good code is? Like, what does that mean? And most of the time when I ask people, they don't have something off the top of their head, and often it's something that is uh, if I can say wrong. Um it has something to do with like crafts craftsmanship, professionalism, that kind of thing. And that's not it. Um and and to be fair, I myself, for the first 10, 15 years of my career, didn't have an answer to that question. I never thought about it. So I I I think part of moving the programming profession forward is getting people on the same page of this very fundamental question of what is good code.

SPEAKER_00

I like to think about, I thought about this last year of like which verb do we use for coding, programming, developing what's the verb? And I think the key is that we are in a form of a writing profession. And almost every other form of writing will allow drafts, throw that away, rewrite it, edit it. We work in code editors, not code writers, and I think we that's the key, is that it is just text. I say it to my team quite often of this will do for now. It's it's only text. We can move it later. And I guess that's another side of good is good enough is sometimes the right level of good right now. Um and that doesn't mean I think there's some standards to that, maybe some qualifiers. It's not just write something that works and that'll do, but that sometimes with the design the best design decision might be to wait on the design, let it emerge. Or and sometimes it's the opposite. Sometimes the the famous Kent Beck quote, I guess, is make the change easy, then make the easy change. Sometimes we have to do that now, but I think sometimes it can wait. Sometimes there are um and we see this as an agency, we have clients, we have this pragmatic. I don't like the word pragmatic so much because people can use it to hide a lot of things, but it's finding that tension between value now, value later, what does the client need now? How much is it gonna cost them in the long run? How much is this gonna cost us in terms of editability later? And back to my point about how everything could be go-to's, if you're writing something that's very niche with very low churn, you can just leave it when it works. If you're adding something to something that's right in the center of your application or is going to be very fundamental, that might require more more of your design time.

SPEAKER_01

I love the directions you're going with this. Um, and I want to pull on some of these threads. Um I've been working on this book. Original title was The Philosophy of Programming. I've changed it to uh Software Design from First Principles because I think that's a more marketable title. Um I I don't want people to think it's just a bunch of airy thinking that that doesn't apply to reality or something like that. Um, because I want to think about these things precisely because they apply to reality and have very practical benefits. Um there's there's two concepts that that I put in the book that I don't hear people talk about very much, but I wish people would. And I think these two things will resonate with you because it's kind of just putting different framing around things we already know, but maybe we don't always frame them this way. I hate the concept of technical debt. I I think it's a corrupt metaphor. It it like almost fits, and it kind of works sometimes, but it it really is the wrong thing. Um because nobody ever pays back technical debt. Like that that just doesn't happen. Um when you buy something on the credit card, you gotta pay it off in like a year or whatever, or else you're screwed. People always do that. Or I mean, you know, that's most people pay off their debts. Uh but in programming, it never gets paid off. At most, it gets like a little bit paid off in five years by different people or something like that. Uh anyway, I use a metaphor of dull blades and sharp blades. Right. And that kind of relates to what you're talking about. Uh uh sometimes pretty good is good enough and stuff like that. And there's a question of when do you sharpen a blade? Like maybe pick up a blade, try to cut with it, and you find that it's dull, and then you know that it's justified to make an investment in sharpening that saw because you you just tried to cut with it, you know it's dull, so it's like, okay, there's a strong case that if I take a little effort to sharpen this blade, then I can cut faster with it. Which brings me to my other uh uh metaphor that I not metaphor, my my other framing that I use, which is um bets and and economics and stuff like that. Um every piece of code that's written is a bet, uh and it's an investment. And when you do a refactoring, you're basically saying, I'm making a bet that on average all of my refactorings are gonna have a positive return. I don't know that I don't know for sure that this refactoring will have a positive return, but I decide whether to make each bet or not uh based on my overall investment portfolio that I expect to have a positive. Positive return. So I just wanted to toss those two framings out there because they seem very related to the things that you're talking about. I wonder if that stirs up any thoughts for you.

SPEAKER_00

Yeah, technical debt is one I've been struggling with as a concept, because we're an agency, we have to forward these refactorings, the cost of the perceived cost of refactorings, we have to charge for our time, very simply. And so some of the argument came down to we went really fast then to solve the problem then. The problem is different now. And almost by definition, if you're going back, if you're running into a dull blade, it's because you were going back to it when maybe you didn't think you needed to, right? I I guess where I don't like the blade analogy so much is it was always dull. It's not like it's got duller, it's just that it was as sharp as you needed at the time, maybe, and now we needed to do something else. Um but the tech dit one's interesting. We recently, someone on our team ran through all of the to-dos in our like seven-year-old repo, and it's almost like any code that still has a to-do above it from five years ago is totally fine. Because we would have fixed it by now. It was like this weird thing where the to-do became this badge that it's probably okay rather than it needs changing.

SPEAKER_01

It's very interesting.

SPEAKER_00

The to-do is so old that it obviously doesn't need doing because it's still there. The code's surviving, it's okay. Um I think my extending thought to this, sorry if it's a bit tangential from yours, but is that I don't think in a in a real application that you're still working on, you're never gonna be 100% happy with all of the code all of the time, and we can make steps in a new direction, but we're very unlikely we're gonna have the space to move all of the application at once into that new direction or that new design pattern or that new way of doing things. We're gonna move piece by piece, and there's always gonna be some stuff that's dragging behind. There's still gonna be some dull knives. We've sharpened some of them. Um and we'll we'll sharpen them when we start using them, maybe.

SPEAKER_01

Um, okay. I I'm I'm birthing a new metaphor in my mind right now. Um so so I I was watching this video recently uh just about like the very basics of calculus, because I'm trying to relearn all that stuff. Uh because uh incidentally, I finally actually need to do some math in my real job, uh like 20 years after learning it in college. So I'm going back and trying to relearn it because I never really learned it all that well in the first place, to be honest. Anyway, I was watching this calculus video, um, and the examples he used were the physics ideas of position, velocity, and acceleration. So you can have a particle's position and make a graph of that over time, take the derivative of that and it tells you the particle's velocity over time, and then uh take the derivative of that and it tells you the particle's acceleration over time, the rate of change of these things. Anyway, the reason I bring that up is because I think this snapshot of a code base at any particular time is like the particle's position. Um and that uh it like matters, but what matters more is the velocity of it. And of course, I don't mean the velocity in the terms of like agile velocity or something like that. Um but if you this is this would never be possible, but if you could somehow make a graph of the change of okay, if if if we treat a particle's position analogously to like a code base's quality, defining that as like the ease of changing the things you need to change in the code base, um what would that graph look like? Uh the the velocity of the um of the um quality of the code. Is it going up or is it going down? And to me, that graph of whether the quality is going up or going down is a much more important graph than the one that just charts the position based on snapshots.

SPEAKER_00

Yeah. I think I agree. I do agree. Yeah, that makes sense.

SPEAKER_01

Yeah. Um and let's see, you were talking about yeah, the the thing that inspired that thought for me is you're never gonna be happy with the way everything is in a code base. And I think you know, I I totally agree, and I think it should be said that like having being being satisfied with every nook and cranny of your code base is not the goal, and in fact, to do so would be extremely wasteful and unwise.

SPEAKER_00

Yeah. I was thinking about this, like, even if a client said, just take this whole year, refactor whatever you want, you still would want to do that incrementally, have it still used in the real world. You wouldn't necessarily want to just change everything, but also I think suddenly that thing that I'd love to do becomes quite boring to me because it becomes an academic exercise now. Right it becomes let's refactor some code because I've read Martin Fowler's refactoring and I've memorized some of the recipes or whatever it is, it just becomes a fun little coding exercise. But most people I know who are into software, they they want to build things that people use. And so that changes the dynamic of what's important a little bit. And I think that then knowing that by refactoring this, this is gonna be easier. And there's another user, actually. I thought of this, the other developers on my team are the other user of the code, not just the end user of the product. So by refactoring this, I make a cleaner break here, which is gonna make it easier for somebody to either edit or not have to read to understand something else they're changing, might be the other dynamic of the change.

SPEAKER_01

Yes, exactly. Uh there's so many thoughts swirling around in my mind based on uh what you're saying about these things. Um Yeah, the the code has two jobs. One is to function and the other is to be changed by other people. And that's why I'm always so frustrated when somebody says something about uh a piece of code being really poor and somebody's like, well, does it work? And it's like, well, define work. It's like, yes, it works in the sense that it it carries out the function that it needs to, but that's not its only job. Its other job is to be changeable, and if nobody can touch it because they're afraid to, because nobody can understand it, and they don't know what side effects that any particular change might have, then the answer is like no, in that sense, in that sense the code doesn't really work.

SPEAKER_00

I also think back to my extended analogy of why not just write go-tos and have it all in one file, nobody would agree that's a good idea. You don't really mean, well, if it works, it's fine. What you might mean is maybe it's defensiveness, or maybe it's uh a counter-reaction to people being too purist about some things, or it's things you haven't encountered before. Right? And that's the challenge, back to I guess our original sort of opening, that's the challenge with when you add design to Rails, because you may employ or bring someone in who's a Rails developer, but the other concepts you add, there's no guarantee they know what those are or how those operate or what you're trying to achieve. Because if I'm a Rails developer, I know they know model, I know they know controller, I know they know view. I'm oversimplifying slightly, but the rest you don't know if somebody's going to understand this other design concept or this other principle. And it can be quite scary for people because they don't know this other world of software design, and that actually it's got a history, and that the uh the old ideas, it's quite a young profession actually, but the old ideas, it's how can I say this better? It was interesting to me when I read Martin Fowler's book on refactoring, because the idea that every possible refactor you can do has actually got a name. It's like uh it's like learning sheet music or or music theory, so that I know that when I put my hands on these three notes on the piano, it sounds really nice. But actually, if we can talk about that as a C, we can save a lot of conceptual time because there's a pattern for it. And then you could go up another level, maybe like jazz musicians, where they're talking about just playing like a 1-5-2, and they've actually abstracted from the notes you're actually playing altogether. These abstractions give us more bandwidth to think about other things, but if you don't know the concepts, it's very confusing all of a sudden. Because I don't know what notes to play now. When it was just model view and controller, I knew where to put my things because they've only given me three buckets to put them in.

SPEAKER_01

Yeah, and it's very helpful to have that shared vocabulary with the people you work with. Because like if if I'm you know, I I play music myself and I've uh played with musicians of different um levels of familiarity with music theory. And when you when you play with somebody who's very familiar, it becomes so much more efficient because it's like, okay, we're gonna do like a 145 chord progression. It's like, oh okay, I know I know what that is, and and you just jump right into it, and and you don't need to spend a lot of time being like, oh yeah, okay, so it's gonna be a C, then an F, then a G, and blah blah blah, and and you can just get it and go. And so, yeah, that's that was a wonderful revelation to me, too, reading that Martin Fowler refactoring book and discovering that all these things have a name.

SPEAKER_00

Yeah, but trying to get those names shared, I think, would move programming forwards. Uh because it's it becomes that vocabulary that makes it easier to talk about. And I think it's the same thing that happens with writing good code. Actually, one of the things that can make it easier to edit is if I've got these eight methods on this 900-line model, and I can pull them out into something that describes what those eight things do with regards to each other, I can move that out of your attention. We don't have to think about in the same way we don't have to think about which note we're gonna play next. I only need to look there if I need to look there. I only need to worry about that later, which is a big appeal to me of some little classes that do one thing well.

SPEAKER_01

Right. Yeah, and what you're talking about, of course, is the concept of cohesion. Um things are cohesive. I I just read this the other day in that uh Dave Farley book. Um things it I'll butcher it, but things are cohesive when things that belong together are placed near each other, something like that. Um sadly, quite a lot of Rails applications do the opposite. You'll have you know the famous user model where it's just a dumping ground for anything that could possibly be related to a user, has very low cohesion because there's there's no grouping of things that are related. Maybe they're grouped in in sequence, they're placed next to each other in the file, but the file itself is just a mixed bag of a bazillion different unrelated things. And like you said, if you can identify those groups of things that are related and move them to somewhere else, then you can say, okay, we're presenting a certain high level of abstraction, and you can see the the high points of the story, and then if and only if you're interested in a lower level of abstraction, you can go over to this other place and see the details of that here.

SPEAKER_00

Yeah, I have a concrete example, I think. On one of our applications, um, there were sales reps on it, and there's commission. And the commission calculations ended up being a hundred lines of Ruby because that's how they calculate commission. I consider this this is domain complexity, not technical complexity. This is just that's what their commission is, right? It's based on all of these factors. And I made it into a class that takes all of the raw inputs it needs from the model. And there was some pushback at the time because you could do those calculations on the model. But what we got from this was many of our team have had to call the commission calculator at some point, but the commission structure hasn't changed for a few years, and that's nicely tidied away in this file. And then you get some of the other benefits as well, which is I can test it with numbers. I don't need to test it with setting up databases and all of this. And actually, I did a weird thing with the tests on that, which is the client really wanted to make sure it worked, and he gave me other examples. Now, as a developer, I'm thinking these are the same examples. It's you we're really just testing if the multiply symbol still works in Ruby. But I add I have a section with his name and all of the examples that he raised, because then it's like every time this thing goes live and we run CI or whatever, all of those examples still pass. They're all still the same. It definitely still works, but that thing's now abstracted away from the thing that calculates it, and then over time commissioned bands came in and some other things came in, and this calculator still just says, give me all the numbers and I'll do the math. And I think that's just such an important abstraction that can save us from a lot of pain, and then where it gets difficult with Rails is it's like I could have summed some of these things with SQL, but actually the volume rarely calls for that, at least in the applications I've worked on. And I I will take the slight performance hit of a Ruby sum for the clarity of the maths is over here and the data's over here. That just is my example at least.

SPEAKER_01

Yeah, that is a beautiful story, and I I hope a lot of people can take away a lesson from that. Um, and the the testing aspect of it, where you don't have to bring in these database dependencies and stuff like that. It's it's so great. It's and it's a very practical benefit. You know, it's it's not just um it's not just satisfying from an artistic standpoint or something like that. There's a practical benefit to not having to pay the price of doing all this all this database stuff in those tests. Um Yeah, uh I think that's great.

SPEAKER_00

I have a I do have a pet peeve with tests. Uh we actually have um I have a derailed tag in my Rails app now, which is all the tests that can run without Rails. And I can get 45% code coverage in like two seconds. And the rest, okay, it's only testing kind of some of the services and these things like this commission calculator and things like that. But it's also this thing of I read some tests and I think we're testing if Active Record knows how to do SQL again. We it's like this, it looks like a unit test, but it's actually this big integration test just in case Rails has stopped knowing how to interact with a database, and it just seems like a strange boundary to me. And it's been but it's been a lesson I've had to explain to some of my team where it's but what if it doesn't save? And it's trying to explain, yes, but that's the responsibility of the model. And and Rails does know how to, it's been writing to databases since version one, it'll get there, you know, and that we don't need to test that from all the way over here in some operation or some request spec or something. I'm quite like understanding what we're testing and why we're testing it seems to be lost. It's I need to write some tests so that the things protect.

SPEAKER_01

Right. Yeah, uh, I'm very familiar with that uh kind of uh phenomenon. Um a lot of people write tests just to be able to check the box that says I wrote tests, um, and they don't completely understand why they're writing tests and why you might write a test for one thing and not write a test for a different thing, and and and so on. And I myself was absolutely that kind of person when I first started, partly because there's a lot of really bad testing education out there that shows you examples uh of here's how you write a test, and it's a completely pointless test. Like, assert that it responds to such and such a method. It's like, okay, you're just asserting that the code he wrote is the code he wrote, like, of course, like that test can never fail. Um and and so what do we write tests for? What's the point of writing tests? And and Uncle Bob said something like um testing is not about verification, it's about specification. So I think people get confused uh between the idea of so so test is a terrible name for a test. We shouldn't have called them tests, we should have called them something else, maybe specifications. Um because the the confusion is between like if I want to manually test a website, maybe I'll like go visit a certain URL and make sure that it loads. Like, all right, I got I'm giving a conference talk and I have to use this website uh ten minutes before I'm gonna go test and make sure this works. I'm gonna hit refresh a few times and verify that it works. But that's not what automated tests are about. We're not testing that it works, we're making assertions about how it works. And I think it's it's a subtle distinction. And I think it takes a lot of people a long time to understand that that distinction, but it's a night and day difference.

SPEAKER_00

Uh if you're sorry. For me, it's uh well, I do TDD, and so that changes what the tests are for, because I'm designing with the tests, right? And I have this thing where if you had to set up 20 models to write your request back, you had bad design in the first place. And I think that holds with our definition of design because that's gonna be hard to change if it needs that much in place, right? But also testing clarifies what your intention was as a developer. So if you create an an add method and you've written in your test, it like it makes sure that like it tests that two times two equals four, and then you've written a plus sign instead, and it's still four, and then it breaks later. I know that you I know which thing's wrong. Because you it's maybe a bad example, but it's like how the sum and the multiply will will end up at the same value. But I know which thing's wrong because you've at least described what you were trying to have the thing do in the test. The test tells me what we were trying to do as well, you know?

SPEAKER_01

Right. The tests are the ultimate authoritative source of truth, not the application code.

unknown

Right.

SPEAKER_01

Yeah, the application code shows you what the application happens to do at this moment, but the tests show you what the application is supposed to do.

SPEAKER_00

Yeah, and I think that's where I like that analogy of you wrote an add method, you accidentally put a times in there, and it passed on your one test of two plus two because it did two times two, but now I add another test with the same idea, and two plus three doesn't work because it's returning six, and now I can feel confident that I can I can change it. Unless it's really old, and then I'm scared, right? Because everything's leaning on it, and we now have to be careful.

SPEAKER_01

Right. Yeah, and everything is is in question. Um yeah, and I want to uh go back a little bit to something we were talking about earlier regarding abstractions and stuff like that. Um that's the section of my book that I've been working on the most recently. Um talking about what an abstraction is. Um because a lot of people I think have the idea that an abstraction is like a uh generalization. You take two things that are similar and then you factor out an abstraction. It's more abstract, it's more general. And that can be true, but that totally misses the point of abstraction. And so I give a lot of examples of abstractions that have nothing to do with programming, and this led me in unexpected directions, and it made me realize that I didn't really understand abstractions myself. Um and so kind of the main example that I used was a wave, like a wave in the ocean. Um a wave is a physical entity, yet it's not made out of any particular matter. When the wave crashes on the shore, it's different water than the the water that the wave started out with. And that's an abstraction. And we humans have all sorts of abstractions that we use in order to compress these complex things in the world into tractable ideas that that we can more easily think about.

SPEAKER_00

Yeah, I think that type of abstraction what it does is it reduces complexity, right? Like trying to hold all of the particles of everything that went into a wave in your brain as one thing is very complex to think of. And you call it a wave and you've named it at a um and a level of detail that you need. I think that's what's good about abstractions, is it's let's put let's name something at a decent level of detail, and then if I don't need the details, which are often I don't when I see a wave, I don't need the details of which which bits of water it landed as, you know, then I don't need to go into the details. And that's like my commission calculator, right? If you don't need the details, you don't need the details. You've got a thing that's that's abstract.

SPEAKER_01

Yeah, exactly. Um and like I'll I'll just toss in another example because I had a hard time with this concept of abstraction. I still do. I I think it's a hard, a hard concept, and there's a lot more to it than it might seem at first. Um but anyway, another uh example is a crowd. A crowd is an abstraction because it's a collection of of individual people, but when you're talking about a crowd, you probably don't care about the individuals. And not only is it easier to understand and and work with when you when you throw away details, um, but the details is just not the same thing. Like if I am surrounded by a group of people and I regard them as individuals and nothing more, and I don't zoom out and regard the crowd as a distinct entity, like those are two different things. It's it's not just giving a new lay label to the same thing, these are two different things. Um and and that's another another way that that abstractions are useful, and a very significant fact is that abstractions can be combined and nested, and then they become very, very powerful, and they can be broken down also. So coming back to the Rails stuff, uh a lot of Rails apps have very little design, and there are no abstractions beyond the active record models, but that leaves such an opportunity on the table because there are way more abstractions that can be usefully conceived of in a program than just the few abstractions of your active record models.

SPEAKER_00

Yeah. Yeah, that makes good sense.

SPEAKER_01

Like your commission, I I think that that's an example, probably.

SPEAKER_00

And if you think as well, like what you said about the different properties, is that if you had a crowd class, it has different methods to the people that are in the crowd. Like a like a crowd can, I don't know, rise or boo or they could I can't think of a good example, but the crowd can be something more. Like I'm thinking of when I'm at football, I guess you'd call it soccer games, where I have the reaction of the guy who sits next to me, but then it's like the crowd was furious with the ref. It's kind of like a different emotion.

SPEAKER_01

The crowd went wild.

SPEAKER_00

Right, and it's probably on average as well. Not everyone stood when I say the crowd was on their feet, you know. Yeah, it's got these like things are broadly true about this thing. The only negative I think about talking about these real world abstractions is that I think it's um this is a completely different topic, so we can go back if you want, but it's it's a little bit for me the lie that object-oriented programming teaches that that it's gonna be it's all gonna be real world stuff, you know? So you have like a dog class, and then it extends mammal, which extends animal, or then you then you have like an abstraction in your application and it's called like a thing that does this, or like a so you have these concepts like repository, and you're desperately trying to keep it as it's sold as you know objects, so you'll know object-oriented programming. And then I watch someone like maybe Sandy Metz or someone find a really good abstraction, but it's not a thing, it's a set of behaviors or some messages that can be sent that breaks that kind of tangibility of objects that I think sometimes we're always trying to find what would I call this this thing, and I haven't found a solution. I did see that Gary Bernhardt tends to name things as verbs a little bit more. So maybe instead of a commission calculator, we'd have calculates commission or something, and it kind of gets away from having to make everything a thing, but then I guess it's drifting more functional. I I don't know.

SPEAKER_01

But yeah, this is man, we we are nearly at the end of the hour, which makes me so sad because I want to dig deep into this one, and and maybe we can uh on a future occasion, but um I I see so many classes, okay. First, first, first, the uh teaching of like dog and cat both inherit from animal and stuff like that. Um that is it it's like the quintessential uh object-oriented programming 101, which is so frustrating because it never exists, right? Yeah, it's so misleading. It it suggests that what you're gonna be doing in object-oriented programming is taking these real-world ideas and replicating them in the program, which like maybe sometimes uh like I don't know, customer or something like that. It's like, yeah, sure, that's that's a real thing. Um but that's only like half of it, and maybe even a lot less than half. There are other abstractions worth making, like this commission thing. Um, it it breaks my heart when I see things like no offense, a commission calculator or calculate commission or something like that. To me, it's just commission. It's a commission and it has a value. And you can say uh in initialize a commission with these certain arguments and then say dot value, yeah. Um yeah, so I'm totally with you on that. And the other thing that it suggests that really bothers me is the value and relative prominence of inheritance. I think inheritance is something that is indispensable when it's called for, but it's only called for rarely. And and and it's not it's I certainly wouldn't say it's what object-oriented programming is all about, or even one of the top five ideas.

SPEAKER_00

Yeah, well, we go back to editability. Inheritance is making a big commitment to uneditability of certain things, right?

SPEAKER_01

Mm-hmm.

SPEAKER_00

It's immediately difficult now. If I want to change something that was in the base, now we're just overriding, which means we didn't need it in the first place, and and so on.

SPEAKER_01

Yeah, exactly. And I often see two-way dependencies where the parents have knowledge of the children, and vice versa, and it becomes this tangled web where you have to bounce back and forth between parent and child to understand what's even going on.

SPEAKER_00

Yeah.

SPEAKER_01

Yeah. Um, so these again are all ideas that I'm trying to process and figure out like how do we talk about these things and what label do we put on these things and try to unteach people things like this dog and cat inheriting from animal lesson, stuff like that. And anyway, um again, I wish we had so much more time to talk right now, but unfortunately, we're we're almost out of time. Um, before we go, is it are there any links you want to share uh so people can find out what you're up to?

SPEAKER_00

And I'm not very active, but I have um adamdawkins.com is my website. It's got like a few posts on it. I'm on LinkedIn. My email address is adam at dragandrop.uk. People can reach out there. Um dragandrop's the company.

SPEAKER_01

All right, well, Adam, thanks so much for coming on the show. Thank you.