581

February 27th, 2023 × #coding conventions#automation#linting

Clean vs Sloppy Code

Discussion on establishing codebase rules and conventions to enforce clean code vs sloppy code through formatting, linting, naming conventions, documentation, and automation.

or
Topic 0 00:00

Transcript

Scott Tolinski

Welcome to On this Monday, hasty treat, we're gonna be talking about clean and sloppy code.

Topic 1 00:33

Talking about clean and sloppy code

Scott Tolinski

Now we're gonna be talking all about different ways that you could enforce rules, establish establish rules, enforce rules, automate, and document to make sure that your code is always clean. My name is Scott Talensky. I'm a developer from Denver. This episode is sponsored by Century at century.i0.

Scott Tolinski

S e n it. T r y dot I o. Century is the perfect place to see all of your errors and exceptions happening in your project, but also how to understand what's going on in your project. But this episode's about clean code. And if you're writing clean code, well, that's only going to help when you're trying to solve problems because things are gonna be named correctly. They're gonna be labeled correctly, and we're gonna be able to dive in and see exactly what went wrong and where. But not only that, as Sentry does a great job of of just constantly improving.

Topic 2 01:19

Sentry session replay introduction

Scott Tolinski

They're Introducing, like, constantly new features, which is always shocking to me because I open up Sentry so often that it it's really awesome just how many times there's something new popping up. For instance, they just launched a session replay, which allows you to get a video reproduction of your, user session so you can see exactly what happened.

Scott Tolinski

It's a brand new feature that, you know, is is brand new to Sentry. And, really, this this thing's super neat, and it works really well with all of the other ways that you manage all of your own errors in your application. So check it out at century. Io. If you use the coupon code it. Tasty treat, all lowercase, all one word. You'll get 2 months for free. I have the cough that will never go away. I swear it's not COVID, but I have been coughing for, like, 3 weeks straight. Yeah. So I'm gonna do my very best not to cough into the microphone here. I'm sure it'll be cut out if it will. My name is Scott again with me, as always, is Wes. What's up, Wes? How's it going? Oh, good. Good. I am

Wes Bos

currently battling a performance issue, which is a very peculiar one. Maybe I'll give you a quick rundown of it. The uses.tech website. I converted it from Gatsby static, to remix server rendered yesterday, and I deployed it. And I just like I was like, whatever. I'm just real quick. I banged it out and I deployed it. And then a couple people were like, it's like it's giving me, like, 5 seconds of white before I see it.

Topic 3 02:16

Wes performance issue on uses.tech

Wes Bos

And it's like the server response is kind of slow, like 600 milliseconds.

Wes Bos

So I can improve that by Caching the result, but it's that's not 12 seconds or 10. Some like I ran it through web page speed test. So I think I think I'm hitting up against some like rendering errors because there's so much HTML on the home page That woah. Because it downloads the CSS and HTML fairly quickly, but apply and it's it's not JavaScript related because it's It's HTML and CSS, right? Like the browser should be able to do that. But then if I run it locally, it runs super fast.

Wes Bos

So I'm gonna dig into that after this. I just can't figure out what the what the issue is.

Scott Tolinski

Yeah.

Scott Tolinski

That's interesting. It's curious. Gotta Kind of love those types of curious little ones, right? Yeah. Yeah. It's

Wes Bos

I'm not I'm kind of excited about it because it's just like it's not something super clear to me. Yeah.

Wes Bos

It's clearly one of those, like, chrome graph things that I need to dig into. So

Scott Tolinski

I might I might make a video on on the issue and how I solve it. Yeah. If you wanna ever be a good developer, I think the fact that that you just said, I don't know what's going on. I'm excited to find out. Like, that to me is is is, like, what makes you a a good developer, and that's typically what makes a good developer is it. Someone when who they reach a problem, especially one that is mysterious, they don't get, like, concerned or frustrated. You get, like, curious. You You know, I think I can figure this thing out and learn something from this.

Topic 4 04:23

Definition of sloppy code

Scott Tolinski

So let's talk about a sloppy code, which I'm sure is not the problem that you're running into, Wes.

Wes Bos

Hope not. Yeah. Who? Although I have no I'm no stranger to sloppy code.

Scott Tolinski

Yeah. Yeah. See, a lot back out. You remember that, Sloppy Joe song? That was a good song. Oh, yeah. Yeah. Yeah. I haven't had Sloppy Joe in a while. I dude, I haven't had Sloppy Joe in a while, and they were never my favorite.

