Conor

We're not we can't have we can't have a 60 minute episode.

Bryce

Uh I I I I think that was great. I think that that that all should be part of this this episode.

Conor

Naming. Part part three. Welcome to ABSP the podcast, episode 10, recorded on January 27th, 2021. My name is Connor, and today with my co-host Bryce, we're gonna be wrapping up part three of our three-part series on baby.

Bryce

So so let me ask you about this. So um uh one thing we didn't talk about last time that I made a note about was um ordering in names. Um so let me give you a few examples of that. Um so the first is like um noun ver noun under bar verb versus verb under bar noun. Um like as an example, do you call a function apply under bar policy or policy underbar apply? Um and uh are those two even necessarily the same thing? And what really gets me here is I sometimes see code bases that do this inconsistently. Like they have one function in their API that follows the noun underbar verb, um like policy under bar apply. And they have some other function that uh follows the uh verb underbar noun um pattern. Uh and I don't particularly care which of those two you follow, um uh as long as you're consistent. I have a slight preference for phrasing it as something like verb underbar now and under underbar noun because I like my identifiers and my code to sort of read as like plain English. So like something like apply policy, like what does it do? It applies the policy. Um so do you have any thoughts on that?

Conor

Well, so this is uh this is great because this is like completely adjacent to one of the things I wanted to talk about. So um to first answer your question, I'm pr I've never actually thought about this um uh in terms of noun underscore verb verb underscore noun, but I'm sh uh in thinking how I would just write code, I think if I were to go look back, it was it's always uh verb underscore uh noun. Um especially because like I started my career in uh a mathematical domain, actual science, so there was a lot of like calculate underscore reserve or uh cal calculate underscore premium or determine underscore you know, insert something. So I think inevitably, yeah, if if right now I look back, it was it was it's almost verb underscore noun, but taking a step back, one thing that I thought was great, because I hadn't thought about it at the time, I heard it from Guy Davidson on a CPP cast episode, is the idea of um naming functions, verbs and nouns separately based on whether they are modifying or non-modifying functions. So there's a very classic pattern in Java and C, and I've even seen it in like Herb Setter's talks where he shows some reflection example of where we're generating methods for you, where you generate these getters and setters. So you have, you know, you have uh get value and set value. And guys guys' point was that you shouldn't ever need to prefix something with get underscore. If you're just retrieving something, you're not modifying. If it's if it's a non-modifying method, just drop the get. And anytime you have a modifying method, you should be using a verb.

Bryce

Uh to that, I I hate there's nothing I hate more than seeing uh like a function that starts with get, you know, under bar. It's just like it's it's it's unnecessary symbols.

Conor

Which was so so that's like when it comes to verbs and nouns, when you started talking about that, I was like, oh, is Bryce about to make my point for me? Um so I'm this is not it's not I just adopted, you know, the first time I heard it was Guy, he probably heard it from someone else. But I I really like that.

Bryce

Don't judge Guy like that. For all you know, Guy was the brilliant genius that invented this.

Conor

It's true. Well, we'll we'll give Guy credit, even if he did uh uh we'll see yeah, maybe maybe Guy will listen to this. We'll we'll add him on Twitter and he can tell us if he heard it from someone or he made it up. Um because I think it's a great rule.

Bryce

And I also I think on that Guy Guy, for the record, I am choosing to assume that you made it up. Connor's choosing to assume that you you just took it from somebody else.

Conor

