🎙 Develpreneur Podcast Episode

Audio + transcript

Building Better Developers, the Developer Podcast

In this episode, Trevor Hewitt shares his approach to building software, focusing on a functional core and imperative shell. He emphasizes the importance of accepting trade-offs and being willing to adapt to changing technology.

2021-07-12 •Season 15 • Episode 492 •Functional Core and Imperative Shell •Podcast

Summary

In this episode, Trevor Hewitt shares his approach to building software, focusing on a functional core and imperative shell. He emphasizes the importance of accepting trade-offs and being willing to adapt to changing technology.

Detailed Notes

The discussion began with Trevor's approach to building software, which emphasizes the importance of creating a functional core and imperative shell. He explained that this approach allows for stability, reliability, and adaptability in a rapidly changing technology landscape. Trevor also discussed his experience working with non-technical buyers, highlighting the need for stability, reliability, and price. He emphasized the importance of accepting trade-offs and being willing to adapt to changing technology. Throughout the conversation, Trevor shared his experience and expertise in software development, providing clear and well-structured explanations and good examples. The podcast format worked well for this topic, allowing for in-depth discussion and Q&A. Overall, the discussion was informative and engaging, providing valuable insights into Trevor's approach to building software.

Highlights

  • Trevor Hewitt shares his approach to building software, focusing on a functional core and imperative shell.
  • He emphasizes the importance of accepting trade-offs and being willing to adapt to changing technology.
  • Trevor discusses his experience working with non-technical buyers and the need for stability, reliability, and price.
  • He talks about his approach to development, focusing on creating a standard way of developing software.
  • Trevor shares his experience with functional programming and how it has influenced his approach.

Key Takeaways

  • Create a functional core and imperative shell to achieve stability, reliability, and adaptability.
  • Accept trade-offs and be willing to adapt to changing technology.
  • Focus on creating a standard way of developing software.
  • Use functional programming to create a stable and reliable core.
  • Use the community standards as much as possible when developing software.

Practical Lessons

  • Create a functional core and imperative shell to achieve stability, reliability, and adaptability.
  • Accept trade-offs and be willing to adapt to changing technology.
  • Focus on creating a standard way of developing software.
  • Use functional programming to create a stable and reliable core.
  • Use the community standards as much as possible when developing software.

Strong Lines

  • Create a functional core and imperative shell to achieve stability, reliability, and adaptability.
  • Accept trade-offs and be willing to adapt to changing technology.
  • Focus on creating a standard way of developing software.
  • Use functional programming to create a stable and reliable core.
  • Use the community standards as much as possible when developing software.

Blog Post Angles

  • The benefits of creating a functional core and imperative shell.
  • The importance of accepting trade-offs and being willing to adapt to changing technology.
  • The role of functional programming in creating a stable and reliable core.
  • The value of using community standards when developing software.
  • The experience of working with non-technical buyers and the need for stability, reliability, and price.

Keywords

  • Functional core and imperative shell
  • Functional programming
  • Software development
  • Stability, reliability, and adaptability
  • Community standards