Scott Tolinski

I've got to be honest, never really love Sloppy Joe's.

Wes Bos

No. Little too sloppy for me. I I prefer to put,

Scott Tolinski

like, some chips in there, make it a little bit less less sloppy, more crunchy. Yeah. If I'm not, like, like, a ritzy a Britney meat place. You know, plate that's got, like, really good smoked meats and stuff, and they have a sloppy joe. That, like, like I said, it's getting a little bit more pulled pork territory. It. Elevate it. I'm I'm done with that, but yeah. Alright. So sloppy code.

Scott Tolinski

Nope.

Topic 5 05:12

Examples of sloppy code

Scott Tolinski

To me, sloppy code looks like this.

Scott Tolinski

There's no real patterns or conventions established. Right? People are doing things the way they want to do them, and everybody has their own experiences their own other previous code bases. You have a team of multiple people working on this thing, and people just add to it. We've all been in code bases where you open it up, And it feels like you don't even have any room to breathe because so many people have just piled stuff in here. It's like the closet that they just shoved everything in and shut, and the door shuts. So it's all good. Right? It. The door shuts. We're fine. The closet's fine. We don't need to look in the closet. And and sometimes code can be like that too where you're just shoving stuff in. In fact, we've had many code bases that I've I've joined in that have existed for, you know, 10 years when you pop open this code base and, not one that I've authored myself, obviously, because I I don't author sloppy code. But, where it was just they they just tacked down another CSS file. Why? Because if you use the global CSS file, You might break something. So we're gonna just gonna attack another CSS file on here, and that's just going to be the solution. Right? Either way, no patterns or conventions established. It. There's people writing things the way that they wanna be writing them all the time, and nobody's saying, hey. We should come up with a unified way to do this. We should do this all the same way. That way, we can save ourselves the brainpower of reading code that all looks the exact same, but also we'll be able to find things when we need them.

Topic 6 06:37

Marie Kondo on organization

Scott Tolinski

People really got up in arms about Marie Kondo, but I think she had some good ideas around organization. Right? So file organization and naming, It's all over the place, and that's, like, a huge win. Right? Having an established pattern for naming files, naming functions, naming variables, and then having an established file system, the way you you put things. Where do you put things? Do you just toss it into the utils full folder And call it a day, is it just another one of the utils, or, do we actually have a way that we organize these things? Where do our components live? Do they live with the routes? Do they live in their own name folder? What is the folder naming? Are the folders named after their models? Like, how are all of these things set up? And the answer isn't necessarily name this this way, feature folders, whatever.

Scott Tolinski

The answer is a way that everyone in your team knows how to do it and will do it the same way. That's the answer. These problems are typically solved by people just declaring that these things are away and everybody's sticking to that. Yeah. It's,

Wes Bos

honestly, the tools are getting a lot better in that they can start to enforce these types of things.

Wes Bos

But there's I don't know if we'll ever be at a spot where you can a 100% enforce these such a thing. You'd often have to have them written written down and and sort of Buy in from the entire team. For for me, a lot of the sloppy code is, like, tacked on where, like, you Yeah. Jump into a See, you need to add something or fix something. You don't feel like getting into it all that much.

Wes Bos

And you're just like, I'll give you a couple of examples.

Wes Bos

My Keycode info website.

Wes Bos

I sold it like a year ago to Toptal, and they Took it and they not rebuilt it, but they, like, they turned it into, like, the way that they do things. So they they added Styled components for for every the style components would live in a separate file for each one, and, they added tests for every single possible thing, and then they added everything was in context. And, like, basically, they Not ballooned, but the code is probably 3 or 4 times bigger than it was because that's that's the way they do it and that All their engineers are able to get in and make their changes, and they sort of just follow that same thing. Whereas versus me, the way I coded it, where it's just like I just I had conventions as well, but it was less of multiple files and whatnot. So, part of that was They the copy paste didn't make it over.

Wes Bos

So that was a feature that was lost when they when they rewrote part of it.

Wes Bos

And I tried to just like I tried to just add it by saying when this thing is clicked, copy to clipboard. It's just an inline on click handler.

Wes Bos

Worked great, And it was more than enough, but they didn't want to do it because there was no, like, integration tests and all this type of stuff. And I was like, you know what? Like, I guess we won't have this feature then.

