Lint and Other Fuzzy Bits - podcast episode cover

Lint and Other Fuzzy Bits

Nov 27, 202139 min
--:--
--:--
Download Metacast podcast app
Listen to this episode in Metacast mobile app
Don't just listen to podcasts. Learn from them with transcripts, summaries, and chapters for every episode. Skim, search, and bookmark insights. Learn more

Episode description

Matt and Ben talk about code linters, and meander into various topics. Matt describes the (approximately) 37 different ways to cast variables in C++. Ben argues that continuous integration was better in the 19th century.

Transcript

Matt Godbolt

Hey Ben.

Ben Rady

Hey Matt.

Matt Godbolt

How's it going?

Ben Rady

Pretty great.

Matt Godbolt

Awesome. Well, um, I was chatting to someone, you know, the other day and they were asking how much preparation work we do before we record these podcasts. And they were, um, pleasantly surprised to learn that we don't do an awful lot. We're not scripted in any meaningful way. I mean, you and I have a couple of minutes chat beforehand, and then we decide on a topic and then we just basically hit record. So we're really putting that to the test today because we literally said, Hey, let's talk about linting and then we've hit record. So let's talk about linting. What's linting Ben?

Ben Rady

That is, that is the extent of the prep. Um, what is linting? What is linting linting is, uh, what you do when you don't have a compiler and that's, that's one way to think about it.

Matt Godbolt

Interesting point, although I would say that I use as much linting in compiled languages as I do in non compiled languages equally, but you know lint, I mean, so I, I don't even know. I've never really stopped to think about the, the etymology, but like lint is.

Ben Rady

The entomology?

Matt Godbolt

The ento-no. The insects-collect-ology of

Ben Rady

That's going to be have, that's going to have to be a running bit. It's like, it's like less and fewer. We just have to constantly confuse etymology and entomology.

Matt Godbolt

Yes.

Ben Rady

One day we're going to have to talk about insects and find a way to work that in.

Matt Godbolt

I was going to say, what's the entomology of the word bug in computing. Whoa. Oh yeah. So yeah, but lint is like the stuff that you find at the bottom of your pocket after you've worn a pair of trousers for a while and you go, well, there's all this nonsense at odd bits of fluff and whatnot. And presumably linting the code term comes from like the removal of that. Like, let's get rid of all that fluff. Let's clean it up. Let's get the, the, the, you know, the little brush out. But yeah,

Ben Rady

But guess I honestly don't know what that's from.

Matt Godbolt

I don't know where it comes from, but w what I think of it as is essentially static analysis of code and the application of relatively straightforward rules to say, no, this is how the code ought to be, right. The language probably gives you freedom to do things in lots of different ways. And as a sort of choice, you say these ways are the ways that we're doing this thing. You know, we, we, we are, we, whenever we call our log methods, we don't use python and F strings. And I say this, and you're going to grin at me because this is my personal bugbear, because that's not the logger automatically does some of the formatting for you. And if you don't, uh, if you don't use the logger's facility, you're paying a cost for something that's going to happen anyway. So, and you can say, well, that's straightforward. Let's write a rule for it. And then I can apply it automatically to my code, but there's thousands of other things, right? So it's basically code quality checking. And then you said something about compilers. Do you want to elaborate on why compilers or the, not the lack of...

Ben Rady

So, so if you don't have a compiler and, and all of your code is interpreted, then there's never an opportunity to do this kind of static checking, uh, normally naturally. But if your code is compiled, you, you know, you could make the argument, uh, in any compiled language that a linter is just all the things, the compiler team didn't have time to add warnings for.

Matt Godbolt

Well, right. There's that, but there's also a lot of opinionated things that they may or may not want to add as a general principle. Right. You know, there's, there's definitely things that are known to be okay, but maybe frowned upon. And it's maybe not the compiler's place to, to, uh, to, to, to make that decision on behalf of you. And, and, you know, some of this stuff also comes from the fact that you, as a, if you're writing in a compiled language that has stronger types, then you can make some of the sort of policy decisions about how things may or may not be used by saying, well, I don't accept anything other than this type here. And then the compiler enforces your rules. You get to write the rules using the language, but in say an interpreted language we'll pick on Python, um, you don't get the opportunity to make those distinctions. You have to sort of say, no, this is, yeah. I need something else to, to uphold these, these rules that I'm making. But yeah,

Ben Rady