Uh sure, sure, we'll stick with that. Um but on that episode, um, he actually made another point how you should prefix um uh predicates, which I had never even heard of that term at the time, with is and has. Um and so I think I asked him, you know, uh, can you define predicate? And that's just a function that returns a Boolean. Um and uh that whenever you have that, you should prefix it with is and has. Because I think that's what ended up happening, is that I said, what about what about functions that like is even? Because technically is is a verb, and he said, Oh, any function that starts with an is or a has is a predicate, and that's an exception. Anyway, so this gets back to sort of the noun versus verb. So you can comment on everything I just said, but I think putting the verb first is like it makes it more clear that the whole thing together is a verb when you're saying, you know, calculate reserve. Really the the key in those two words is calculate. And if it's actually a free function, so that it's n it's not like a non-modifying or modifying, like ideally it's a it's a pure function without side effects. And in that case, I actually I don't know what I prefer. Do I prefer calculate reserve or reserve? Because if you call it reserve, you just pass it the arguments. I don't know.

Bryce

So the uh the the that question about the predicate or that that mark of guys about the predicate functions is actually interesting, and that's one of the few patterns that's actually recomm that we act that's actually in the proposed recommendations for standard library design guidelines. Uh but I as as I uh uh mentioned a little earlier, um uh one of the things we uh one of the conclusions we came to when considering C library design guidelines uh in the C plus plus library design group last week was we want to try to avoid decorating names uh whenever uh it's not necessary. And by decorating names, I mean adding prefixes or suffixes just because just because a function or an identifier um is some class of thing. Uh uh sort of similar to the Hungarian uh uh naming convention where you embed the type of the thing into the name. Um but one of the ones that that we'd actually suggested uh uh did make sense was you know to have the is underbar for predicates. Um one of the examples that somebody pointed out was you know um the empty method on a lot of the standard library containers, it's kind of ambiguous whether calling vector.empty um empties the contents of the container or tells you whether it's um empty or not. Um and the standard library is actually like a little bit inconsistent here. Um so as an example of that, C's stdFuture um has a valid um uh method. Now that one's pretty unambiguous, you know, um uh that that tells you whether it's valid or not, unlike empty, which is a bit more ambiguous. But the concurrency TS proposes some additions to std future, and one of those additions is an isReady function. And I just find it amusing that um uh, you know, I could understand inconsistency between different classes, but it really tickles me that there's a proposed inconsistency within this same class, that we would have isReady, which would be one predicate, and valid, which would be another. Um and I I am inclined to say that like the world would have been better if stddvector had called it is empty. Um so maybe that's one of those rare cases where um uh the decoration is really truly useful.

Conor

So I thought that it was a widely acknowledged fact that empty was a mistake and that going forward we were always supposed to use isempty. I can't find it right now, but I know that there's two examples in the standard that have actually started using isempty. One of them is stdd file system, the other one I can't find right now.

Bryce

What is you're absolutely right that that is the policy going forward that that that and and that's what we were discussing last week was codifying it into an actual policy document.

Conor

What was interesting though is that the other day I was code reviewing someone's code, and we have um I think it's in uh the QDF um repository, so it's the open source library I work on. We have a device span and it had an empty um method. And whenever I see that, I comment, oh, let's prefer isempty. And I have some link somewhere where I link to, you know, this is a you know widely regarded mistake, and that going forward we should use isempty. And um I think we're gonna be.

Bryce

Although if we're gonna do that, we should probably all of the C standard library things that currently have an empty, we'd probably need to give them an additional isempty um so that uh people can consistently just use isempty. You know, it's a pain if you have to remember, hmm, does this thing have an empty or an isempty? And then it becomes even more of a pain in generic code.

Conor

Uh that's true. Um so yeah, it would be nice to get those. Um, but where I was going with that is that the the person I think it was Vucasan, I hope he doesn't mind me shouting out his name. His response was, oh, we're keeping it consistent with std span. Or and I was like, wait, what? Span added empty? I thought we were not doing that anymore.

Bryce

Um well span probably did it for the reason I just mentioned, which is span probably called it empty and not is empty because for consistency with um the existing things. Yeah. See, this is the problem with consistency, is that sometimes you have to like some I I I always say, and this is sort of like Bryce's law, I'd I'd rather be uh uh consistently wrong than inconsistent. What that that the idea that that you know like like what why is spans empty? Why does span have empty and not is empty? Because it would rather be uh uh uh consistently wrong instead of being inconsistent.