Wes Bos

But I guess that could see the reason they didn't want to do that is not because they wanted it. But if you allow 1 little in line thing here, one little thing that's outside of the way they do things.

Wes Bos

Then all of a sudden it becomes okay. There's 2 ways. Okay. Why is this done like this? Okay. And then it becomes a little bit unmaintainable over the years. It starts to rot, you know? So by being a little bit more rigid, I guess they have a longer term

Scott Tolinski

On that type of thing. Yeah. Because if there's 2 ways to do something, they'll eventually be 3 ways. Exactly. Potentially, 4 ways. Right?

Wes Bos

That's never good. Another one is, like, reaching outside or using side effects, for a quick fix. So here here Here's another example of sloppy code I recently did, the Syntax website. Now that Chris edits the podcast, he puts timestamps In the show notes.

Wes Bos

And the timestamps also get pulled into the Syntax website, but we had never built the syntax website to handle timestamps. They work in your podcast player. If you hit them, tap the show notes with your thumb, but they're never on the syntax website. And I was like, oh, I could do that. That's all you do is you parse out hours, minutes, seconds into seconds, and then you grab the audio element and you scrub the audio element to The size that you want and everything else in the React application that is the syntax website will react to that. The scrubber will move the Saving your location will move. Everything else will will move. So I just wrote a quick little function that would, Handle a click on these things and scrub it to the spot, and it worked great. Except the one thing was the syntax website, the the actual audio element that plays the podcast.

Wes Bos

That is the way that you reference an element in React as you use a ref, and you have to pass that ref around so that you can access it because I needed to set the current time. However, the way that I built the site initially was that The audio element and the show notes are siblings.

Wes Bos

Yeah. And how do you pass something with siblings? It's you can't. You have to move the state up and you do. Yeah. Yeah. You pass it down. So I was like, I'm not Refactoring this thing. If I built it today, I'd put the audio element as high as you possibly can, because it can live anywhere. It's not visible, But the the UI can live anywhere else. So I should have put it higher, but I didn't.

Wes Bos

What, 6 years ago when I built the thing And I wasn't ready. I don't want to refactor it. We want to redo the website anyway. So I was like, you know what? Document query selector, all audio dot current time equals blah blah blah Bang. It works. Ship it, you know, and that's okay. That's a quick fix for that type of thing. But if we did too many of those, Then all of a sudden that's a side effect. I'm reaching onto the page and grabbing it rather than referencing it. And what happens if at some point we want to put 2 audio players on the page? And Now that code will break it, so you gotta be careful with those types of things.

Scott Tolinski

Yeah. Totally.

Scott Tolinski

You do. So okay. So we understand Copy code. It it can cause problems. It can cause slowdown where you're working. It can, you can be shipping more code than you need to because you don't have a it. Pattern of establishing adding new codes. You're just adding new code all the time. It can cause a lot of problems in your your code base, especially over time of just adding this it. On to the point where nobody wants to work on it. Eventually, you'd say, oh, maybe we just rewrite this thing from scratch, when in reality, you could probably add something maintainable if you just wrote it maintainable from start.

Scott Tolinski

So we understand sloppy code. We would like to establish rules to fix our sloppy code, and then we want to enforce those rules and automate it where we can. So to establish rules, you you're gonna have a couple of different types of rules for, like, repo rules. Right? You have a repo. Perhaps it's a mono repo or perhaps it's just a simple solid repo.

Topic 7 13:14

Establishing codebase rules

Scott Tolinski

Where do your components live? What's your file system like? What's that structure? What are the patterns for how you make folders? When do you make a folder? It. Is it deeply or shallow? Like, do you have a lot of folders with index files, or do you have an individual folder with a, name folder and then a name file within that? These are things that you and your team need to establish because somebody is gonna make a folder with an index file if you don't. And then if you don't save no folders with index barrel files, or any of that sort of strategy. Somebody's going to do it. So you gotta have those ideas. If if this is the way it's gonna be, then this is the way it's going to be.

Scott Tolinski

When should a new configuration or package be added? Right? Those are big questions.

Scott Tolinski

Adding another config is not just another config. Right? It's something else. It's like another baby that you're bringing into this world. It's something that you have to make sure, is maintained, it's updated. If it updates, then you have to make sure it continues to work. Is this config doing any positive things for you using enforcing these clean code rules? There's a lot of, libraries out there that will do that kind of thing. But, Ultimately, are we just adding things for the sake of adding things or not? Like, when when when is the the process for adding something to the code base?