Yeah, yeah, definitely. I mean, if you're, if you don't have the compiler there, then I think the, the, the linter has a has a much more not I'm, I'm not really trying to make the argument that if you have a compiled language, you don't need a linter, that's not what I'm saying. Um, but I am saying that if you don't have a compiled language, uh, there, there are going to be more instances where you need a linter cause there's just no other opportunity to do that. Um, and you know, I feel like that that, um, demand changes with various aspects of the team, like how junior the people are, how big the team is, uh, how much consensus there is around, um, around sort of like conventions that prevent bugs or enforce particular style, or, you know, just make, ensure that a pattern is repeated consistently and things like that.

Um, you know, it's, it's, I think it's actually quite common to have situations where if you got everybody in a room to, uh, try to have them agree on how something should be, they would actually agree. Um, you know, maybe after a little bit of a discussion, but they would, they would agree, but they don't know that they agree. Um, and so you sort of like have the linter there, as the objective judge to be like, no, this is, we pre-agreed that we're agreeing on this. So if the linter is telling you something, then that's what we're doing. And then everyone is like eh, okay, seems reasonable. Right, right. Um, so, you know, there's, there's sort of like, uh, varying degrees to which you might agree. Uh, but I, I think that's, that's, that can be a role that, that linters play is if you have, you know, larger teams, especially, um, but really any situation where you're trying to create that consensus around, like, what should the code be doing, what it should not be doing? Um, linters are a tool to achieve that.

Matt Godbolt

And I suppose the way that you could think about it is that we have tests for the functionality of our code and we make them automated and we have them like checked in and they're run as part of a CI. What linting is, is a layer of level above that, like meta, this is how we said, we're going to write the code. How do we enforce and tests check, how do we check that we are keeping to the rules that we all agreed on? And I think probably the, the difficult aspect about linting is it's it's, it is more subjective. There are things that are more subjective and you have to make some, I mean, you alluded to some of that. Yeah. You get most people in the room and they say, yeah, don't do X. And I'm having trouble thinking about what X is that would everyone would agree to not, well,

Ben Rady

Uh, the, the non scalar values in Python, default arguments, I think is a great one. And it is, it is actually like one of the ones where it's like, I don't actually think it's maybe as clear as like, oh, the tests are testing for like correctness and behavior and the lints are more stylistic. Cause you can definitely find bugs in code with linters like, it is possible

Matt Godbolt

We should just explain a little bit, what that is, because

Ben Rady

Oh yeah.

Matt Godbolt

Yeah. So do you want to give us a quick rundown?

Ben Rady

I think I, I think I can do it off the top of my head. So, uh, so basically when you declare like a function or a method in Python, you can give it default arguments, um, and all galaxies

Matt Godbolt

And have so parameters that you're passing will have default value. So you can say like Def, uh, say hello, uh, username equals Matt. And in which means if call it with no args, it'll say Matt, and if you call it with an arg, it'll say what you passed in. So you get to default the parameters that you're passing into a function. Got it. Yes.

Ben Rady

Yes. And so the, the problem is, is that Python has no opinions at all about what those values can actually be. They can be anything. Right. Um, and very unintuitively, I think if you pass in something like a dictionary or a list, um, the, the declaration of that, uh, the, the creation of that object is done once when the function is evaluated, not when it's executed. So every subsequent execution of that function will reuse the same instance of a list or a dictionary over and over again.

Matt Godbolt

It's not a scalar type, like an integer or a float or a string is a reference to an object that exists. So there is exactly one object that is the like empty dictionary you pass as the default. And now of course, if you mutate that you're mutating the actual thing, that's going to be passed in every single time I see. Right.

Ben Rady

Right. Right. And

Matt Godbolt

So that seems like it's a language flaw that seems like that's actually a problem with the language.

Ben Rady

The language. Well, and that's why I kind of make a little bit, I mean, it's very tongue in cheek, but I make the argument, you know, with, with, uh, compilers and stuff that like the lints are just all the things that the compiler team didn't around, get around to making warnings about, um, which is not, it's not really true. It's, just kind of a joke.

Matt Godbolt

No, but it carries...

Ben Rady

There's a flavor of it. Yeah, yeah, yeah, yeah. Yeah. So, um,

Matt Godbolt

