3 ms·
I very much disagree with you. "starts_with_foo" is a horrible name, because it only says how it is implemented, but doesn't convey any meaning or the intention
by Ma8ee 7y ago
I very much disagree with you. "starts_with_foo" is a horrible name, because it only says how it is implemented, but doesn't convey any meaning or the intention of the function. When I read the code, I have to paus and think about why we do this. When I see a name like "is_foolike" I should have good enough understanding of the code that I know why we want to know if something is "foolike", and at that point, I should not have to worry about how it is implemented. It is only if I got reason to believe that there's something wrong with the function or when I review that particular function that I need to worry about the implementation details.
In addition, if we for some reason want to change what we mean with foo-like (say to "contains("foo"), we suddenly have to change all calls to the function, in addition to the defintion.
- kerkeslager 7y ago> "starts_with_foo" is a horrible name, because it only says how it is implemented, but doesn't convey any meaning or the intention of the function. Two questions for you: 1. If `starts_with_foo` only communicates how it's implemented, what about `starts_with_foo(x)` communicates to you that it's implemented as `x.startswith('foo')` rather than `x[:3] == 'foo'`, or some other implementation? 2. If the intention of the function isn't to test whether x starts with 'foo', how is this not a bug?
- Ma8ee 7y agoYes, it only says that we are checking that the first three characters are 'foo'. Exactly which commands you are using is irrelevant. You are telling us what we are doing on a too low level. With your logic anything that doesn't spell out exactly which assembly language commands that are used won't be implementation details What is a bug? If the name of the function is IsFoolike, the definition of the function will be the authorative place in the code that tells us what "isFoolike" means. Then it is a semantic question if that is a bug or not. What do we mean when we say that something is Foolike?
- kerkeslager 7y ago> Yes, it only says that we are checking that the first three characters are 'foo'. Exactly which commands you are using is irrelevant. You are telling us what we are doing on a too low level. With your logic anything that doesn't spell out exactly which assembly language commands that are used won't be implementation details Nothing in `starts_with_foo` describes what commands are being used--it describes what it does, not how it does it. With your logic, telling what the function does at all is too low a level. > If the name of the function is IsFoolike, the definition of the function will be the authorative place in the code that tells us what "isFoolike" means. Okay, so why not just name your functions, `aaaaa`, `aaaab`, `aaaac`, etc.? If the name of the function is `cdyfj`, then the definition of the function will be the authoritative place in the code that tells us what `cdyfj` means. Aren't you worried that `isFooLike` gives us too much information about the implementation? After all, the string "foo" is in the implementation. What if you want to test for "bar" later? Then you'll have to change all the places where `isFooLike` is used, in addition to the definition! > What is a bug? 1. You're claiming that the name should tell us what the intention of the function is. 2. You're claiming that the intention of the function isn't `starts_with_foo`. 3. The function tests to see that the string starts with 'foo'. The only way all three things can be true is that the intention is if the function does something it's not intended to do. That's the definition of a bug. > What do we mean when we say that something is Foolike? The fact that nobody could possibly answer this question is exactly the problem I'm pointing out. You might as well just name the function `cdyfj`, because `isFoolike` doesn't actually give you much more information than `cdyfj` does.
- Ma8ee 7y ago> With your logic, telling what we are doing at all seems to be too low a level. No, we need to say what we are doing on the right semantic level for that part of the program. It is rarely describing exactly what we are doing, because then only function of functions will be to abbreviate common patterns of code. The main function of functions is to abstract. At this particular level, Foolike has a semantic meaning to the reader of the program who knows what a Foo is and what isn't. And in this particular version of the program we happened to implement it from the first characters of the string. But maybe later we decide that it anything that inherits from a Foo, or has the Foo interface, or just walks, but not necessarily quacks, like a Foo. And the reason I don't call the function some nonsense is because then it is hard for the readers of the code to understand the meaning of it. And it might not help even if the they read the definition of the function, because the definition isn't the meaning. It doesn't say anything about why it is interesting to know if the string starts with 'Foo' or not (which is, as I have mentioned, the problem with the name you suggested). >> What do we mean when we say that something is Foolike? >The fact that nobody could possibly answer this question is exactly the problem I'm pointing out. No, we already know what foolike means. It is part of the domain that we are working with. The people who wrote the code and the people who read the code are assumed to have enough domain knowledge to know what a Foo is, and they understand me when I say things "we better use a Foolike here, otherwise we'll get a Bar problem". Let's use a bit less abstract example. Say I implement the function NextInvoiceNumber(). My first implementation might be something like {return ++n} (because I'm making a proof of concept and I'm in a hurry). You seem to argue that a better name of the function would be something like AddOneToNAndReturnN(). But then the reader of the code won't understand what the purpose of the function is, because nothing says anything what n is good for and why we are interested in getting the next n. And the moment I start to add different number series for different articles and some of them increment with 10 and some with 100, the name AddOneToNAndReturnN() will be wrong. That will not be a problem for NextInvoiceNumber(), because that is perfectly normal for anyone who has done any work with invoicing. Invoicenumbers are part of the domain that the developer must know about.