Wes Bos

How many people need to be on board for that? I think scaffolding tools can be helpful here. Oh, yeah. Where if you need to add like, let's say you you need to add a new component. And Every time you add a component, you need the component itself. You need a styles for that component. You need some integration tests.

Topic 8 14:38

When to add new packages/configs

Wes Bos

And what are some other things that could go maybe, like, maybe database schema that go along with it? Just think like rails, right? The types of stuff that rails generates for you. Oh, you might need, like, an update form. You might need a delete form. Right. There's so much to that type of stuff. And sometimes scaffolding can be like, Do we really need to just duplicate this code over again? And sometimes the answer is no, but sometimes the answer is yes. It's good to have a set of base where All developers can start with, especially if you have 5, 10, 15 developers on your team. It's nice to keep that consistent. Therefore, somebody can jump in at any time and not say, How did they how did whoever wrote this is different than the way I did it before. Yeah. Totally.

Scott Tolinski

Also, updates.

Scott Tolinski

When are packages updated? Who they who who gets to be the person in charge of updating packages and making sure that stuff still works after the update? And how often do you update packages? Those are all questions that you gotta know. Because if it's you're just doing it willy nilly, sometimes maybe somebody could update something on 1 branch that causes some weird Branch issues of, you know, did you update this on a branch that you were working on a feature on, or did you update this in another branch and then merge that in? CS. Like, what are those processes? And and we have to make sure that everybody's on board with the same idea, and that even goes along with Git strategy too. Like, Git Strategy is part of clean code in my mind. We're like, what is the the what is the flow? When do we create a new branch? How are these branches names? When do we merge them in? How do we merge them in? And those types of things, it's your stuff your team has to all come together on. Because If we have rules for all of those, then we can start to enforce those rules in all kinds of ways and just overall make our our overall flow better. I have a question for you. So let's say you're working on a feature

Topic 9 15:40

Scaffolding tools for consistency

Wes Bos

on your code base. So you check out a branch and you're working on that feature. And while you're there, You realize, oh, I could refactor this function, that is totally unrelated.

Topic 10 16:42

Refactoring unrelated code

Wes Bos

But I I I'm I'm in the headspace right now or, while I'm here, I might as well just update all the dependencies. And and then you you put in a pull request and it says, alright, This is my pull request to add this feature, but I also fixed x, y, and z and upgraded all these dependencies as well. I was so very tempted to do that type of thing.

Wes Bos

Is that something where you would just wait or pause, Update those things on the main branch and then come back to the feature you're working on. Do you have any rules around that? If you wanna know what I do versus what I should do,

Scott Tolinski

what I do Is that I'm 88 ADHD ed out, and I will just do I'll I'll just do it. And then Yeah. And then just have that be in my commit message. But it. I I work with, like, a small team, very small team of a couple people. Right? So the larger your team is, the more strict you need to be on all of this stuff. I I think for every single person you add to your team, the more and more, the more check marks of how strict all of these rules need to be. But for me, personally, it. I would just do that even though I know it's wrong, and I would feel bad about doing it. I'm like, I don't know. I shouldn't be doing this, but I'm doing it anyways.

Scott Tolinski

Ideally, what I would do is I would switch branches, go off the main branch or this the the working branch and and go from there and just Yeah. Do that. I I think if I was it. If I was working in the flow of I need to be, I need to be organized here and I need everybody else to To also be organized, you got to follow the same rules that everybody else is following. So I would try to I would try to do that off of another branch if that was a thing I actually

Topic 11 18:27

Branch strategy for clean code

Wes Bos

Really care about it. It's a delicate balance because, like, at a certain point, your developers are just going to stop Caring because there's way too much overhead to get something done. Like, you have to get approval and somebody has to do it. And it's just like, I just wanna fix this one thing, and And it takes me 10 seconds to fix it. But there's 6 meetings and 8 Jira tickets attached to this type of thing in order to get it fixed. And That's really frustrating for developers, sort of on the flip side. So I think there's probably some sort of delicate balance to strike there. Yeah. You know what? I would think each project it. That you're starting probably should get some kind of a number, 1 through 10, of how

Scott Tolinski