So that's like an, a, an example of a lint rule that everyone who gets into a room would, would agree with, right. Would say like, you know, this is all, there is almost no situation in which you want this to be true. And I mean, I suppose the other thing is that with linting rules, you can reasonably decide to turn them off on a per line basis, which is something you normally don't do for other things like, you know, actual compiler it's like, there is no way to get past the fact that the compiler is saying, this is broken. Your types are not compatible. You tried to pass them in. And if, but here you can say like, no, no, no, just on this line, don't do it. But it's a, it's an opt in thing to do. And maybe you even turn those off, maybe if you decide, but like, if you did really, really, really mean to have a mutable default parameter, because maybe you're accumulating things into it or whatever you're doing, but it's a very purposefully done, then you can turn it off, but it's not the default anymore. And it stops you from, it protects you from yourself, um, down the line, right? Yeah, yeah. Yeah. So that's a, that's an interesting, that's a lint rule that is everyone can get behind, but I'm sure there are ones, examples of rules that people could reasonably disagree about.

Ben Rady

Yeah. I mean, a lot of the times I feel like you'll have linters that have stylistic rules, like, oh, this, this variable name is too short. Right. That's, that's a, that's a, that's a linting rule. Right. Um, and like, you know, okay. Like, you know, I, I get, I get that people would want to do that, but there's almost certainly, you're almost certainly going to run into situations where it's like, no, no, no, in this context,

Matt Godbolt

It's fine to have X and Y those are what we call the parameters that get passed into, I don't know.

Ben Rady

The graphing library that's plotting X and Y and like, that's actually what they are

Matt Godbolt

You have to be very careful that you're not incentivizing people to start adding like X underscore version or underscore one just to make it long enough, right?

Ben Rady

Yeah, yeah. Right.

Matt Godbolt

It's a sort of anti-pattern uh, yeah. But yeah, there's, I mean, I, you know, um, I suppose an extension of linting rules, and maybe this is actually, I don't know if you would agree with this, how do you think about automatic code formatting as essentially, um, a lint or rather, you know, like, you know, the the, the checking of a format could be considered to be a lint. It's like, hey, if your code doesn't look the way that we said our code is going to look, then it's, you're, you're breaking the sort of the style guide and we value consistency in layout so that we don't spend all our time by pausing and recognizing, oh, oh no, that's just a function declaration or whatever, but you did it in a different way for me, or however it is.

Ben Rady

Oh yeah, absolutely. Yeah. I, I, my, my take on that is that you should use a consistent style, like a hundred percent of the time. It is possible to do that without something to enforce it. If you have a small enough and cohesive enough team, and I have been on teams like that, where it's just like, yeah, we're just gonna do it right. Um, and that's fine, but no matter if it takes automatic formatting, and if it takes checking of that automatic forming to make sure that you are doing it, then that's what you should do. It's sort of like you, you know, if you were to model this over the evolution of a team, you start off with just like two engineers who are very senior know each other. Well, it's just like we're using that, that formatting that we always use, right.

Yes. That's what we're doing. Right. And then you work for six months and you add two more people to the team, and you start to notice as you open up files that the formatting isn't quite right. And you tell them like, Hey guys, you need to make sure that your formatting is, if they think, oh, yeah, sorry. And then maybe it gets a little better. And then you had two more people to the team and everything goes out the window. You're like, that's it, we're putting in automatic formatting. I can't, I can't do this anymore. Right.

Matt Godbolt

You know, but then there's a level above that, which we're grinning at each other because we, you know, I think we agree on this that I senior or otherwise experienced, I think is probably a nicer way to, but enough where I'm like no day one in comes, the automatic formatting, it's just, I don't want to have to argue about it's. I don't even agree often with the way that the code ends up looking, but I value the consistency and the simplicity and, and frankly, things like, um, so I'm talking specifically in like a C++ code base. I will use uh, clang format, which is now pretty much across the board accepted by all editors. And it's an external tool that just works, and it has, it's configurable enough, it's got many bells and whistles and you can usually find a decent enough compromise. And then you check in your format file.

And you say like, that's just how our code is going to look now. And you can turn it off in small regions if you really, really, really want to like, have like a data structure that has, you know, as a sequence of hex numbers or something, you're like, no, these are eight align and whatever, but for the most vast majority of time, you just want to say this is our code style. And what I have found is that the consistency is great. And it allows me to do refactorings in my code base without having to worry about all those other funny little rules where, you know, if you did a find and replace and you replace a name with a slightly shorter name, and you have like rules about things, either aligning or not aligning or fitting on a line or not fitting a line, you know, we've all come back to a code bases where you can clearly see things because.

Ben Rady

Oh yeah, where sed has come through?

Matt Godbolt

somebody renamed something, and that just goes away.

