7

Based on this question. Would you consider it best practice to create a function that does the opposite of an existing function just to give it a different name.

Example: If you already have bool In(string input,string[] set) which returns true if the the array set contains the string input and false otherwise, should you create a function like bool NotIn(string input,string[] set) which returns false if the string is in the set or true otherwise?

3
  • 11
    If someone calls themselves a programmer yet can't recognize what !someBool means at a glance then, well... they have a serious problem.
    – Ed S.
    Apr 15, 2011 at 21:53
  • 1
    Ed, I agree with you 100% and up-voted your comment, but I could see the use for both 'IsIn' and 'IsNotIn' methods if creating an API that utilized method chaining, similar to what the major mocking frameworks use today. For example If(object).IsNotIn(IEnumerable<T>).Then(Action<T>).Etc()... In this case an 'IsNotIn' method reads more cleanly and avoids parentheses nesting such as (!If(object).IsIn(IEnumerable<T>)).Then(Action<T>).Etc(). Just a thought. Apr 16, 2011 at 2:50
  • 1
    IMHO this is a one way street, going the opposite direction of where you think: Should you come upon a boolean with "not" in the name, you should try and get it into a "positive" name. E.g. turning isNotValid() into isValid() is a good thing to do, but the other way around it's not.
    – R. Schmitz
    Jul 16, 2019 at 10:04

7 Answers 7

25

No, certainly not best practice at all. All languages that I've ever used have a "not" operator, so use that. It's very clear, very easy to read and it saves writing essentially duplicate methods.

E.g. the meaning and the intention of the code below seems to me to be pretty clear:

if (!In(...)) 
{...}

Whilst if I saw a bit of code like this:

if (NotIn(...))
{...}

I'd think, "this is probably the opposite of In(), but if it was why didn't they just write !In()". So, I'd end up having to check the docs or the code :(

Obviousy it is not syntacticaly wrong to write such a method, it's just not idiomatic (in any langauage I''ve ever used).

Edit As Amir mentions on the comments, this is the kind of thing that might well be covered in coding standards, along with how to name a method (or property) that returns a boolean value.

7
  • @Steve That mistake can be avoided by coding standards. Apr 15, 2011 at 21:47
  • Sorry, I'm not with you, what mistake?
    – Steve
    Apr 15, 2011 at 21:50
  • @Steve The misunderstanding can be avoided if there are code guidelines that everyone in the team are aware about. Apr 15, 2011 at 21:53
  • Ah, OK, I see. I thought you meant there was a bug in my pseudocode:-). It's a good point, I'll add to my answer if you don't mind.
    – Steve
    Apr 15, 2011 at 21:54
  • @Steve no problem at all! :) Apr 15, 2011 at 21:57
9

In functional languages, this is may be sometimes convenient for predicates that are passed to other functions, i.e.

filter (`notElem` xs) ys

looks nicer than

filter ((!) . (`elem` xs)) ys

This Haskell example demonstrates that the syntax rules may force one to write 4 extra parentheses just for a simple negation. Because clarity diminishes overproportional to the number of parentheses, it is good to have notElem.

1
  • 1
    You beat me to it. Generally creating such functions is silly, but this is definitely an important exception. I do it all the time for functions I pass as predicates to other functions.
    – dsimcha
    Apr 15, 2011 at 23:44
7

As long as they are mutually exclusive you shouldn't. You should however do it, if you'd have 3-valued logic (True, False, unknown). Which happens to be typical for example in SQL.


(source: wikimedia.org)

4
  • 1
    Not sure how this justifies having a separate function that just returns the negated result of the first. Apr 15, 2011 at 22:04
  • Props for including the truth table.
    – Jim Dennis
    Apr 15, 2011 at 22:44
  • 2
    @Daniel - That's the point, If In() returns a tri-state then !In() may not be the same as NotIn(). If it is some sort of cached collection, which tells you unknown so that you can chose whether to perform some expensive lookup, then it might know when things are definitely not present, but not know when they definitely are, or some other asymmetry.
    – Mark Booth
    Apr 15, 2011 at 22:54
  • Another related possibility is that two questions which might always have opposite answers in an existing version of a class might have different answers in future versions. For example, IsWritable and IsImmutable might behave as opposites for present versions of a class, but future classes might reasonably return false for both (e.g. if the object represents a read-only view of mutable data which is owned by some other object that could change it). While the combination of properties would have three states, each would have a well-defined Boolean value.
    – supercat
    Jan 8, 2013 at 21:13
5

No, you definitely shouldn't. A negation operator is sufficient.

However you may want to think first what is the most "popular" use of this function - to ask for a direct answer or for a negated one. Then you do the most used check by default.

For instance, if you have a method Question.IsOpen() and you observe that you're mostly calling it along with the negation like !Question.IsOpen() you could reverse it into Question.IsClosed(). Here you notice how it is quite possible to find a separate word for a negated situation.

2
  • "A negation operator is sufficient." - if the only thing one can do with a function is to call it with all arguments applies, this may indeed be so. But this is not the case in all languages - look at my post for an example.
    – Ingo
    Apr 15, 2011 at 23:44
  • Having both IsOpen and IsClosed may often be a good idea, if there's any possibility that an object might be in a state where it is not presently usable, but is also not ready to be abandoned, especially if there may be significant time between when an object is asked to open and when it becomes ready for use.
    – supercat
    Jan 8, 2013 at 21:17
0

If I have a property that I'm binding to in say an mvvm project in WPF, then I create explicit versions of properties that are the direct opposite of others. Though, I prefer to use fairly detailed symbols of what the meaning is rather than just prepending 'Not' in front of the opposing property name. I guess if you're talking functions and pure code I'd probably agree that you should use proper not operators instead.

0

I would say it depends. Ruby, for instance, encourages this due to readability/clarity > all else. It's common practice in a Rails app to wrap up the negation operator in a method to make the code more English-like if it doesn't "flow" naturally using the unless keyword.

5
  • 1
    I still don't see how !InSet is any less clear than NotInSet. Also, I've never used Ruby so I may be completely misreading this, but "unless NotInSet" seems much LESS clear than "if InSet"
    – Kevin
    Apr 19, 2011 at 14:45
  • The Ruby intent is that if it doesn't "sound right" to have unless in_set (which is a bad example because that does sound right) you would make a not_in_set function so you could write if not_in_set instead. It depends on the specific context; I was merely stating the Ruby convention is to use these reverse boolean functions when it would help readability/express intent. Apr 19, 2011 at 14:51
  • Why the downvote? Ruby (and specifically Rails) does encourage this sort of thing; someone might disagree with it, but what I stated was a factually accurate answer. Apr 22, 2011 at 15:00
  • Don't know who down voted you or why, but you get an upvote from me. While it still doesn't seem to make sense to me, if it is common practice in the language you are using, then it would make sense to at least consider it for consistency's sake.
    – Kevin
    Apr 22, 2011 at 15:13
  • @Kevin Thanks :) I notice a lot of people on these sites will downvote something just because they don't agree with it, even when the answer is the right one. Apr 22, 2011 at 15:16
0

I agree with others here that suggested the use of the not operator, when you are using existing libraries.

When you are writing your own functions, I would name them such that callers can author their conditional with positive semantic. For example, allow them to write if(lightIsOn) by naming your function lightIsOn(...).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.