strict the clean code guidelines need to be for this This repo, is this a thing that a lot of people are working on that's going to exist for a long time? 10 out of 10. This is a thing that 1 person is working on and you're hacking it together on a weekend.

Scott Tolinski

1 out of 10. Right? So, like, for me, every project falls into that realm of, like, how how clean does this need to be? And if it doesn't need to be clean, there's it is gonna take you a lot. That's actually a huge pet peeve of mine is when things are prototypes or they are small projects or hack things, and people want to put in all of this crazy tooling around, these clean code things when this thing won't even exist. Like, I have often cited this on this show. We were doing a prototype of a experimental interface, and the these, it was like a third party Agency hired to do some extra work on it. Did, like, visual regression testing on this. It is a prototype.

Scott Tolinski

It is a hacked together thing. You don't need visual regression testing. But in a big library that or a big code base, that becomes actually something you'd want. So, you know, it really depends on what you're working on here. And so we also have code rules. Right? We have those repo rules, and your code rules can mostly be solved by formatting and linters and, hinters, those types of things. Right? It. Basic formatting tools that that can take care of a ton of issues. Prettier. Right? We're all using Prettier in in 2023. And if you're not, it's Easy to add. You should be using Prettier. It doesn't matter if you use the defaults or what, but you should be using something, to format your code to have it look nice. But, also, we get into the ideas of, like, how our function's defined.

Topic 12 20:39

Code rules with linters/formatters

Scott Tolinski

When do we use the arrow syntax first, the function keyword? Variable naming.

Scott Tolinski

Variable naming is often something people are it's like, variable naming is hard. Naming things are hard. It's every everybody says The naming things are hard, so I'm just gonna say it too. Naming things aren't hard. You just come up with a system. If it's a Boolean, you could prefix it with an is. If it's not a Boolean, you just name it. CS. You you come up with your own system for your own team about how terse or how long the names for things should be, but naming things is an art, especially if you have a system for it.

Scott Tolinski

How and where is CSS defined? What patterns for class names? You need a pattern for class names because just like the naming things above, If you don't have a pattern for it, people are gonna name things whatever you want. You're gonna have a container component. You're gonna have a wrapper component. You're gonna have a, a window. All of at least things who may very well do the exact same thing. A wrap, a wrapper, a container, a container. Who knows? Right? Still has some rules there. Yeah. Say this the way we write this. I mean, and that's one thing Bem did really well as it gave people a set of rules to to to name their class. It's a lot easier when there are rules. I almost Wish that

Topic 13 21:41

Naming conventions

Wes Bos

I or think that I should come up with my own list of of rules because sometimes I'm like, okay, this is the unparsed values.

Wes Bos

Sometimes I'll call it like raw or response.

Wes Bos

And then there's the parsed value, which is like the usually, that's the variable I want it to be. So customers or podcasts or something like that. So, like, What do you name the things that are before that? Podcast Raw podcast response.

Wes Bos

I should put together just a list of, like, Common things.

Scott Tolinski

Rappers, you know, like you said, that's are you spelling rapper, w r a, or are you starting r a p p e r? Wow. How are you doing that? But no. Those are those are the types of things that are really important to establish. And I actually have a Notion document of all of ours for our code base just so anybody can look into at any point, but it's also really well used essentially in the code base where, we have rules set up. And and another one, breakpoints. Right? What are the Breakpoints. Are you just breaking whenever, you know, there's an issue and, like, does that become untenable? Or do you have established breakpoints that you're doing for specific reasons? Are they named perhaps with Sass variables are named using some sort of future CSS thing that you're transforming with Post CSS? What about, like, commenting out stuff? Like, you know, people always say, like, leaving commented code is a bad practice, and I gotta say I agree. Get rid of that stuff.

Scott Tolinski

Like, what are your rules for comments and commenting out code or or or commenting out stuff? We've established rules.

Topic 14 23:03

Commenting code

Scott Tolinski

Yeah. We we're we've understand sloppy code. We've established rules. How do we enforce rules now? Because enforcing these rules is the part where the rules are actually, important. Because If you don't enforce rules, they might as well not even be there. So some of this big stuff you know, GitHub actions are really, in my mind, one of the most powerful tools here. Granted, GitLab also has CI stuff that you can use as well, but GitHub Action specifically, end up saving you so much, So many so many issues down the line. Right? On commits, on pushes, on any you can hook into any of these things, and you can format your code. You can run it through a linter. You can say, hey, block these PRs if the TypeScript's not compiling, if the the, The StyleInt isn't passing any of these things, and make sure that you enforce these rules in a way that's actually enforceable. Because if somebody can walk past the sign that says Don't go in here, then you might as well not even have it. Yeah,