And that's a kind of a nice property, especially with IDEs that can do refactoring. And that also understand, uh, the format file, because I I'll do the refactor and I'll do it in the style as described by the formatting you've got. So that's very valuable to me. And final thing on that as well is that, um, it, it tends to make diffs between, uh, like long lived branches, less painful, as you will know that, like, if you have arrived at this, if you've like separated from, uh, the baseline, the, the, the main line, and you've been effectively applying small changes that are equivalent, you'll run the formatter on both sides. And you will basically agree on everything except for the past where you actually different and that's fine. And then you can like merge them back in together. And the, so, so I'm a, I'm a big fan of that, but I, you know, I just wasn't sure whether or not you consider this to be a, a linter. I mean, I'm straight and here I am like testing to see whether or not the thing that I'm talking about matches are very important as discussed carefully did, uh, decided to topic for today. Yeah.

Ben Rady

Right. Exactly.

Matt Godbolt

Oh my god, am I going off ticket? Off topic, or ticket.

Ben Rady

Uh, no, I, I, and anytime, I would say anytime, you can get automatic formatting in a consistent way, it's just, it's less things you have to worry about.

Matt Godbolt

Fewer

Ben Rady

Fewer. If you are, uh, you don't, you don't have to like spend any brain cycles at all. Thinking about the formatting, the one place where I think it gets weird, though, is if you have an IDE that does automatic formatting and the configure it, and then I think this is becoming less and less true, but, you know, there are, I think there are still situations where this might be true where the, the formatting operation can not be externalized. Right. So basically in order to enforce the format, you have to have the IDE running, like, you know, you can't enforce it in a build, or you can't use a different editor and have a command line tool that does it, like whatever you choose, um, to do your formatting and to check your formatting, uh, needs to have a like character for character equivalent that can be run automatically. It can be run from the command line, can be run in different tools,

Matt Godbolt

On the CI system, to make sure that you have confirmed all of these things. I wholeheartedly agree. I think that's one of the big, big deals, you know, I think when, um, you know, a lot of the, the, uh, the IDE, the jet brain's ideas always had their own idea about formatting. And for the longest time, I just used their defaults, but, you know, they are moving now more and more to where they're saying, well, here's the dot config file that tells me how to format. And I'll use that instead. You know? That's great. Yeah. Brilliant. Don't use your own format or use one that my friends who are using VI or, you know, edlin or whatever they're using. Yeah.

Ben Rady

It's about, it's just like tooling. You have to have intersubjective tooling. You have to have tooling that everyone, and every thing, like every part of your process can use to produce the same result. Right. Um, you know, they can follow the same steps and produce the same result. Um, cause if you don't, it's just, it's just going to create a whole bunch of headache that you don't need.

Matt Godbolt

Right. I think what you've, you've kind of implied in that also is that those one way to achieve intersubjectivity is to just mandate, these are the exact tools everyone must use. Right. So I could just say, Hey, everyone uses this tool, this editor, but you know,

Ben Rady

All using pycharm, we're all using Clion. We're all using IntellijJ Idea. Right.

Matt Godbolt

You know, visual studio code or VI with these. Yeah. That's one way of doing it. But I think you and I have realized that that's a great recipe to make unhappy developers. There's like one thing, the one thing you can do to a developer to make them feel up, uh, you know, not effective in their own, you know, not, not able to make the changes at the speed they would otherwise be able to do it is to make them use an editor they're not familiar with,

Ben Rady

It's like wearing someone else's clothes, no one likes no one likes doing that.

Matt Godbolt

It's a funny thing, and this is sort of slightly different. I know, but like, you know, I always used to think it was funny that people would buy expensive keyboards to, to work on until I bought one myself and went, oh my gosh, my life is a ton better. Now I don't have pains in my hands. I got like all those good things. I feel like I'm more effective in my job. And then it occurred to me. It's like, that's, that's, that's the primary way I communicate to do my job is through typing. And so it sh I should spend, if I'm going to spend any money on anything, I should spend it on a decent keyboard, a decent mouse. I have a decent editor that I'm happy with so that I can do my craft as effectively as I can in the way that I am happy with.

And I kind of got over that hump now that that's not like, oh, we should just be to pick up any old thing and get on with it. You know? Like it's like, you don't see, um, musicians wandering around just picking up any old, you know, cello and kind of going, oh, this will do, I suppose. I mean, I'm sure they can, you know, a good musician will be able to make good music out of anything, but you wouldn't expect them to as I'm. And I'm not saying that that's what I was thinking, but it was an epiphany moment I have. And it's certainly how I'm justifying, you know, hundreds of dollars worth of keyboards to, uh, to myself.

Ben Rady