Transcript Text
This is building better developers, the developer podcast. We will accomplish our goals through sharing experience, improving tech skills, increasing business knowledge and embracing life. Let's dive into the next episode. Hello and welcome back. We are continuing our season of interviews and our series of pieces of an interview with Trevor Hewitt. And we're going to talk this time about one of their key approaches as they refer to it. And this actually comes from, I sort of borrowed this idea from someone else, the idea of a functional core and imperative shell. And we're going to talk about this and I think it will be defined, although we talk about it somewhat in a definition. It's probably better to just talk about the examples of how it is, it's implemented. And that's going to be our focus for this episode is we're going to talk about basically building software in the modern world of there being so many libraries and pieces and reuse and how to work with that. Maybe how to leverage that and also to leverage your own experience and skills and code as this goes into a really more of a focus of not a single software project. But as you go through project after project, product after product is building on what you already know to some extent and some some rules and guidelines around that. These are definitely, these definitely go into our personal experiences and some of the things that we found. So they're definitely not hard and fast rules as much as some food for thought, we'll say. Some things that you can consider as you get into developing a product and then another product and another product or maybe within your company if there's multiple groups or multiple customers that you're dealing with. So these things may prove to be some approaches that will be useful for you as well. And we're doing our best at this one goes actually sort of long. So I have pasted out a little bit will change gears at the end. Basically, as we get into the next episode but try to keep all of this is our initial discussion of building software, both using your own code that could turn into a framework or library, and also using the code and framework and libraries that are out there whether it's a bit open source or some other you know some commercial product. That being said, we'll get right into it. So slight. So a detour back to somewhere originally was what originally got me wanting to talk to you about is he mentioned the, which actually this really goes back to some of the work you've done we're talking about some of the integrations and things like that is the whole idea of a functional core and imperative shell. And this, in particular, has been, you know, not in that, not using those terms necessarily but this is this has been one of those problems that I've struck I don't know if it's struggle with but definitely have banged my head against a couple of times, and particularly in recent years is there so it particularly as we've gotten into the web world and there's so many visual things, but there's still a lot of stuff in a lot of software that's not and figure out how to work within and test and sort of show off and in those environments in a way. It's where he said you've used this in several places to some excess as well I wanted to sort of see how you, how you've, how you've approached it and how you've maybe, you know, built it in maybe from the start and how it's turned out and particularly if you've got any warnings or, you know, great successes kinds of things we say hey this is, you always want to do this or you never want to do that, those kinds of things. Sure, sure. Well, you know I am trying to rid myself of as much dogma as possible in the programming world because I've seen more than a few people be bit by that one. And, you know, I think, as you know the wars over different styles and different frameworks and different tools can get semi religious for some people too. So, one of the things that I try and say is, you know, this is an approach that's worked for us. And here's why it's worked. And the why is because we're willing to accept several of the trade offs that come with that approach and of course the negative trade offs you know everyone wants the positives. So you know this approach is really good and fast and easy to hire developers. No one's going to complain about that. But the, the stuff they're going to complain about is the negatives. So, talking about a little bit about this, this is one guiding principle we have but I'm going to, I'm going to back out just a little bit and zoom the camera out, talk a little bit about the way we think about running our business. So, we are working a lot with non technical buyers, right in small to medium sized businesses. And as I said before, usually it's a buyer whose product is not technology in and of itself they're selling something else. We work with law firms, solar power companies, insurers, a sustainable LED lighting installer, just to give you an idea of different kinds of companies that is not really delivering technology at the end of the line but has a lot of internal technical needs. And the big thing these users want is they want stability, reliability and price, right, and they are not overly concerned about tools and tech as a matter of fact they want to hand that entirely over to us. And that's a big part of our model is that we're going to own all those decisions so having been an on site contractor before I've worked in several major finance institutions as well as HBO for a period of time that's a totally different kind of engagement, because you go in and you work by the hour with their team, and they are still making technical decisions and you're helping them implement them. And one of the things I noticed is just small and medium businesses our customers just don't really care about that right so they want us to own the technology and the technical solution. So we do that. And as a result we have a pretty standard way we develop our software as a matter of fact I'm trying to standardize it so much that all the projects are exactly the same in terms of framework and setup. And this is not in a bid to stifle creativity. It's not in a bid to stifle a lot of the cool ideas our developers have. As a matter of fact, you know the developers, we work with, tend to push us forward because they'll they'll introduce new ideas and patterns to the code base and then slowly we'll just adapt that and say okay that's, that's actually an official pattern at this point but the big reason we want to have that is we want to make it really easy to switch people from project to project and get a lot of stuff out the box because once again we're dealing with stability reliability and price, and the way to get stability and reliability up is have things work pretty similarly so we tend to know where the issues come from. We can build around those we can work defensively. We can also build tools that just eliminate problems altogether. Right, like we never have to figure out how to use our logging system ever again because it's the same logging system for everything right so it just, you works out of the box. And that's been a process of trying to develop the approach that allows us to be very high reliability, but still high function. So now we can zoom down into where we got the functional core and imperative shell and a lot of what we were seeing was the functional push in a lot of web software over the last few years. I attribute a lot of this to changing taste but also the fact that functional programming is a big interest to a lot of people given some of the more academic languages they were learning that were relying on it like closure and Haskell. I think JavaScript works well with functional programming styles because frankly I think the initial versions of JavaScript, you know older versions pre type script just didn't really do classes, very well, it was kind of confusing the prototype and everything. So it lends itself well to functional program, but then I saw data management patterns be very, very complicated at the top end for functional programming so I really liked what I saw going on close to where the action is happening but at the controller level of an application or manager or whatever you want to call it. All of a sudden, I found people were jumping through a lot of hoops do it. So that got us to functional core and imperative shell and it's, it's something we've implemented a lot of on our platforms right, which are just, they're not, they're not the most amazing and most sexy platforms you've ever seen but they're actually extremely reliable and it's, it's stuff that all my developers know how to do and have pretty good confidence around, you know, fully type script react based front ends type script node JS backends restful services haven't really found a big reason to integrate graph QL just yet. And trying to do functional core and imperative shell so there's management, and a lot of more o type processes happening at the top level usually have the react application and down at the lower levels at the utility levels or helpers, everything is very functional you know trying to commit to some kind of immutability and just functions doing work that does not alter state. And I think the community has moved around this a lot I mean the react core team is trying to make the framework as you know functionally oriented as possible so this has been easy for us because we're mostly just adopting stuff that's straight down the center, and the very last thing I'll say and what is a very long blurb that you might end up wanting to split up but we try to use the community standards as much as possible. So I have pumped the brakes a bit on introducing tons and tons of third parties into our code base obviously we use third party libraries for the things they're really good at especially when someone's done an implementation that would take us a lot of time to do, but we've started to move away from some of the helper methods and tools that just replicate what's already available natively and JavaScript and now type script more and part of that is just because we are trying to deal less with the changing taste of the community and have the code be right down the center. So I'll stop there for a moment because that was a long bit. Let's ask some questions about it. I guess the first one is, but really it's like how do you manage size and complexity of those functions is do you have some rules there to sort of allow it to the developers sort of figure it out or is there some maybe some rules of thumb that you work to find that those are the best ways to figure out the essentially the granularity of functions that you're building at that core. This is an incredibly dumb rule, but it's actually done a lot for us. I'll still say it. One thing we have on all of our linters is we're just limiting files to 400 lines. And I'm doing some contributions on a Python project right now where apparently every file in a Python project is 8000 lines long. So that that's a little surprising for me. But, you know, that's been a really good thing is just to try and make people figure out okay, I've got to structure this differently. I've got to maybe spread some of this logic across multiple places. You know, I like I actually don't and this is probably somewhat heretical but we can we can talk about it. You know, that's a podcast or for a little good heresy every now and then but I don't even mind a little bit of repetition in the code right, particularly if we're separating out where different things are happening. You know, obviously I want I want to do something like number formatting like really generic utilities. Obviously, we shouldn't be replicating that. But if we say have two utilities that work in different parts of the application, end up producing fairly similar results. I don't mind that stuff being separated out as well and tested separately. And part of that is just because you're you're lowering the footprint of super bespoke business logic type functions. And so you're saying, you know, stuff that's really, you know, observant of the easy to replicate across, you know, spaces say currency formatting or something like that. We want to centralize all that kind of stuff. But once we get down to business logic side of it, I also want developers to have pretty independent leaves that they're operating on. And so if they end up replicating some functionality here and there, that's fine as well. And I think I've learned a lot from them. I mean, I think that's, that's the ultimate, you know, lesson in organizational humility is if you think you know the whole architecture, you probably don't. And you're going to have some skilled developers who are able to, to better inform it. And I just want to make sure that it hits up to a couple benchmarks. I don't want to presume that I know everything that they're going to try and do, but I want to make sure okay, what kind of new problems is this introducing? How testable is it? Do I understand it when I read it? Basic stuff like that. And that's, it's actually sort of funny because there's most of places I've run into have something very similar to that is it's just sort of a very, almost random how they limit some of those things and you know, to size and complexity and things like that, which is often it is things like, you know, you can only have 50 lines of code in a function or you can only have a, you know, eight kilobytes size file or some things like that, which to some extent does have some of those things have huge value, particularly when you start looking at microservices and some things you can do there because then you may be in, or actually particularly if you go into hardware or something like that, where you may have very limited size and space and memory and processing where you do need to, to really shrink those things down. And I'm, although I come from a, I guess I'll join the heresy a little bit here is that I come from very much of an almost religious object oriented kind of background that always loved it and the approach and the design around it, but also have found that like everything, it seems like there is a, there's a practicality to it where you there's everything in moderation, I guess. And, and there are situations where I look at stuff and even all kinds of varied situations of code where I look at something and say, you know, it's probably better instead of us trying to make that function that's almost what we need in this other area, work in that other area, let's just essentially copy it and then edit it so that you have, you do end up having code replicated to some extent, but sometimes that's the faster, easier way to do it than try to have one thing that solves, you know, essentially solves two problems. And sometimes it's one of those things too, that I've found a lot, it's sometimes maybe easier in the short run to go ahead and do that. It's just replicate it, just copy, change it, move on. And then you can come back, particularly if you're doing this across clients, where you can always come back and look at, you know, hey, we solve this problem for these five different clients, let's take a closer look at those solutions. And maybe we can abstract out something that is, that is more generically useful and that would work for all of those, or that would be a better starting point for client number six or seven or wherever we're at with them. You got me on the abstraction there. I mean, that's exactly what I like to do. And that's probably the moment when it comes together. And now we've got some, you know, true economies of scale starting to happen, right? And that's a process I find incredibly gratifying is to say, all right, we've let this sit for a while. We know this implementation is good. And, you know, by good, it don't just mean that I like the way the code looks, but actually users are using it, right? You know, potentially in some cases with some of our customers, hundreds, maybe even thousands of people have already run through this API. We try and time out times, time out specific periods when we're going to go back and take a look at the different patterns we've utilized to good effect and start abstracting those out. And that's a really fun process. Because, you know, I mean, first of all, there's just the feeling of being able to do it over again and make some different choices, maybe ramp up the testing a little bit. And then the sense, and I think it's a real sense that that investment is now some kind of investment in the future, you know, hoping that you can do something more with that. And we've had some really good luck with some of the stuff that's become standardized to all of our projects. I mentioned the logger pattern earlier, you know, nothing that exciting about that. I think our module for the logger is something like three or four files. But I mean, the mileage that thing gets because it's really in every single one. And we make some pretty minor updates to it, but we've got it all configured the way we want. And so we're not coming back to that problem over and over again. Another thing I found too, is there are now a number of systems we're integrating with that also we have a very certain way of integrating with them. So one that comes to mind is actually QuickBase. And I don't know if you've used QuickBase or all. It's kind of like a no code database. And we've had the kind of odd luck of a couple customers using it. And so we've been able to abstract away a lot of the standard stuff we do there that requires a lot of scaffolding if you just use the QuickBase APIs. And of course, we're sitting right on top of the QuickBase APIs. We've done nothing so amazing that it would make sense to do an open source release of it. But that is yet again, something that just translates from project to project. And one of the features I use more than anything with my developers, I mean, if they took away this feature, it would just destroy my work. But I love the GitHub has links to specific lines that you can put in the repo. You could just quickly generate a link to a specific line of code. I mean, the amount of references I have across repos where I'm showing a developer, hey, just do it like this, do it like this implementation. And oftentimes I'm referring them to a repo, especially if it's a new developer that they've maybe never seen before. But then they've got a great example that's feeding back into the main line. So I'm trying to identify more projects to do that modularization with. My one word of caution there is people like me, probably like you, people who are operationally minded like this, I think we tend to overdo it sometimes. So I've often jumped into libraries too quickly and not really sat on it and said, is this really a problem I'm going to encounter that many times? So one of the things is it's almost like buying a firearm or something. I have a bit of a waiting period until I actually turn something into a library. So I force myself to just do it, just throw it into the project, see how well it works, tweak it, and then eventually reintroduce that as a library. And that's been a pretty good model for making sure I'm making the right decisions the second time around. Yeah, I think that's a good, again, that's a good rule of thumb. And actually, that's again back in my background, there was a company I worked for that they were primarily actually were entirely a consulting company. And then they found that there were tools and things that the consultants were doing on a regular basis, particularly as they talked to each other, that they said, you know, it makes sense to pull these things out and just supply these to the new guys and gals that are coming in. So they've got it right away or also for ourselves to use it in a way that we don't feel like we're reinventing the wheel every time. And that it does go to that that abstraction where I think you you get in these situations and particularly when you've got if you communicate well within your your team, your group that you find that the hey, we keep seeing this problem. We've solved this three or four times. Or you may even talk to somebody and say, hey, have you ever solved it like, oh, yeah, I've got this little repository over there. And at some point you say, we've got this in four or five different places. Maybe it is time to take a look at it and see if there's a essentially, you know, library eyes it if that's even a word. But, you know, turn into some sort of a library or a module or something that's very easy to reuse. And then, you know, maybe put a little documentation around or something so that you've got enough for somebody to pick it up that really maybe doesn't understand much about that problem. And then you can just say, hey, here's how you do the solution. Here's how you implement it. And you're off and running and allows them to go on and solve bigger and better problems instead of trying to do that one again. Yeah, and we we like to the stuff that we really like we will green light for open source as well. Because I mean, I have no problem with that. You know, whether it's open source or not, I'm still going to just keep using it. And especially if I'm in control of the repo, I can certainly get pull requests in there quickly enough. So that won't be a problem. And that seems as good a point as any to pause for now. That's a break in this episode. So we don't go too long. I will come back with probably what will be the last one, depending on how I slice it and dice it. But probably we'll wrap this up and get into a little more conversation with Trevor. But this turned out to be hope for you as much as for me. I think for me, a great way to see some insights into a group, you know, Trevor and his company that have done a lot of software development and have learned quite a few things. And maybe even you've noticed that there's there are a lot of things we can do to improve our software that we build and our processes that are not terribly complex. We don't have to go get an enterprise tool or anything like that. But sometimes very simple rules and reviews will move very forward, very quickly forward in the direction we want to go, such as, you know, maybe you get with agile from sprint to sprint every few weeks, coming back, doing a retrospective, making some adjustments. There are there's simple things we can do that will pay off big. As I've said before, both Trevor and I are happy to answer any questions about anything that we've discussed. The links to his information will be on the in the show notes. You can always reach me at info at developer.com and hopefully you'll come back and join us for this continuing discussion on how to become better developers. And as always, go out there, have yourself a great day, a great week, and we will talk to you next time. Thank you for listening to Building Better Developers, the Developer Noor podcast. For more episodes like this one, you can find us on Apple Podcasts, Stitcher, Amazon and other podcast venues, or visit our site at developernoor.com. Just a step forward today is still progress. So let's keep moving forward together. There are two things I want to mention to help you get a little further along in your embracing of the content of Developer Noor. One is the book, The Source Code of Happiness. You can find links to it on our page out on the Developer Noor site. You can also find it on Amazon, search for Rob Brodhead or Source Code of Happiness. You can get it on Kindle. If you're an Amazon Prime member, you can read it free. A lot of good information there. That'll be a lot easier than trying to dig through all of our past blog posts. The other thing is our mastermind slash mentor group. We meet roughly every other week, and this is an opportunity to meet with some other people from a lot of different areas of IT. We have a presentation every time we talk about some cool tools and features and things that we've come across, things that we've learned, things that you can use to advance your career today. Just shoot us an email at info at developernoor.com if you would like more information. Now go out there and have yourself a great one.