Conor

Are you sure you want that to be your law? I don't think I agree with like you're saying I I think you mean it in like a narrower scope that it comes across. Like I'd rather be consistently wrong. Like I'm I'm not gonna have any flexibility of thought on my opinions on matters. I'd rather just stick to my guns and uh be wrong than uh eventually be inconsistent and change my mind. That sounds like an awful law.

Bryce

I am I am happy with my law as uh as stated.

Conor

Are you sure? I'm gonna give you a couple episodes to think about whether you want this to be your law.

Bryce

I I will think about that. So so I have another story which uh I'll I'll give a shout out to my uh coworker John Bashan, who is actually my coworker at NVIDIA and also my coworker at uh Lawrence Berkeley National Lab where we used to work. And um we he when I we were both at Lawrence Berkeley, he was working on um this uh asynchronous runtime system. And uh uh whenever you have such a system, I I worked on you know one myself called HPX, you tend to have some set of functions that are asynchronous and that have some you know async um decorator on them. And in the code bases I had worked with, the async always came at the front. So you know you'd have async uh underscore reduce or async underscore transform uh etc. Um but in John's code base, if I recall correctly, he would call it like reduce um uh underscore async, uh transform underscore async. And I one time I asked him, hey, why do you why do you put it at the end, not at the start? And he told me, well, it it's I uh he thinks of it sort of like um uh grouping um that uh the uh he he wanted the uh most specific thing to be first. So, you know, the what's the most specific thing of a asynchronous reduction algorithm? Well, it's it's of the family of reduction algorithms. Um it's not uh of this, you know, that that's more fundamental than it being a member of the family of things that are asynchronous. So he sort of made an argument that the ordering of things in the name um said something about sort of the grouping uh or the categorization of those things. Um and I've I've also heard this claim made for things like code completion, that you know, if you call it async um underscore reduce and async underscore transform, then when you type async, you know, underscore, you're gonna get almost everything in your library. Whereas if you do it the other way around, then if you type reduce, you'll get autocompletion for reduce, just the synchronous version, and reduce underscore async and whatever other functions you have that are some form of reduction. And so I thought that was a very interesting notion that I I had never really thought much before then about um uh how the ordering of words in a name um could denote um a grouping, sort of sort of similar to namespaces, but um even just within the identifier itself.

Conor

Yeah, no, I I've actually spent a lot of time thinking about that because there are examples where that like it's an amazing design for exact for that exact reason that you end up with like a list of algorithms that are alphabetically sorted, and then you see, you know, zip underscore, zip underscore, zip underscore, and you you're clearly like, oh, okay, these are these are all doing roughly the same thing. However, you can go too far with it in some cases. So like in Ruby, there is a collection of algorithms, I just looked it up, each con so they each start with each underscore, each cons, each entry, each slice, each with index, and each with object. And I don't know what all these do, but if I were to if I were to uh ask you, what do you think each underscore cons does? Like, do you think you could guess? And our listeners can play along if you want. And and the point that I'm about to make here is that yes, they've they've family familyized these, you know, they put them in a group, but they've completely, in my opinion, obfuscated like what these do. And like the same named algorithms in other languages are completely different.

Bryce

Interesting.

Conor

In fact, I'll I'll give you a I'll give you a hint about each cons. Um the cons is a reference to uh an old language.

Bryce

Yes, so it's like a reference to to Lisp, right? Like to the operation where it takes the tail of a list.

Conor

Uh well, cons is basically your like your procedure that creates a pair. So like in Lisp, your linked list is just a bunch of conses.

Bryce

Oh yeah, yeah, yeah, yeah, yeah. Yeah.

Conor