Yeah. Yeah, no, and I mean, you know, uh, you will definitely have a hard time hiring if you're like, we use this IDE and this tool chain and, you know, only Mac books and all the other constraints that you put on there. It's like, you better be putting them on there for a good reason, because you're eliminating a whole pool of potentially really good engineers, uh, that will not work at your company because they can't use VI or whatever. Right.

Matt Godbolt

Yeah, no, that's an interesting, I mean, so anyway, going back to it, this is obviously you're saying that, uh, any kind of linting tools or formatting tools need to be intersubjective and, you know, the, the obvious way to say that they, they need to be a run headless on a CI server, if nothing else. Right. If I need that alone, that's a good reason

Ben Rady

That's like the minimum level. Right. Yeah, totally.

Matt Godbolt

Um, and yeah, talking about lint, you know, you obviously, you've mentioned about compiled languages and there are definitely, um, a million rules that you uh sorry, a mini, a million warnings that you can turn on in your C++ compiler. Some of which are a little bit a bridge too far, because they are very, very opinionated about certain things. But, um, there are definitely, um, linters that are useful to have run on your code as well. There is clang tidy, which I was getting confused between clang format and claim tidy because they both sound like they would basically do the same thing, but there are a number of things that, that can do static analysis that can do. There are a number of commercial products as well. Um, and the thing about these are this is where it becomes more subjective, very much, you know, like you can definitely say, like, there's, it's not the compiler's job to tell you that you shouldn't have a naked new, this is like an unmanaged new, that's not being held by a smart pointer.

So you're like, you're basically promising that the I'm going to write the code to clean up this object afterwards. I promise. And that's a completely reasonable thing it's allowed been allowed since the dawn of the language. Very, very occasionally it's what you want to do nowadays. It definitely should not be the compilers position to tell you that you can't do that is my opinion. But I think a linter could reasonably say under no circumstances, should you use a naked new anymore. You should always use one of the managed things, a smart pointer, a shared pointer, a unique pointer. In fact, always a unique pointer, never a shared pointer, but that's, that's a whole other talk. Um, and you know, then you can maybe elect to turn it off, but it's not really, I don't believe morally that that's a compiler's job. Um, it's a style thing, and this is certainly what the, the clang tidy way has moved.

Now. There's a, not a lot of companies have published their own guidelines there's Google guidelines. And then there's the LVMS own projects guidelines. And these are enshrined in rules that are inside of clang, uh, clang tidy. So there are a lot of those do say, yeah, yeah, you can't, you can't name this thing this way, you know, or you can't have, you can't use this idiom of the language. It's just not, you know, don't, don't do it. It's, it's widely accepted to have been a mistake. And we can't take it out of the language because of the way C++ is,

Ben Rady

But please don't.

Matt Godbolt

Probably, you didn't mean to do this and you obviously you can turn it off. So I just wanted to make a bit of a stronger case for the fact that I think linting and static code analysis. You know, these are, these are great safety nets to have around. Let's just assume the programmer is a hostile witness, make sure that we have tests for any changes they might make, make sure that we have styles, uh, guidelines that are enforced and make sure that every kind of thing that we can analyze can be thrown at them. And then I think it gives you a lot more confidence to make changes, which is a nice thing. Nice problem.

Ben Rady

Uh, there is, there is a trade-off there by the way, with, um, like, you know, basically build times or just deployment times, you know,

Matt Godbolt

interesting point.

Ben Rady

where, you know, all these static checks take time. Sometimes they're pretty fast, but sometimes they can take a long time. Uh, and you do have to kind of make a little bit of a trade off between cycle time and the sort of safety or correctness or formatting or other checks that you get putting those things in place. I mean, I think the ideal world is that you have, uh, and you know, we've been messing around with this a little bit recently, but you have a pre-commit hook that just does all of these things for you. So it's impossible to check in code. I think one of the I'm going to, I gotta get on my soap box for just a minute.

Matt Godbolt

All right. Hang on, I'm just getting comfortable.

Ben Rady

All right. I'm think. Yep, get a cup of tea, lay back. Um, so I think that the software development world lost something when we started building CI tools because in the very, very early days of CI, the way it worked was there was a machine that was the CI machine, and you either copied your code over there. Or you walked over there with a floppy disc, like you took your code

Matt Godbolt

Woah, very early days.

Ben Rady

