Pybites Podcast
The Pybites Podcast - Insights to become a world-class developer.
Coding is only half the battle. To truly succeed in the tech industry, you need more than just syntax, you need strategy.
The Pybites Podcast is your weekly mentorship session on the soft skills and career skills that senior developers use to get ahead.
Join Pybites co-founders Bob Belderbos (ex-Oracle) and Julian Sequeira (ex-AWS) as they share real-world insights on mastering the developer mindset, crushing imposter syndrome, and navigating your career with confidence.
Whether you are a self-taught beginner stuck in tutorial hell or a senior dev looking for that extra edge, we cut through the fluff to help you build a career you love.
Website: https://pybit.es
Julian: https://www.linkedin.com/in/juliansequeira/
Bob: https://www.linkedin.com/in/bbelderbos/
Pybites Podcast
#212: Elmer Bulthuis on Rust, WebAssembly, and Sustainable Design
Change is unavoidable in software, so how do you make it safe to evolve systems without breaking trust? In this episode, we’re joined by Elmer Bulthuis for a wide-ranging conversation about building software that can adapt over time. We explore how Rust’s ownership model shapes clearer thinking about design, why WebAssembly is becoming a practical way to share complex logic across platforms, and how Elmer has used Rust and WASM in real projects to keep behaviour consistent across TypeScript and .NET without duplicating effort.
We also dig into the everyday practices that make long-lived systems possible: choosing names that work in context, designing abstractions that don’t leak, and treating tests as living documentation rather than a checkbox. Elmer shares thoughtful perspectives on local-first development, keeping CI honest, and using AI as a helpful power tool for refactoring without outsourcing engineering judgement. Along the way, we touch on team culture, ego-free collaboration, and even yoga — because sustainable software is ultimately built by sustainable people.
Connect with Elmer:
LinkedIn: https://www.linkedin.com/in/elmerbulthuis
Github: https://github.com/elmerbulthuis
___
💡🧑💻 Want to become a more focused, motivated, and effective Python developer? The Pybites Developer Mindset (PDM) Program helps you build strong habits, deepen your skills, and make real progress in just six weeks. Join us for mentorship, accountability, and a supportive community that keeps you moving forward. Start your PDM journey now! 🌟✅ https://pybit.es/catalogue/the-pdm-program/
___
If you found this podcast helpful, please consider following us!
Start Here with Pybites: https://pybit.es
One thing that I know is that whatever format I choose is gonna change. So one of the first things that you design is a a model where change is possible. Another thing that I could do, I could also build a system that is very rigid and I could be, you know, and maybe I'm I'm I'm a day faster with delivering it, but it can never change. So if you wanna rebuild that into something you can change, you're gonna run into trouble because the old data, you know, what are you gonna do with that? You can migrate it, but this is all extra work. One of the things that I always do is I'm always backwards compatible in anything I make. That is the key to be able to work iteratively.
Julian:Hello and welcome to the Pie Bytes Podcast, where we talk about Python, career, and mindset. We are your hosts. I'm Julian Sapera, and I am Bob Beldeboss.
Bob:If you're looking to improve your Python, your career, and learn the mindset for success, this is the podcast for you. Let's get started. Hello and welcome everybody to the Pybytes Podcast. This is Bob Beldervos, and I'm here with uh Elmer Bildhouse. Elmer, welcome to the show.
Elmer:Hi, thank you very much.
Bob:All right, uh, let's check in. We are recording. I think we have done our both our workout today, so we're off to a good start today, right?
Elmer:Yes, in the morning. Every morning, uh yeah. Well, almost every morning I like to work out. It keeps me uh sane, basically.
Bob:Yeah, yeah. It's uh it's probably the best hour you can spend every day.
Elmer:Yeah, definitely. Yeah, yeah. If you do like a nice workout in the morning, then it's already a successful day, no matter what happens. And this positive vibes you can carry that all through the day. And it's a physical exercise. My work is of course mainly uh in my mind.
Bob:Yeah.
Elmer:And uh, you know, to keep the balance, I like to work out.
Bob:Yeah. Yeah, so tell us a bit about uh your work and and your background. Who is Elmer?
Elmer:Uh well uh I started with with computers um a very long time ago. I was uh I think I was eight when I did my first uh thing. Um it was a batch file in MSDOS. My my father he got a computer for work, and this was a 12 megahertz machine, which was incredibly fast for that for that uh for that era. It had a 20-megabyte hard disk, which was insane because nobody had a hard disk. So this was like top of the line. This was like the best computer. Uh, also we had a printer, which was very interesting because people in school they made fun of me because I had a printer. Um, nobody had a printer. And uh so that's when it where it all started, and later uh I worked with uh the Commodore 64. Uh much later I got a job at Commodore actually, and that was my last real job, or my last job that I worked for somebody else. Because after that, I I started a couple of companies and um also I did a lot of freelance work. Uh nowadays I I I I call myself uh an interim um uh software and infrastructure engineer. Um so basically I help companies with their uh well software and engine software and infrastructure problems. And um I work with a lot of startups but also uh corporates. And uh both of them are very interesting. So I work with uh with quite a few languages in my in my uh in my life, yeah, like programming languages. Uh a lot of uh I did a lot of C sharp. I'm doing a lot of C sharp lately, but it's not my favorite, uh favorite language. I like uh JavaScript TypeScript and Rust. Those are my my favorites. For the rest, I do uh some Python, I do some Java from time to time, a lot of bash, which is actually it is kind of like a language. And then in the back in the day I did PHP, of course. I do also HTML. Uh I do React, but not because I like it. Uh I'm more a fan of web components because just a better solution, I think. But you know, the world wants uh React and everything. So yeah, I do front end as well. Uh infrastructure, also databases and uh architecture and whatever, whatever. The only thing I don't do is everything I make is ugly, it looks like shit. But uh I'm absolutely not a graphical designer. Everything I'm I I I have two beautiful children. That's the most beautiful thing I created ever. Well, yeah, it always is, of course, but yeah, if you if I design a website, it looks terrible. So other people are much better at that kind of stuff. Yeah, I have a degree in interaction.
Bob:You do like the beauty in code.
Elmer:Yeah, my I think my code is nice, it looks beautiful. I think it's important that code looks beautiful because you have to look at it, right? So yeah, and um, so I I I got a degree in uh interaction design. Uh I'm not a good interaction designer. I only did that because everybody was expecting me to do to do computer science. Um so I didn't do that. So I did something else. Uh interaction design, which is actually also a lot of programming, and I'm a really bad interaction designer. So but yeah, I just stick to the to the code, yeah, and everything that comes with it.
Bob:Yeah, and we're definitely gonna dive into it because with all that experience I want to distill the lessons. Um we're gonna talk about Rust, WASM, abstractions, testing design. Uh before before we dive into it, uh, do you have a win of the win a win of the week?
Elmer:A win of the week. Yes. Um, well, I have a win of the past um the past um weeks, months. Choose your battles, it's kind of an open door. So um you know uh you don't always agree with the rest of the world. Um usually you don't because most people are other people and they have other opinions than you, but um that does not have to be a problem. You don't have to change everything, just the things that matter, and uh all this energy, you know, you're gonna lose it if you're fighting for something very small that is uh not simply not worth it. Yeah, yeah, yeah.
Bob:That would be my that's a great mindset win.
Elmer:Yeah, yeah, and you know, it's also it makes you a lot happier. Yeah, which is the most important thing.
Bob:Yeah, yeah, you you you cannot and should not fight all the battles, will make me makes you um unhappy. Uh become selective.
Elmer:Yeah, exactly. Like for instance, code formatting, you know, do we really care if it's an uppercase or a lowercase? Do you really care?
Bob:That's you know, there's the saying you can be right or you can be uh you can be liked or something.
Elmer:Is that it? I don't know that one. Yeah, but I think you're always right because you know I'm always right. Because if I would think something else, I would say that was the truth. So you're always right, you know.
Bob:In your yeah, in your opinion.
Elmer:In my opinion, I'm right, because I would believe something else if I wasn't, but you know, being right is not the point. The point is, well, I don't know what the point the point is having fun, actually.
Bob:Well, um what about Rust and Vasm?
Elmer:You are yeah, I'm very excited about that.
Bob:Yeah. So um what do you like about them and how the good things are? Well, they're they're of course different why yeah.
Elmer:Well, yeah, of course, what I like about Rust is that they they that it introduces a whole new paradigm into uh into programming. See, I never saw anything like that. And I'm talking about the borough checker then uh the whole concept of ownership. This concept is already there, but it's in your mind, but now it's actually enforced by the compiler, and I like that. Um it uh it hurts in the beginning because there's a there's quite a steep uh learning curve. And uh but it makes you better programming, also in other languages, uh, because you are very aware of what you're actually doing. Um, and this is this is partially because uh you have to always think about who owns the the the thing, the the variable in this in our case. Um but it's also the the other thing I like about it that everything is very explicit. If you want to make a uh like a like like something that that sounds simple, like a note with a parent and a child, so right? So this is do you do this often, probably. You've seen it, you see it everywhere. If you want to do that in Rust, it's not so easy. And this is good because it's not easy for your compiler as well, because you have like circular reference and then and one of them needs to be weak in order for it to be able to collect it properly. Um so that's one of the things I like that everything is explicit, and uh everything that is that is heavy or or at least more have more heavy things are more code. So this goes perfectly in line with uh with with with uh you know if if you if you have less code, it's probably faster. And that's uh that's that's like a rule of thumb that you can just apply with uh with Rust. It's also why making things that are really fast and really optimal is simpler than making something that is not so fast. Assuming that you don't clone everything, which is of course not how you should deal with Rust, but yeah.
Bob:But that's of course an um in the compiled language level, right? So for example, in Python it's just abstracted away and you don't have to care about the memory, right?
Elmer:Exactly. And it has, of course, it has a whole different use case, yeah. Uh, and that's only I think the use case for Rust can be very broad, uh, it's very expressive. Uh uh people use it a lot for uh for system level uh uh software. I think that that actually Microsoft was planning on uh rebuilding their entire kernel in Rust and they want to have it done by AI or something like that. That was like a rumor, uh, which is yeah, I don't know if that's actually gonna happen, but it says something it's very suitable for those kinds of things. But I think also that Rust is very suitable for back-end programming, and one day maybe even front-end. Um, and that would be then via WASM, which is yeah it's a great technology that actually goes hand in hand with Rust. And I think that is well, Rust was really early with being able to compile to WASM, and they can be really early because they have no garbage collector, they don't need a garbage collector that's all handled by uh basically by the compiler at the compile time. But uh WASM is uh well it started out as uh what's it called? It started out as a JavaScript library, and it was called Ms.criptum them, I think. And it was actually you could there's actually a a site that you can play Doom in your browser, and that was like years ago. That was actually it was impossible, but you see it and you wouldn't even believe it. It was Doom compiled to JavaScript. What it did is they made a uh like a bytecode, which is now uh the wasm code, and they uh uh they they they had like a runtime built in JavaScript. So you could compile your Doom in this case to something that runs in your browser in JavaScript, and that's completely amazing. And this is I think this is the the the the the well, actually this is this already happened, we're already past that, because now you can run native WASM in your in your browser. But if you think about it, JavaScript is the is actually the biggest language, it runs literally everywhere, it runs on your phone, right? You know how many phones there are, it's insane. And now with Node, you have it on uh you know server as well, so it's literally everywhere. Now you have this bytecode that actually runs on JavaScript, so it will also runs everywhere. And that I think that was the beginning of the success uh of something like WASM because you have absolutely no friction in uh in using it, you can use it everywhere. Nowadays it's you can run Rossom in your in your browser, which is great, but I think we're still not where we want to be. Uh if you wanna you wanna manipulate the DOM with uh with WebAssembly, that would be great. And now you do it via via interops still, I believe. But there are things happening that you can directly manipulate your DOM from uh your Wasm code, and then you can literally use any language in your browser. And this is only one use case, of course.
Bob:So I'm new to Wasm, so it's it's sort of a translation tool from one language to the other. In this case, you can write Rust and then run it in the browser.
Elmer:You maybe can it stands for web, uh it stands for WebAssembly, and web, of course, comes from because it will started out in the browser. Assembly is like it's where all languages compile to. Um and it's similar to uh to Java bytecode or maybe the.NET CR. Uh so it's a universe, it's a compiled, it's compiled to a format that you can use anywhere. And anywhere in this case means your browser, because then you can have it run by JavaScript or uh natively in your browser, but also there are uh plenty of runners that run on your own machine or in the cloud. And um this so it's comparable to assembly, but it runs everywhere. So it had this assembly is normally compiled uh with a target that is your your CPU. So if you run it on AMD, you have a different code, then it runs on uh on Intel. Uh but um so that's that's that's that's and and it's any language. I mean, I know that Go uh and Rust at least, uh, and I think also Java can be compiled to WebAssembly, and there are coming more and more a lot of languages compiled to WebAssembly. Um so this is kind of what uh what Java tried with the Java bytecodes to have one one uh you know one uh one one format that runs everywhere, and and Microsoft tried it with CLR, which is one format that runs everywhere. But you know, the whole um CLR is tied to .NET. Uh Java bytecode is tied to Java. Wasm isn't tied to anything. Uh so you could literally run everything with uh with WebAssembly. And this is uh this is happening already, yeah, but you don't really see it.
Bob:Do you have any cool projects um where you use Wasm?
Elmer:Yeah, I I have a uh I'm working on a on a on a JSON schema uh compiler which compiles JSON schema into uh it's currently TypeScript and Rust. Um and there is uh there is some some interesting logic there that's quite complex. So I build it in uh in WebAssembly uh or I build it in Rust, compile it to WebAssembly, I can use it in different languages. Okay, I use it in uh I I build the TypeScript compiler in TypeScript, I built the Rust compiler in Rust, and there will be a.NET compiler that I build in .NET. But the core logic uh it's it's quite complex and hard to test and everything. So uh it's nice if you can reuse that.
unknown:Yeah, yeah.
Elmer:That's what I um that's why what I use it for nowadays. Yeah, but I can't wait for this to be uh to be big. It's also much faster than uh than most uh most languages.
Bob:And people can check that out in the GitHub, right? We can link that.
Elmer:Yeah, yeah, uh it's uh yeah, so github.com slash love to sun. Yeah.
Bob:I'll link that.
Elmer:Cool. Cool, cool, cool.
Bob:Um yeah, that's uh that's talking about building things actually and the maker mindset. Um shall we start? Maker mindset.
Elmer:Well it reminds me. I I actually I I uh I know somebody who is a uh she makes uh furniture. Yeah and she showed me a uh you know you had like two pieces of wood and they are there was some kind of connection and they were put together. They were that would fit perfectly. And they would and and I thought it was really sexy. And that is the same feeling that you get when you make something that is actually absolutely beautiful. So I think this this maker's mind said if you make something in software, it's the same thing as making something in a furniture. I think there are similarities, but it's it's the joy of of making something that is uh yeah, that is just uh perfect or sexy or how you would call it. I don't know.
Bob:Yeah. Yeah, though, and it's kind of related to the next question I have the designing things in your head first. Can you can you tell me a bit about your progress? Um, sorry, your um your process of going from idea to to MVP, right? Because you definitely don't straight away at the the terminal. You you've you do a lot of design up front, right? And and mostly in your head or with pen and paper. Is that correct?
Elmer:It it it all happens. There are two things that that I think are really important. I I I think a lot about it before I put it down. Actually, I use my computer to uh to to dump my thoughts in. That's kind of it. And of course, you know, it may be some tweaking, but most of the work is done before I even touch my computer. And it happens, uh, you know, uh, I I I think it's also in a in a way, uh, working programming behind your computer can be distraction, distracting. Um if you re and you if you especially if you're designing something that is complex, you need uh you need to take away all those those hurdles. You need no distraction, you just need to be uh so this works for me, this works best on a piece of paper. And uh maybe I draw a line or something. It doesn't really has a you know it doesn't really look like anything, but it helps me think. So I use a piece of paper very often as a as a way to organize my thoughts. It's not like I'm making a list or anything. That is and I but I think that it's a very uh you know, think I think you know, programming has many aspects, and I think one of one very important aspects of programming is is planning, actually. And this planning is something that that that you you should do not while you're coding, because then you're actually doing it and not planning it. Yeah, I think with uh with the planning also comes a very important aspect that is uh I I really like to work iteratively. I only work iteratively, that's way faster than uh than anything that uh else actually. Well, you know, in a way, working iterative iteratively is working in very small waterfalls, but um I take small steps and I just do the things that I'm sure you know, because especially when you have a client, they don't know what they want until they see it. Yeah, so I think it is very important to start with um with something. And you usually I start out with something that I know that they are gonna need. That's the one thing. And the second thing is that uh I start out with something that I know that's gonna be a risk. If you do something for the very first time, that's a risk, you know. If you think if you're not sure if something works the way that you think it works, that's a risk. And that's uh that's a really uh it's a really simple actually. Oh, it's you know, to put it in practice might be a little bit harder, but it's a way to go way faster. The first thing you deliver does nothing interesting, you can only log in, maybe. And the second thing does nothing interesting, and the third thing does something interesting already. Uh you can get to that third version really quickly if you uh if you get uh you know if you if you if you practice this, yeah. Yeah, yeah.
Bob:That's my experience as well, right? Yeah you that's my experience as well. You yeah, make a mind map, and at least you have an overview of the components, yeah, but then focus on that core feature and get it out to people as soon as possible for feedback because everything is going to change.
Elmer:Yeah, that's the only thing that's not gonna change, but that's the only thing, but it goes also with like I'm currently designing a system, uh, and what we're doing is we are um we're storing uh uh data that cannot be, you know, it's like a system where you store logs, but these logs they need to be in a format that they cannot be changed. And if they are changed, it needs to stand out. Um so they can use be used for forensic analysis and whatever. Um so one thing that I know is that whatever format I choose, it's gonna change. So one of the first things that you design is a a model where change is possible. Yeah, and these these are these are the things that are necessary to uh to get to a uh to to work iteratively. Another thing that I could do, I could also build a system that is very rigid, and I could be, you know, well, maybe I'm I'm I'm a day faster with delivering it, but it can never change. So if you want to rebuild that into something you can change, you're gonna run into trouble because the old data, you know, what are you gonna do with that? You can migrate it, but this is all extra work. Right. So, but that this is all part of the the whole planning uh thing, right? So uh if you know, and then I think I think one of the things that I always do is I'm always backwards compatible in anything I make. And that is the key to be able to work iteratively. For instance, also even if you have an API, imagine that your API is only consumed by yourself. Even then, you want to be backwards compatible because you can just, you know, they don't they're not dependent on each other. They can move in their own uh fashion. And there's always something, you know, if you if you build an API and it's completely backwards compatible, which is pretty pretty well, it's easy to do if you know how, um, then you can just release it and everything works as it did. And then you can have a next version that uses this API. In reality, what happens is you're gonna uh release that API and then something happens, and you cannot release the other thing, but it's not a problem now. And uh so these kinds of delays, you know, in in in in if you're building something, anything can happen. Um so that's that's one of the things that I that I always do. Uh stay backwards compatible uh in iterations, and you know, always look for things that that that can um I think they call it a critical path, yeah. So if there's a a thing and it's critical that it happens, um so I don't know if you have like a database is also a very good example. Always keep your database schema backwards compatible, it's possible. Just don't change the whole thing and expect it to uh just take baby steps. Because if you change the entire uh database schema in a non-compatible way, then this is on the critical path. And that means that if it goes wrong, the whole project is stopped. Yeah, the whole project needs to wait for it.
Bob:Yeah, and for the data corruption, right? Good example with uh database migrations, right? You go step by, it's like the version control of databases, yeah, exactly. It's very granular, and you can roll back, you can yeah, basically version control.
Elmer:Rolling back is also also incredibly well, rolling back what is yeah, that's that's absolutely right. If you if you are always backwards compatible, you can roll back. And being able to roll back is a way to sleep at night.
Bob:Yeah, well, imagine, for example, a project like Pydentic, right? That they go to version two and they have the whole core rewritten and Rust, right? But then for some reason, a lot of projects can only um use the one dot something version, right? So they need they need to respect it, right? So um, especially as a library uh creator, you you just have the fact that a lot of your code will be pinned to a version, right? Yeah, definitely. You cannot break it. Uh shouldn't break it. I should never break it, but it's it's more like an uh a common concern for library uh.
Elmer:It's possible, but you need some kind of discipline. You know, one of the best and and most interesting examples, I think, and I really I really love that. You know, in the HTTP specification, they misspelled refer because it's with one R. But in the specification, it's in the specification it's with one R, but in reality it's with two R. So they tried to fix that. It's still supported with one R. I think you know, and that's a I think that's a beautiful thing. Um, you should just keep writing it with one R because this is a specification. Uh it doesn't matter if it's a typo, it's it's kind of cute in a way, you know. But this is how you should be dealing with your code as well. If you gave a shitty name to a thing, keep the name. It's it's people will and maybe if you have a next version or something, maybe you can uh improve the name. Um but it doesn't matter, you know. You made my maybe you think it's not a great name, but most of the people that work with your API they don't really care. Maybe they think, oh, that's a weird name.
unknown:That's it.
Bob:So concretely, instead of renaming the name causing breaking changes, which I've seen in quite some plugins, yes, has been annoying. Make a wrapper function that just calls the old function, for example, right? So no, yeah, you can still use the old function, but you have a a new name that wraps around it, for example, right?
Elmer:No, but I would just if you have an API, uh uh uh I would just keep the keep to the name that is that is not so nice. You know, and and I'm I'm I'm I think you know names should be uh uh you know you should really think about how you call your things.
Bob:Naming things is hard, but doing it right and I I think it's not I think it's not that hard.
Elmer:You just have to um accept that there's no perfect name.
Bob:Yeah, because it goes with understanding the problem, right?
Elmer:Uh yeah, oh but as I think as as a rule of thumb I always use uh uh two parts. If it's you know mostly I use two parts, so it is not a um I don't know it's not a crawler, it's an uh a container crawler. I just named something container crawler. Um so this this is a a system that crawls over a container. And if you know the context, and this context is it's a system for Azure, so you know it's a blob container. Um and that's the second thing with naming. I think context is really important. If you are in a uh if you are in a system and you do something with uh accounting, then uh an account is is something else than if you're in a system that has sales. And it makes no sense to uh maybe you know in in in one case you might be maybe you call it sales account, maybe that's even better because it's two parts as well. But if you say account and it's you know it should be clear because you you need to be aware of the context if you work on that system, of course. Yeah, but even if you would make a a system for a accounting firm and you call uh you call something an account, and then you uh uh you you you you are you know uh working with with accountants or something, so then they then I should not rename that account word to sales account. I would just keep it account. Yeah.
Bob:Which I think is a nice segue into the next uh topic. We have abstractions, right? Um yeah. But uh why do you think abstractions are so important and what makes good abstractions? Uh maybe examples.
Elmer:Yeah, abstractions are uh the whole concept is abstract. So uh I think abstractions are are are incredibly important in programming. I think also that uh that it's that's hard to get right if you just start out. Uh it's something that you get with experience, I think. Uh but it's also it's it's a way, a way in the end, it's a way of thinking. So this is very much it actually has nothing to do with programming. I think it's more a way of thinking about the world, um, and also being very rigid about that. If you are not rigid about your abstractions, you get leaky abstractions, and it basically means that one level of abstraction leaks into the other, and that's the beginning of a lot of uh of pain. Um so what is so abstractions are very important, and also it's a way to uh to improve maintainability, which is incredibly important, I think. Um if you if you have a a right abstraction, you could make like a base clause or something like that, and with the right kind of abstraction, you can you can use that for for years and never change it. So get maybe a bit optimistic, but if you don't change it, it's very rare that there are bugs in there. So it's also a good way to achieve quality. There's many upsides to abstractions, uh, but difficult to get right, I guess. Um why that is, I know that you know, yeah, because that's really I think that is really if you are a developer, that's how you think about things. Um it's not a very human way to think about things, maybe. Um I had a uh um so what what it what it actually is is that yeah, you you uh it's a difference between for instance. I am um yeah, like I said, it's very hard to find an example on this because it's all very abstract.
Bob:Run from a code base.
Elmer:I have uh I recently had an experience with somebody who um um okay, so we had to compare two models to each other, and um they uh there's in it was in C sharp, and in C sharp there's this this equality interface that you implement and then you can compare two things. But we found out that we did not want to compare um every every field in that in that model. Like for instance, the identified ID should not be compared in in this case. We were verifying if a change came true. Uh and we were not verifying the ID, but if you have two objects uh that that you want to equal, you want to know if they're equal to each other, then you should definitely take in account the ID. Because the ID is a very important part of the object, it's actually an identifier, which is what ID stands for. So if you have uh so it should really be be taken into account. Um so um, and that is that is an abstract way, abstract way of thinking. So we have uh uh an but we wanted to use it for something else, so uh we introduced uh the object uh what's it called the the the equ equality comparer or something like that. I think I forgot the name. And this this is especially designed to uh uh to compare two different objects, two of two the same objects in a different context. So in the context of verification, if the chains went through, we do not take in account the ID. But if you want to know if the objects are the same, then you take in account the ID. Uh, this is these are two different things, and that is where abstraction uh comes to life. So and you know, so uh in the end, uh uh uh we wanted to compare the objects, but we found out that strings were uh should be the same as nulls. Uh and in in at the first moment we implemented it in the in the uh in the base class for the comparator. And this would mean that every uh time a string uh is compared, we would say that null is the same as an empty string. Um, but you know, there are cases where this is not the case, you know, some concrete cases. So this was a form of leaky abstraction. We had a bunch of models, and uh as a coincidence, I think, or uh maybe as a as a shortcut, we figured that they were all stream, empty strings were nulls, uh implemented it there, but that would get us into trouble later because you do not expect that, not necessarily. Yeah, it's a very subtle uh thing, uh, but it's hard to recognize, I guess.
Bob:And uh, it is a very base class and dirty child classes now implicitly get that new behavior and then they don't have expected that, right?
Elmer:And you would not expect that, exactly.
Bob:Because so you introduce another object um or another sorry, because if you do like another base class, sister base class, and then you have multiple uh inheritance that's you could be complex, right?
Elmer:Yeah, but you could introduce another uh uh uh another level, another uh base class. And maybe and you should call it you, maybe you could call it like uh normalized compile or a comparer or whatever. Yeah, that's one way to solve it. But then another thing is that if you introduce another level of uh abstraction, you introduce quite a lot of complexity. If you just um coalesk every uh null with an empty string, then you're done. Only this this you know, in a in a way, this feels uh bad. I don't think it's bad, but I can imagine that you think that you're because you're typing these coalesc functions all the time or coalesc operator as this in.NET, uh you do it everywhere. It feels like um it could feel like a repetition or something like that.
Speaker 3:Yeah.
Elmer:Um, but I think uh repetition is not necessarily a bad thing if it adds to um clarity. Yeah, it was it is unmistakable to see what happens there. That is a very important thing. I think that is even more important than that is more it is more important than than repeating yourself. It's if you can make something extra clear that it cannot be misunderstood, then it won't be misunderstood. If there's an option that it will be misunderstood, it will be misunderstood. And that's also where, you know, in a in a code base that is difficult to understand, you know, your development is gonna be slower. It's gonna make more mistakes, uh, it's difficult more difficult to reason about. Yeah, I think the most important thing that you can do as a developer is making things simple. And maybe that's also the hardest things you can do. Hardest thing you can do. Uh but if you're able to do that, then then you're uh that should be your main priority, I think, as a developer.
Bob:Simple is better than complex. Yeah, yeah.
Elmer:Well, complexity is complex complexity is easy to make, I think. Very easy.
Bob:Um it comes with a price or a risk.
Elmer:And you know, sometimes you need complexity, which is uh which is terrible. Uh but even if you have complexity, isolate it somewhere, so you you do not have to uh you know and and document it very well and test it very well as well. That's that's even more important, I think. Yeah, and then you can work a level so you have like a system that is easy to understand on the surface, but there are parts that are complex. Maybe you don't understand them, but because you you made the interface simple, you can work with them.
Bob:Yeah, yeah, yeah. It's all about isolation, right? To have these boundaries and inevitably there will be complex parts, but can you isolate them and have clear interfaces with them, right? And yeah, and if you stand the library is also complex, but it has a nice interface, so you pip install it or include it in your project. Exactly. But the complex the code might be complex, you might not realize it because the out the interface is is elegant.
Elmer:Yeah, yeah, you don't even have to. I think it's nice to know those kinds of things, how complex what it actually does, but you know, the complex things, you know, just let them be complex. You don't have to be bothered by that. Yeah.
Bob:Just a quick break from the episode. Stuck at the beginner or intermediate level and wondering what it actually takes to become a senior developer. It's not just more years of experience, it's owning projects end-to-end, making solid design decisions, writing clean tested code, and communicating like a pro. That's exactly what we help people with inside the Pybes Developer Mindset program. You build real-world apps, get weekly code reviews, and sharpen your developer mindset that will lead to promotions. If you're serious about stepping up to a senior dev, check out the link in the description and apply right there. Now back to the episode. I want to talk a bit about testing because you have quite a statement there that uh you think the test code matters more than the production code.
Elmer:Yeah, I have two two very strong statements on testing and uh let's get them out. You're right. The first one is so testing is more testing is more important than writing code. It's terrible, but it's true. Uh so beautiful code is worthless without a proper test. It's better to write shitty code with uh which is very well tested instead of beautiful code, bug-free, that is not tested. Because in the if you don't test it, you don't know if it works. And not knowing if it works means it's broken by definition. Um, and even worse, you don't know it's broken. If it is broken, if you have beautiful tests with shitty code, then you know that the code is shit. And you can improve on that. And if you improve, because you have beautiful tests, you know that it is good code. So testing is is is incredibly important, I think. And the second thing is I think um also in theory, in practice, it might be a little more uh more friendly, but in theory, humans cannot test. Uh, because we need uh in order to have a proper test, you need a stable precondition. Humans are not a stable condition, they are very instable, and that has its own uh beautiful uh uh traits. But testing is not something that humans can do, should be doing. Also, it's incredibly inefficient. If you have like 100 tests and a human should do all those tests, that's never gonna happen. And even if that does happen, then this is a really terrible job, I think. Um, you cannot if you uh like for instance, also you know what happens very often is that you have like uh uh test test scenarios. Humans do this, they click through your system and they test all the things, but they always miss the things that are very hard to test. Forgotten password is a very uh uh very nice example, I think. If you go how how often are you is is the forgot password function tested? I'm pretty sure that is not a well-tested uh function unless you do it automatically. Um for instance, I'm I'm working on a system that uh that that that that that uh that that does payments with a bracelet. There's one scenario that I have that assumes that you have a new bracelet. If I would test that as a human, I would need for every test I need a new bracelet. Yeah, which is like a very big box of bracelets, and if I test 10 times, which you know is the almost incredible amount of time that takes on the day, then I have my whole house is full of bracelets. So that makes no sense, in my opinion. Um of course you do test sometimes as a human, but I think it's much better to invest in automatic testing for those two reasons, yeah.
Bob:So there are different types of testing, unit integration, end-to-end. Um prioritize, how do you um depends on the order?
Elmer:I am uh I'm very uh fond of uh specification by example, which is uh uh you know, in a way, a test is a specification because the test tells you what to do. In specification by example, we uh we kind of assume that that people don't understand each other, which is very true. And we can talk about a function forever, and in the end, it's gonna be a little bit different in your head than in mine. So we need a better way to communicate those specifications and specification by example communicates specifications uh via examples basically. Uh so imagine you have um uh uh rock, paper, scissor. I'm doing this example in a workshop uh in two weeks. Uh only we call it uh uh uh rabbit rabbit carrot gun. Yeah, because it's the same thing but a little more funny. But so if you if you would explain that to somebody, um then you could do that, but I think it's much faster if you give examples. So if you say like, okay, so uh um uh carrot wins from gun, gun wins from rabbit, uh rabbit wins from carrot. So now we explain the entire concept. Yeah, and um you know we you need to uh only if we now we need to so so this this is this is this is you it cannot be misunderstood. Um now all we need is uh a way to write it down, a proper way to write it down, and then we have a specification. Now the proper way of writing it down is you know using the three phases of of testing, which is uh arrange uh uh uh uh act assert in uh Gherkin, which I like to write things down, it's uh given when then. So you could say, like, even I play a game of uh uh rabbit carrot gun, and I uh uh and I and I have a uh I have a gun, and the other opponent also has a gun, then nobody wins. We have a specification. And um tells a story. It tells a story, and everybody will understand that. And this is not, you know, maybe you think it's a little bit uh pedantic or something, I don't know, but it's really clear and it's uh it's also it this also works across cultures, which is really important if you work with people from abroad. Um and if you write it in a structured way, you can also have this automatically tested. But even if you don't do it automatically, this this this works as as uh as a great way of uh of communicating your specifications. Specifications. So if you test this, it would then you would go more into end-to-end testing, which I think is also a really interesting way to uh to test, you know, to test for your specifications. I think also uh to test for bugs, if you encounter a bug in the system, which will happen, then it's great if you can first make an end-to-end test that exposes the bug. And um preferably in a way that everybody can read it. So the one maybe even the one reporting the bug if it's internal. Um then you uh write a unit test that exposes the bug. And then you fix the bug. Bug is fixed, unit test passes. This is what you test locally, end-to-end test passes. This you could also test it locally, but usually they take a little bit longer. What happens now is because you have this process of first making a test and then fixing the bug, this bug actually, as a result of the bug, your system is now more stable. You know, the bug happened for some reason, but you know, you can objectively say, I think, that it was a weak spot in the system. Because if it was, you know, bugs happen in weak spots for uh whatever reason, but it is a weak spot because there was something wrong there, but now you have an extra test in that weak spot, which makes for a more stable system and it will never come back again. Um, and order to do so, you really need to follow that that process of of TDD. So making a test first and then the implementation. If you're developing, I'm a little bit more relaxed with TDD, but yeah.
Bob:Yeah, yeah, it's not always a fit. But I love that that flow of uh hey, bug, write a test that exposes it, fix it. Yeah, and then all the other tests guarantees that you don't mess up anything else, right? So it's really robust, yeah.
Elmer:And it's actually uh uh a faster way of working, but it's it's uh it maybe it seems like a slower way of uh of working. I do some uh CrossFit uh as a as a as a sport, and uh one of the things that uh that we say with CrossFit is uh uh slow is smooth, smooth is fast, which is very true for CrossFit. But I think also if you talk about software development or maybe especially testing, it kind of fits there as well. If you if you make a test first, then maybe it feels kind of productive because yeah, you're not fixing the bug, right? You make another unit test, you're not fixing the bug, but then you fix the bug. But you never have to test by hand, you can just push a button and see if it works. So that is already a faster way of uh at least verifying if you're done. And then on top of that, in the future, you change something else and it breaks your code. Now you know. So you would not you only have to fix that bug once.
Bob:It's all about the future, right? It takes a bit more time now, but uh to save you so much debugging um and potentially unhappy customers uh and unhappy developers, especially at scale. Is is worth everything, right?
Elmer:So yeah, yeah. And I think also because a lot of there's a lot of you know, people talk about quick and dirty, and the re uh often a reason to do this is to build something fast, and this then needs to be done because somebody else wants a product or something. I believe in quick.
Bob:Sorry, especially with vibe coding now.
Elmer:Yeah, yeah. Yeah, vibe coding is you know, it's it's it's uh it's uh it's a it's a power tool. Yeah, yeah. If you use it right, you can you can really uh use it to your advantage. Yeah, but if you use it in the wrong way, it's like you know, if you wanna if you if you you know you can destroy a lot of stuff, yeah, yeah.
Bob:I mean, I mean I mean experienced developers, of course, use vibe coding in a responsible way, right? Um but it does create that hype of like quick and dirty, and it can be fun, but some things you cannot shortcut, and and testing is one of them, right?
Elmer:Testing is one of them, but it's also uh planning that that often gets forgotten. The design, and I think I believe in quick, I don't believe in dirty. You can be quick and clean. Um, and uh it's not you know, you just need a little bit of discipline and think about it before you do it, you know. Um actually, I think the whole AI hype with coding is is is it doesn't change a lot. Well, it changes a lot, but it doesn't really change the way you work. Only some things are can be done faster. It reminds me of uh I remember when internet came up, and uh back then I was programming, and um what I did, I was very young then, I went to the library and they had these books there, and I would take a book and would copy, uh copy it in the copy machine, and we take that home and uh try to understand it at home. So then the internet came, but the work didn't change. Only it's a whole lot faster to just sit behind your computer and look something up than if you need to go to the library and copy stuff and read it back home.
Bob:It's a lot faster. Potent tooling, same principle. Sorry, and more potent tooling, but same principle.
Elmer:Yeah, yeah, exactly. Now, with so so this is uh a revolution that is similar to to the internet in that sense. I think we're gonna be able to work a whole lot faster, but we still need to work, yeah.
Bob:Yeah, yeah. The design doesn't change. The fact that you need to write tests doesn't change, but we have better tooling to do it faster.
Elmer:Maybe we can write tests a little bit faster and write the code a little bit faster. And uh, for me, uh as a person that is only able to make ugly things, I I like it that now can at least put an ugly picture in my uh ugly code base. It doesn't make it more pretty, yeah, but it makes it easier to look at, yeah. Yeah, yeah.
Bob:But uh are you using AI tooling a lot? Are you in cloud code?
Elmer:I use uh I use AI a lot as a as a for research. Um I use it as a search engine. I can find things way faster. Um and I sometimes I I use it in uh PRs, so most mistakes I make are stupid mistakes. And um uh AI is very uh easy to recognize those those mistakes.
Speaker 3:Yeah.
Elmer:We're talking about typos, and uh, you know, there's some things that I can never get right. Like if if you have two variables and one is earlier than the other, you know, I I cannot that doesn't fit in my head or something, so I always mess that up. But and those are little mistakes that you can also get them via testing. Uh but it's good that uh these are the kinds of things that AI AI AI helps me with. Um and for the rest, you know, it I think it's also useful for front end in some scenarios, because you uh in front end you usually have a lot of code that is the same but a little bit different, you know.
Bob:Very predictable, yeah.
Elmer:Yeah, and um I think uh if there's a pattern to be recognized in what you're making and you need to repeat that pattern but not the same, uh that's really useful with AI, I think.
Bob:Yeah, uh yeah. When I was using Tailwind CSS for the platform, just to copy pages and just it was so good at just emulating the CSS classes or just um you know uh extrapolating that.
Elmer:Um but then I start with a good foundation uh and I do that by hand and maybe a little bit of a, but at some point when you have a foundation that is that is solid, then it's able to replicate that, and that's very useful, I think.
Bob:Yeah, yeah, you have to you have to design right and uh yeah, then you can go very fast, but it still requires you to think through the things well, yeah.
Elmer:Well, and also refactoring. So yeah, I I made a system with Tilwind and I was not happy with Tilwind. So I said to my uh what was it? I think it was Copilot that said you just make normal classes out of this, and it did that. And there were messy classes, but it gave me a first step into uh refactoring it to into more clean uh more to clean code. So it's also a way to um uh yeah, it's also a way to Kickstarter basically to get started with something really quick.
Bob:I had another question about uh testing um the design. How do you make your code easier to test? Um because for example, mocking gets complex very quickly, so yeah. Do you have certain go-to's for for that?
Elmer:Abstraction, yeah.
Bob:Yeah, right.
Elmer:So um that is but that is the key to uh to uh to having uh testable code, I think. And maybe abstraction not not though, yeah. So one of the the the things that that I like to do with uh so develop the test and the code at the same time, then you uh you know it's testable, and if your code is not testable, spend time on making it testable. And this may restructuring things and stuff like that. Like I said, maybe uh it feels counterproductive because you're not building functionality at that point, but it will speed up your development massively in the end, uh, because now your code is testable, so it will be tested, testable. And um if you need, you know, it also depends a little bit on what what your if you if you have a function, you want to test a function, all right. That's that's easy, right? Uh that's not the most interesting test, but if you have a service that uses other services, then dependency injection could be a very useful uh uh design pattern to use. You could mock those services or do whatever. I think mocking could be in some cases it's a very good idea, sometimes it's not, depends on uh on what you're uh. Um and one thing I always do is I want to be able to the thing should run locally, really. If it runs locally, it runs in CI, it runs everywhere. Uh I see quite often that you know people they use their uh AWS or Azure account to test against. Um, don't do that. Um I I often use Docker Compose and I run all services that I that I use in there. And I I also run that in CI, which is you know, I have the same test in CI as I have in uh a local machine. And it it's it mimics the production environment very very closely. On top of that, usually I I like to build uh Kubernetes clusters with everything in it. Uh depends also, of course, also on the on who I build it for, but uh uh I usually have a a cluster that I can also run locally. So I can the thing that I run in production is the same thing that I run locally. Um that really helps. It also helps to save costs because you know you need a state the the whole function of a staging environment changes. Very often I see people testing in the staging environment, which is actually not the right place to test. But if you can run everything locally and if you have proper testing that uses this local environment, you don't need that. Saves you money, but also you know, if you work with many people on a team, you do you need a separate environment for every developer. Well, who really has that? You know, yeah.
Bob:Um which again comes down to the how you plan it, break it out, boundaries, because if your core logic is not dependent on any service and you can just unit test it locally, then you might have 80% reliability and testing already done.
Speaker 3:Yeah, yeah.
Bob:And then leave the services more at the outer onion uh layer, right?
Elmer:Um, but I think I would even go that far to uh to select services that are easy to test. Um and and and but this is this is where I guess also a little bit more more political, I guess. You know, because if I would be choosing between SQL Server or Postgres, I would choose Postgres for the simple fact alone that it is that I can run it locally. I think even now there's there that you know fun fun fact is that I heard that there's a um there's a JavaScript version of Postgres. What they did is they compiled Postgres to WebAssembly and run that from Node. Uh this is perfect for testing, so you don't even need to do a do use Docker compose for that. I wouldn't do it, but you could do that. And um, so there has to be a really good reason to use something else, uh, something that is not as testable. Also, for the for the fact that I mentioned earlier, the code is more the testing is more important than the code. Uh, so also I would choose dependencies based on if they are testable. Of course, the dependency needs to meet your requirements, that's the most important thing. But I think being testable is a requirement, an important requirement. Um, and uh, you know, being able to test locally is a very big uh big advantage. Of course, if you want to do all of that, you need a you need a good design to set it up. Um, like one of the things that I like to do, I like to test in the in a browser. Um, I use playwright for that nowadays. I used to do it with Selenium, but playwright is really good. Uh it's really well done. It's Microsoft again, but uh it's really well done. Uh, I really like it also because it works with web components. Um, love it. But you know, the the principle stays the same. You need uh if if you want to do tests like that, you need a really good design to um uh to make it maintainable. And that is one of the key things. If you want to work with tests, you need to also think about you know, testable code also means that it is maintainable. And having your tests you do, if your tests are maintainable, it's the only way you can ever you know survive this. Uh because if you if you if your tests are not maintainable, what's gonna happen if you're gonna spend a lot of time in testing at the point where it's non-product really non-productive anymore? And in the end, you're not gonna run your tests because they're all broken, and in order to fix them, it will take uh an unreasonable amount of time.
Bob:So that's that's such a no-brainer, right? A lot of good tests because uh you have your specification right there, form of documentation, you have your regression suite, so your code is more robust, less risk of future breaking changes. Yeah. But then also this whole thing if you develop an intendem that uh it makes you think so much more about the code. So your design of the code is going to improve a lot because without if you're not focused on the test, you might just write code that's not testable, right? That's yeah, exactly.
Elmer:And so it's that's that's three major wins that it kind of enforces the right amount of abstraction a little bit.
Bob:Yeah.
Elmer:This in the ecology if you if you have maintainable tests. Yeah. And I think this is the most yeah, this is something that you should spend time on, really. Yeah, this is this is if if it takes you, you know, I don't know, maybe you you make an extra clause and think about that for a day, and then you think like I should make that class. Yeah, great, go do it. But don't um I just say that, uh don't try to save time on designing your code. This is more important than writing it. This is the the only reason why uh why you're a programmer, right? You know, everybody can write code, just read the book, use AI, do whatever. But designing it, that's where that's where you can make a difference. That's where the difference is between a well, you know, let's call it the good and a bad programmer.
Bob:Yeah, yeah, yeah.
Elmer:Yeah, I agree.
Bob:Cool, man. We went from Rust and Wasm to three major things, which is design abstractions and testing. Um coming to the end. Um, so we always end with a book tip or recommendation. But if you're not currently reading anything cool, maybe a book or resource in the past that is really helpful.
Elmer:It's about it should be a book about uh about about the job, right? About programming.
Bob:Well, actually, that's not required. I mean, if you have a cool book in that space, fine, but if you have a work of fiction or art or whatever, I don't really read a lot of books to be honest.
Elmer:But a resource uh resource. I think I think uh what I've okay, it may um not that yeah, it's kind of a resource. So uh okay, uh one one resource that will make you better programming is yoga, which is maybe um maybe not uh because one of the things that I I I I one of the things I learned from yoga is to uh to work with my ego, and I think I'm a better programmer if I am less programming for myself and more programming the right thing. I think all all these, you know, I love my job. I like to make something that is completely amazing, but in the end, I'm making it for somebody else. It's not about me, it's about the product. Um, and these kinds of life lessons, there are plenty of more in yoga, um, they help you become a better person and a better programmer, and I think uh those two will go hand in hand, by the way.
Bob:Yeah, that's awesome. That's the first time I hear uh the yoga programming connection. So, how does yoga help with that?
Elmer:Well, I think in in in in in at least two ways. You know, one is the the the physical part of it, you know, uh programming is is is a mental job, it's a uh intellectual job, but you as a human, you're not only an intellectual being, you have feelings and uh spiritual side and a physical side as well. So these need to be imbalanced, I think. If they're not imbalanced, you're gonna eventually get stressed or whatever, you're gonna get all sorts of nasty things. If you're if they are imbalanced, you can go much faster and much harder on every uh of them. This is one of the things that yoga does. And like I said, you know, the the whole uh uh ego thing, I think often in in in in some a lot of uh programming cultures like uh companies and everything, sometimes or way too often I think there's a there's a there's like a competit competitive culture, but not in a good way, you know. Sometimes I feel like if somebody thinks they're a better programmer that they're a better person, which is simply not true. Uh it's great that you're a good programmer, but if you're in a team, it doesn't matter. You do it as a team. And what really matters is how can we do this. It's not about what can I do to make you look uh you know bad or the other way around, oh you're so good, it makes me look bad. And this is the kind of thing that that that is that is that is ego. This is the kind of thing that you learn how to deal with with uh more spiritual things and yoga is is a very very nice uh thing of that, I think. Um so yeah, that's that's that's a way to deal with this uh this culture that is that I perceive as toxic quite often. Um yeah, and you can make it better, you know. If you if you just go somewhere and somebody's like, look at my code, it's great, and you like, yeah, your code is great, you know. And if you can really mean that, then you can just forget about that thing, you know? We're all good, it's all good. You're good, I'm good, we're a team, it's great, and this is how it should work. Yeah, yeah. Instead of instead of being like, I'm the best programmer in this team, yeah, no, nobody should care about that.
Bob:Yeah, yeah, unfortunately that toxicity is out there. Um, yeah, and we can benefit from that that mindset, yeah. That's uh that's a great uh um piece of advice.
Elmer:Yeah, you can change the whole vibe, you know, you can change that kind of toxicity, uh, toxic toxicity toxicity, no, whatever. Uh if you bring in a better vibe, and I think that is that is that is, you know, in the end, you're a programmer, okay. You write code, right? But you don't only write code. You also you are responsible for more things than just writing code, you're also responsible for the team spirit.
Bob:Yeah, yeah. So much more than just code.
Elmer:Yeah. Yeah. Yeah.
Bob:So awesome. Yeah. Well, thanks, uh Elmer. Really enjoyed our discussion or uh conversation today. Yeah, great. Uh lastly, where um can people reach out to you? Are you in the Bybytes community? If not, please join.
Elmer:I will join after this. Yeah. My name is Elmer Bildhouse, and my company is called Love Da Sun, L-U-V-D-A-S-U-N. Uh, but and I'm I'm uh in on many, uh you can find things about me on the internet, but actually, if you really want something from me, just uh reach out to me. Yeah, because on the internet there's no not so much impressive stuff of me. Yeah and if you want help with anything, I'm I'm glad to help. Uh you know, if you have questions, don't hesitate. I'll I'll just make time and see if I can help you. I like to do that. I think we love. Programming.
Bob:But some Rust posting and we we commanded and that's how we met, right? It was on LinkedIn.
Elmer:I think we met because somebody said something about Rust. That kind of triggers me. I try to stay away from LinkedIn and all of that that media, but you know, if somebody starts talking about Rust, then I'm all ears, man. Yeah.
Bob:Yeah. Alright, thanks, Elmer. And uh have a great day.
Elmer:Yeah, you too. Thank you. And thanks everybody for listening.
Bob:Great to have you on. Okay, ciao. Thank you. Cheers.
Julian:Hey everyone, thanks for tuning into the Pie Bytes podcast. I really hope you enjoyed it. A quick message from me and Bob before you go to get the most out of your experience with Pybytes, including learning more Python, engaging with other developers, learning about our guests, discussing these podcast episodes, and much, much more. Please join our community at pybytes.circle.so. The link is on the screen if you're watching this on YouTube and it's in the show notes for everyone else. When you join, make sure you introduce yourself, engage with myself and Bob, and the many other developers in the community. It's one of the greatest things you can do to expand your knowledge and reach and network as a Python developer. We'll see you in the next episode, and we will see you in the community.