Um but so I believe I can double-click just to make sure that I'm not wrong, that each cons, you pass it a integer, and it gives you the sliding window. Of the length of that. So like each cons 2 will give you adjacent pairs. Each cons 3 will give you a sliding window of length 3 where the step is 1. And so so this, yeah, this in most languages is called uh sliding or or windows or windowed. You know, Rust, I think, just added uh a couple different versions of this in their 1.48 or whatever the version that they're on. But yeah, so like I I completely agree that there are times where like prefixing everything with the same um with the same prefix is like a really good way to like have people explore the language and discover, oh look, there's a very similar algorithm I could use. In other cases like this, I think each with index isn't bad. I think that's just that's just basically it's called Yeah, that makes more sense. That that that it's called different things in different languages. The most common name is enumerate from Python, where you just you bundle each element with an index. But yeah, it's you I in this case I think they went too far. And it's really unfortunate because uh crystal, um, which is actually a language I think I first heard about from you, it's uh it's basically Ruby statically typed. Although I think Ruby actually just got static typing and like Ruby something point something. Um it's yeah.

Bryce

Thank you for that very informative comment.

Conor

Ruby static uh typing. 3.0 I'll guess. The state of Ruby 3 typing. I'll find I'll find out if it's it's been added and added to the show notes. Um I could be mixing up Scala 3 and Ruby 3. Um, because Scala 3, otherwise known as Dotty.

Bryce

See, folks, this is this is why you shouldn't learn, this is why you should have learned f uh only a few times and images and not a lot, because then you don't get them mixed up.

Conor

Touche or touche, fair points. Anyways, what was my what was my point here? Alright, Crystal is statically typed, supposed to have the performance of C version of Ruby. Um, but they they basically just like verbatim took all the algorithm names from Ruby. Whereas Elixir, which is basically like Ruby plus Erlang, um, they looked at all the algorithms, took the good ones, and then renamed the bad ones. So they didn't take any of the each underscore methods, they renamed them to like chunk um and and better names, which I think is the is the better design decision, you know. Learn from learn from languages mistakes, copy what they did right, and then you know, iterate.

Bryce

Yeah. What do you what do you think about uh about naming styles?

Conor

Well, so is this is this like snake case versus Pascal case versus kebab case? Well so um we'll we'll I'll answer that in a sec, because kebab case? I don't know what yeah, well kebab case is adjacent to um yeah, so there's well okay, let's let's answer this question. So we've got uh snake case, pascal, camel, and kebab case are like the four main ones. There's a couple other variants, uh, but I think those are the four main ones. Uh I think most people have heard of snake case, it's the underscores in between words. Pascal case, the start of each word is capitalized. Camel case is Pascal case, but the first word is lowercase. And kebab case, for any Lispers out there, um, they'll know what um kebab case is. It's where you hyphenate the the words. Uh I actually like kebab quite kebab case quite a bit.

Bryce

Although it does not work in a number of languages.

Conor

Uh it definitely doesn't work in a number of languages. But I I think snake case is my my preferred my my preference.

Bryce

I really strongly dislike camel case. I just think it's like super unreadable, and it just like it is jarring to me for the first word to not be capitalized. I and I just I want to understand why. Why should it why should the first word not be capitalized, but the rest of them should be. It just like Pascal case I can uh I can uh I'm at l I can be okay with because like it's consistently capitalized as the first letter of each word, like that's okay, but but no, I'm not okay with not okay with camel case.

Conor

I do not share, I mean, I'm I'm surprised actually that you have such uh not strong feelings about formatting, you know, you can do without, but then for for that first letter in camel case, uh that's where you draw the line. Either capitalize or don't capitalize.

Bryce

Um Yeah. Is there is there is there a style where you don't use underscores but you don't capitalize anything? Where you just mush everything together? Does that have a name?

Conor

Uh all lowercase? I don't know. We'll let we'll let our listeners, if that's a thing, tweet at us and we'll mention it.

Bryce