Over to the machine and you integrated your code on that machine. And then when it was all integrated and the tests were all passing. Then you, you would leave it. And when people want it to update, they would go to the machine and they would get the latest version of the code and they would pull it back. Now, obviously that's a, you know, that's a really slow process. I'm not actually suggesting that anyone does that, but one of the benefits of that was that it was basically impossible to share code with other people that wasn't correct. What we have now with basically every single CI system that I've ever seen is you share the code and then the checks run. Right? Now, it could be that you're sharing it on a branch. Right. Which makes it a little better, but the model is still the same. Right. And you still have that moment when you take the branch and you merge it into master and then you find out whether or not it's correct.

Matt Godbolt

I think what you're sort of alluding to really is that sort of intersubjectivity is like, if, if, uh, if you can, if you can't develop, uh, confidence that your code works intersubjectively without first checking it in and saying, Hey, the first person who's going to find out is the CI machine. Oh. And anyone else who types "git pull" at the same time. Right. Then you've got a problem. Right, right. That's interesting. Yeah.

Ben Rady

And I fully grant the way that this problem was being solved before was with a really horrible lock that people would hold for hours. Right.

Matt Godbolt

While they integrated, yeah.

Ben Rady

So it's like, while they integrated, so it's not like it was better, but there was this dimension of it that was lost where it was like, you know, I, in an ideal world, what I would want to do is not have any CI at all. What I want is a completely hermetically sealed, infinitely, fast pre-commit hook.

Matt Godbolt

Not much then.

Ben Rady

that you could, that you could run. Yes. I know. Right. I'm not asking for much here that, that you could run, uh, on any developer machine and it would be completely intersubjective would not depend on the environment at all. And it would give you extraordinarily high confidence that the code met all of the, you know, the testing and the linting and all the other things such that it was impossible to commit code that was incorrect. And then you just push and then there is no CI because you have high confidence that the commits themselves can't be wrong,

Matt Godbolt

Proven at a different level. And, you know, it's a distributed proof as well, which means that, you know, computational stuff, you know, you, haven't got a single bottleneck and all that kind of stuff. That's really interesting. Yeah. Yeah.

Ben Rady

Um, you can kind of do this with server side pre-commit hooks, but

Matt Godbolt

You have all of like 5 seconds to do it, right?

Ben Rady

Github in particular has a timeout on them. If you run your own git server, you of course can do this. And I have done that actually.

Matt Godbolt

Oh, interesting.

Ben Rady

Um, yeah, there was, there was a small project where I actually like, I, it was kind of like a little bit of an experiment, but basically like the production deployment server and my git repository were all the same thing and I backed them up accordingly. Um, and so you would push to the server, it would run the build in a pre-commit hook that took as long as it took, it didn't really matter. And then just deployed right onto that machine, restarted the services and did all that. Uh, and like, that was my only repository. So it was sort of like the, the Heroku style of git deployment, except the production server was also the git repo. Um, and you know,

Matt Godbolt

Interesting

Ben Rady

and I would take frequent backups and snapshots of that. And that was it. That was all I had. Um, you know, again, I'm not recommending that as a good idea

Matt Godbolt

No, but as an experiement. For doing yeah, no, I get it.

Ben Rady

It gave me this property, which was like, you know, you can't share code that isn't both correct and in production.

Matt Godbolt

Right. Interesting. One, I guess, you know, you alluded to this earlier about the branch, but, you know, enabling, um, requirements of a PR in say something like github, um, that gives you some of that ability. You are still using the fact that you're pushing it to some other place as a sort of, uh, intersubjective test, then, you know, you get it reviewed. And then if you don't allow merges without the passing of a CI, then you've kind of reclaimed that. But, uh, you know, I think probably what you're alluding to is something that we've seen at work a bit, which is that if your tests take too long or too hard to run locally, it can be quite easy to start using a pull request as a crutch for, uh, maybe you just run, can someone else run my tests for me? And that's not necessarily a bad thing if you've got other things to be getting on with, if you like, okay, my tests take 15 minutes because there are a whole bunch of really complicated integration tests. And I want to move on to the next thing. So I'm going to push it to a branch and then I'm going to move myself to a different branch and go, and, and I might machine is not bogged down running these complicated things, but I think, you know, it's sort of, obviously it would be much nicer if you had your infinitely fast pre-commit to do it, run all of these integration tests and you wouldn't have to think about that kind of thing. You wouldn't have to context switch so much. Yeah.

Ben Rady