Topic 15 24:08

Enforcing rules with GitHub Actions

Wes Bos

I was actually working on this on Friday.

Wes Bos

One of the repos I hardly touched is the burner email list.

Wes Bos

There's another guy that maintains it and he was like blocking.

Wes Bos

Basically, there's a GitHub action that says if the if it's not alphabetical and or if it's a duplicate Or if there's a blank line, then reject the pull request entirely. And I was just like Mhmm. There's literally there's 15,000 lines in here. No one's gonna alphabetical Well, their thing, the computers can do that, you know, or same thing with with coding. Don't block a PR because it doesn't mean you're prettier. If you can, your GitHub Action can just fix it, lint it, remove it, do whatever it needs to do, and then you just add in another commit where, it will Commit the fixed values for you.

Topic 16 25:02

Automating formatting/linting fixes

Wes Bos

So don't let that be a hassle to somebody if it's something that a computer can fix. And Ideally, somebody would be running these things, maybe even pre commit. But it's possible that somebody puts a pull request in. And if you have to block it because of something silly like that. Someone's going to say, all right, I tried to help, but I'm not here to, like, learn your up to set up to submit a

Scott Tolinski

typo request. Yeah. I think there's caveat. I I think there's definitely, you know, there there are certainly, like, times where you go to contribute, especially open source projects, Where you'd be like, I'm helping. And then the, the PR comes back and it's like, listen. You didn't jump through 8 hoops. You didn't swallow a flaming sword, And you didn't, you know, get the dogs to stop barking, so we're gonna stop this commit from going through. And and that could be very frightening. You say, okay. I'm not helping them. I don't want to do that. Don't wanna do all this stuff. I don't wanna have to read the 8 paragraphs you just gave me about all the things I have to do. But you know what? Hey. Sometimes those things are are required to have projects that are long living and enforced. Right? And if you if you, wanna get the work done or wanna contribute, then you gotta follow the rules is really what it comes down to. So if the rules are enforced, I think we can automate as much as possible. Right? Automate, automate, automate because nobody wants to spend time working on the rules or a clean code or anything like that when you don't you know, you wanna be making stuff. I don't wanna have to worry about scrubbing my code when I could be worried about the thing that my code's actually doing. So, like, the easiest wins is, you know, Prettier, format on save. ESLint, format on save. Stylynt, format on save. Fix all those things as much as possible for you. So that way, as early as possible, these things are getting taken care of, and then perhaps they're being run again inside of the, continuous integration process and GitHub action or something like that. But, again, establish those rules and force those rules to automate them. And then the the last thing is document them. We talked about this a little bit, but I have a notion a document that just says all of our different things. Hey. Use error, use function declarations like this in all cases except for these. Right? You can use inline arrow functions in these ways whatever.

Scott Tolinski

This is how we name variables.

Scott Tolinski

We prefer snake case over camel case. We do this. We do that.

Topic 17 27:14

Documenting coding standards

Scott Tolinski

C s CSS variables defined in this specific way. Always do CSS variables, never use color variable or color properties in CSS without a variable attached. It. A lot of really, really neat stuff. I think that's it. I think that's it indeed.

Scott Tolinski

I hope your code is cleaner or at least you understand when your code needs to be cleaner. Because sometimes code can be dirty, and that's fine too. We don't mind that. But, sometimes it needs to be clean, and we gotta scrub it down. So let's, us. Get our our code clean when it needs to be, and we can write some sloppy code too if we're just exploring. So that's really it. That's all I got. Do you have anything else for me, Wes?

Wes Bos

I don't think so. I think that is it. Thanks, everybody, for tuning in. We'll catch you on Wednesday.

Wes Bos

Peace.

Scott Tolinski

It. Head on over to syntax.fm for a full archive of all of our shows.

Scott Tolinski

And don't forget to subscribe in your podcast player Or drop a review if you like this show.

Share

Play / pause the audio
Minimize / expand the player
Mute / unmute the audio
Seek backward 30 seconds
Seek forward 30 seconds
Increase playback rate
Decrease playback rate
Show / hide this window