What what do you so so in C20, in the C standard for many years, the the names for things that were um the moral equivalent of concepts, we didn't have concepts in the language, but we had names for these sets of requirements. Those names were always they used Pascal case, um, which was nice because it made them distinct from the uh standard library identifiers, which were all used snake case. And uh when we added concepts, we were originally going to add the named concepts in the standard library as Pascal case, following the precedent of the named requirements that had been in C for many years, like um uh copy constructible or um uh random access iterator. Those names, you know, were would have been spelled in Pascal case. Um, but then there was a a fairly late decision was made uh To um make those concept names be snake case, um, which has led, I think, to some unfortunate um ambiguities. So for example, std colon colon iterator is the name of a concrete type from like C03 or C11. Whereas std colon colon random access iterator is the name of a concept. Um whereas uh uh with the Pascal casing, you had this, it was very visually clear when something was a concept versus a type because the concepts were in Pascal case and the uh the concrete types were in Snake case. But we we decided we didn't like that. And I personally think it was a mistake. I don't know what do you what do you think about it? Do you think it's confusing that uh the concepts use the same uh naming pattern or the same naming style as types? I I I did say earlier in this discussion that uh you know I'm not a fan of um you know these decorator type patterns where you have a prefix or a suffix or a particular style for things, but I guess in this case I felt it would have been a good idea to have concepts be visually distinct from types in the standard la in the C standard library.

Conor

Yeah, I mean I feel like that paper and that decision got made on either the first or the second committee meeting that I went to, and um I didn't spend most of my time in Lug, um, but I was I did sit in on a couple of the discussions. I did not have anywhere as near as a strong opinion as the people in the room. Um uh I think the biggest argument, if I recall, uh against mixing them was like this was breaking precedence for the first time ever, and it's although but but what but you could argue it was like it was gonna break precedence either way because it broke the precedence of the existing naming pattern.

Bryce

There was a thing that was a referenced in the standard called you know random access iterator in Pascal case. It wasn't a uh programmatic concept because those didn't exist yet, but the the name of it now is inconsistent with the what we used to use to refer to this set of requirements. So I I I think, and I wasn't in the room at the time of this discussion because I was chairing a different room. But if I had been in the room, I would have made the argument that um there was gonna be an inconsistency either way, and we should have should have gone with the one that was gonna be less ambiguous and that was gonna follow what the existing name of these things.

Conor

Well, so so although what you say is true, I think the argument was coming from trainers um or you know, people people whose primary occupation and and are very exposed to um you know teaching C. And you know, you mentioned that's that's the way it is in the standard. I don't think the majority of C developers are working their way through the standard. And then you can make the argument, well, it's not just the standard, it's also in EOP uh elements of programming.

Bryce

But I don't think it was just in the standard. Like if you go and look on C like you know, CPP reference uses it. I I think there's a lot of code that that uh there's a lot of pre-C20 code that referred to some of the core concepts from the standard using the Pascal case naming that the standard uses. I'm sure there's a lot of codes out there that refer to this type is copy constructable Pascal case.

Conor

So, you know, yes, you can make all those arguments, but I think the argument, and so this is the thing, is I'm doing a poor job because I'm trying to make someone else's argument for them. Um but I think their point was like this is it's different, and this is gonna be one more thing that I have to teach that like um people are gonna are are, you know, uh whether it's students or whether it's professionals that are, you know, uh getting training um or just learning the language for the first time, they're gonna ask, you know, oh, why is this different? And it's a short answer, it's a concept, but I think from the educator's point of view, like if they're if there's one thing that they don't need to teach, or like they don't need to add to a bullet list of points of like, you know, insert, why is this different, that's preferable.

Bryce

But now they do have to teach people that std. colon colon iterator isn't the name of the of a concept, even though std. colon colon random access iterator is the name of a concept, and a bunch of other little cases like that. Like, I don't remember what it was for there was another one around Boolean that was very odd.

Conor