Yeah. I definitely, I definitely, this is maybe just a thing for me, but I definitely had this sort of like idealistic mode that I have experienced in like brief moments and I never let go of it. I, don't always kind of like all of the tools and all of the techniques that I, that I wind up seeing, I'm always sort of comparing to the sort of platonic ideal of, you know, infinitely fast feedback loops and all these other things. And I'm like, yeah, okay. I kinda get why we need to do this, but let's never lose sight of the fact that it's not what we really want. Yeah,

Matt Godbolt

Yeah, yeah. Yeah. One day I'll get you working on some C++ with me, and then you'll suffer for that idealism.

Ben Rady

I did a little bit of that, but I know. Yeah. I mean, that's, that's definitely a world where I'm just like, man, this is, we've got, there's a pretty big gap.

Matt Godbolt

Yeah. That'd be a better way of doing this, right. Yeah. Yeah. So, you know, our original goal and topic was linters, uh, I, you know, we covered a little bit of C++ and some Python. Uh, have you ever had an experience of other languages, um, JavaScript or

Ben Rady

I've used some JavaScript planters? I've used some Java linters um, I definitely, you know, it's the same sort of philosophy, but I am definitely in the camp of always turn on all the compiler warnings And then just do whatever they say. Um, one of the things that I wanted to ask you is whether or not you had ever run across any domain specific linters.

Matt Godbolt

oh, um, I, well, so clang tidy essentially has some of that built in, um, you know, like, you know, so you could consider like Google style guide as being domain specific and, and the LLVM code base style guide is domain specific. Now I know also there are things like MISRA, MISRA C, which has standards for the automotive industry that say, you just can't do these things, right. You just, this is not allowed you can't ever do this. This is not, you know, those kinds of levels of things. And I believe that there are rule sets for those. And if not there, I believe there are commercial tools that will basically run over your code and tell you, yeah, you, you did something that is this disallowed by MISRA, you, you downcast a 32 bit value into a 16 bit value without checking to see if it was truncated. You know, those are the kinds of things that you might want to say, reasonably, is not a good idea.

Ben Rady

Yeah, yeah.

Matt Godbolt

There are also, I mean, an interesting sort of corollary to that is, um, there are now, um, something called the guidelines support, sorry, the, the C++ guidelines, which are sort of a semi norm. It's not normative. It's not part of the standard, but some of the people that are heavily involved in the standard are behind it. Some of the sort of big names of C++, and they've kind of sounded like these are definitely rules that we think you should follow, right? And you basically do this by default. You have to have a reason to not do things this way. There are clang tidy rules for those as well, right? To say, like, please turn on all the GSLs that you can find, sorry. GSL is the name of the guidelines, support library. And there. So they've published a library that says, you know, this is a way of casting, a number from 32 bits to 16 bits, and we will throw an exception if it does fall outside of the bounds of what can be represented in a 16 bit number.

And the linter is in cahoots with the library. And we'll say, okay, if you are doing this through that function, that's fine because I know that it's covered, but otherwise I will say, no, no, you can't just assign this value here. And of course, C++ has always been very lackadaisical or very relaxed about you passing, you know, 12 into a function that wants a char. And you're like, well, okay, I can see that 12 is not going to overflow a char, but in general, 12 is an integer and an integer is probably bigger than eight bits. And so the char could overflow. And maybe I should be checking that. Now, obviously the thing about C++ is that you want performance as well. So sometimes you want to be able to say, no, I'm doing this on purpose. And I'm promising, Scout's honor that this won't happen at runtime.

And so you have to use a different version, which again, tells the linter look, I'm doing this on purpose. It kind of bakes in the linter rule that says, no, this is fine. And so that's an interesting thing, right? You're using a language to almost build a DSL of like, these are things that I'm telling you on purpose. The language has always been fine with. Um, and it sort of almost builds on something. Now I'm going to go, I'll go off on one here. But you know, it builds on something that when C++ was came around, um, you know, you remember C casts, you know, where you just put something in parens and say like, this is an int, You do paren int x. And it's like, Hey, there you go. It's now it, now it's an integer. And the problem with that is that you can cast pretty much any single thing to any other single thing.

And the same operation was used to say, no, this is an integer. And I want to pass it as a floating point value on purpose, or, um, this is a pointer to void, which is just like a random address. And I'm going to cast it to some really complicated structure with behavior, like an actual objects instance type. And you're like, wait a second. Those are very two very different operations. One is just reinterpret the data. Sorry, not reinterpret, but actually do a conversion. I know that that construction is going to run. That's going to turn it into a float. Another one is like, just tell the compiler internally, by the way, um, just treat this memory address as if it's containing a completely different type of object. And when C++ came in and with the sort of like complicated virtual hierarchies of objects, as you were casting backwards and forwards between say, um, objects that were in a, uh, an, a hierarchy, uh, and is-a hierarchy then potentially there were some fix-ups that were needed to be done.