Yeah. Anyway, so we we should get someone on that voted uh voted for it, and then you can debate them. But yeah, we have to go. But the last thing I want to say before we wrap this episode up is that the same way that Lisps uh have a very sort of unique kebab style for for some of the Lisp dialects, I actually think that Lisps have a feature that I wish a lot of other programming languages had when it comes to the naming of predicates. Do you know how uh you denotate a predicate function in a Lisp? Or in most Lisps?

Bryce

Uh I don't.

Conor

You use a question mark. Um, which I actually really, really like because instead of having to say um is empty or has, you know, feature uh which don't share the same you know prefix, all of the predicates end in a question mark. So instead of you know is uh is empty, it's just empty question mark. And then uh if if you have, you know, what's another one? Is even. So yeah, like even and positive are not like is even or is positive. It's just even question mark, positive, question mark. And I think that's super, super nice because there is actually some cases where is and has, you know, the is underscore and has underscore aren't aren't the right prefixes, and then you sort of have to come up with some awkward prefix that doesn't really work great. But if you can just add a question mark on the end, it becomes immediately clear, oh, this is just a predicate, and I can use something simple.

Bryce

That's interesting. Yeah, it's you know, it it it I wonder I I think that that uh it would be interesting to see what uh a language like C would have looked like if we could have had a wider set of identifiers, uh a wider set of characters and identifiers. Like if we could have had question marks and identifiers um or exclamation points and identifiers, um, what styles and would that have led to? Because I know I know languages that do allow question marks or exclamation points in identifiers, um uh you know, those are often used to convey to denote certain types of uh of functions, etc. Like I I generally think that languages benefit greatly from having as many characters in the identifier set as possible without, of course, restricting, you know, what you have available as operators, etc.

Conor

Yeah, there's uh like Smalltalk is a language that you can define uh binary operations as any combination of like a set of like 20 different ASCII characters, so you can come up with some really, really cool things that yeah, you can't you can't do anything. You're you're limited by the set of what binary operators are overloadable in C, which we do have a bunch, but you can't just like create one out of thin air that doesn't exist before, whereas in other languages you can.

Bryce

Yeah, it's it's um I I'm always jealous of languages that can invent uh you know operators like that. Um I think it's a very powerful feature. It's one that I often wish I had access to in a language like C.

Conor

Julia actually I just learned um you basically can define like any Unicode operator that you want. Because it's a scientific language, and so a lot of like uh domain-specific applications, they want to have like a logical and that's you know the upside-down V and a logical or.

Bryce

With a lot of C compilers, you can get away with using Unicode in your function names, not for operators, but in function names. And so uh there are some shenanigans you can get away with there. If you follow JF Bastion on Twitter, um you're probably familiar with this.

Conor

Yeah. I've also I think it was in a meeting Ciz I I saw it was just uh smiley face emojis. Um it was, you know, what is his output?

Bryce

Uh yeah, I remember that too. That was uh we were there together. That was 2019. Man, you remember that? You remember that? That that was a crazy month. We were on the road for like six weeks. Um that was when we went to Tyreek.

Conor

You were you were on the load, you were on the road longer than I was.

Bryce

Uh yeah, that was that was uh I miss those days.

Conor

I miss those days. How long has it been since I've been on a plane? It's almost uh I think 11 months or 12 months now.

Bryce

Yeah, it's yeah, it's it's gotta be yeah, because it would have been Prague last year that we went last went on a plane. Oh man, I miss it. I miss it.

Conor

It's alright, the vaccine. My my partner just got her second vaccine yesterday.

Bryce

Oh awesome. My uh my uh grandfather and my dad are getting their second uh dose this week. My grandmother finally got hers, so now all of the all of the people over 80 in my immediate family have gotten one, so I'm happy about that.

Conor

Yeah, it's awesome. It's uh it's happening slowly, but hopefully 2022 we'll be able to meet up in person. That brings our naming trilogy to an end. We hope you have a great day, and we'll see you in the next episode.