Like, oh, you know, like, Hey, this is, I mean, don't use multiple inheritance, but if you did use multiple inheritance and you were casting up and down to the two different base classes, potentially things needed to be fixed up. And so that same parens cast is now going, oh, it's not actually a, uh, uh, uh, Bob, it's an Ian. And now I need to add 16 to like the address of it. So there's an added, hidden in there as well. The problem with the C style cast is that it would, it would use whatever information it had at the time to do the best effort of what it thought it was. So if it didn't know that Bob and Ian were actually related in any way, because it hadn't, it only seen the declaration of Bob and the declaration of Ian, it would just go fine.

They're the same thing. Fine. You told me this, but if they were actually, if had seen the class definitions that says, oh, they both inherit from two different, you know, somewhere up in the, uh, further up the hierarchy, then it would do some work. So, sorry this is a very long sidebar.

Ben Rady

This is good. This is good.

Matt Godbolt

So when, um, when C++ came along later on in the sort of the simplest plus, uh, I just say this was actually, I will make no, no bones about when this came up, but very early on in my experience in C++ plus, there were these new style casts, static underscore cast, dynamic, underscore cast, reinterpret underscore cast and const underscore cast. They have different powers. And so if you did a static cast, you're saying, I know these are related types. You can do a conversion from one to the other using knowledge like that will allow me to go from an int to a float, a float to an int.

It will allow me to go from Ian to Bob. If the compiler knows that they have got an inherited base class, it would be an error. If it didn't, it would say, like, I don't know that these are related. And so therefore it would stop. Yeah. And so, um, those kinds of things, they look like function calls, static, underscore cast, template, parameters, the thing. And so eeerp all the way back to the beginning, now, the GSL things that are like, Hey, narrow cast or narrow look like the built-in types in the language, which is just a function call that does this for it. So there's kind of a precedent for it I suppose is where I'm going with this.

Ben Rady

Interesting. So we need to be, what you're saying is we need to build a, a custom linter that can check for these kinds of relationships between Bob and Ian, and we should call it cahoots. Because then because then it'd be like, you can't cast that. No, it's fine, Bob and Ian in cahoots.

Matt Godbolt

Right. Well, that's, that is kind of what the static cast is doing rather unfortunately. But yeah, it's a, it's a funny old world. Yeah. In cahoots. Oh Man. I think

Ben Rady

It's right there. Cahoots dot config. It's right there. They're right there.

Matt Godbolt

Well, I guess that's a linters thoroughly talked about and uh, code formatting and random C++

Ben Rady

Yes. And rants about how CI used to be back in the 19th century.

Matt Godbolt

I was going to say that my earliest experience with CI was a CI server. I wrote myself in Python, early, very early versions of Python. And I actually came across the code. The other day was hilarious to look through it and have a laugh. But one thing I'd forgotten that I was reminded by that is that I had bought one of these, um, um, an outlet that I could control programmatically through the serial port on the CI machine. And I had had a, uh, green lava lamp that was on when the build was green. And then I had a red spinning, like actual disco, like a police thing for when it went red. Um, which was a great idea. I had a great fun, you know, getting, we'll only have to get the protocol to work over the serial cable to get to talk to this funny device and putting it in there. And as you might have guessed, the red spinning light lasted about three minutes before it was unplugged and removed.

Ben Rady

I think I even have, do I have, oh, I have.

Matt Godbolt

All right. Okay. All right. I have to make I'm amusing myself here as Ben, uh, unseen is rushed off into the background to his, uh, shelving and has come back with, drum roll.

Ben Rady

This is exactly what this is.

Matt Godbolt

Oh my gosh. We are the same person.

Ben Rady

Here's. Here's the cable, a USB-B cable. Here's the power supply.

Matt Godbolt

Little flashing light.

Ben Rady

Here's the little on/off switch.

Matt Godbolt

That's amazing

Ben Rady

It does exactly the same thing. We are. This is two's compliment man. We just branched back. We branched apart came right back together.

Matt Godbolt

We're in cahoots. All right. My friend. Well, we'd better stop there because I don't think we can top that.

Ben Rady

Yeah, sounds good.

Matt Godbolt

I'll see you next time. My friend.

Ben Rady

Yep, see you later.

Transcript source: Provided by creator in RSS feed: download file
For the best experience, listen in Metacast app for iOS or Android