Is a new Boolean field better than a null reference when a value can be meaningfully absent?












35















For example, suppose I have a class, Member, which has a lastChangePasswordTime:



class Member{
.
.
.
constructor(){
this.lastChangePasswordTime=null,
}
}


whose lastChangePasswordTime can be meaningful absent, because some members may never change their passwords.



But according to If nulls are evil, what should be used when a value can be meaningfully absent? and https://softwareengineering.stackexchange.com/a/12836/248528, I shouldn't use null to represent a meaningfully absent value. So I try to add a Boolean flag:



class Member{
.
.
.
constructor(){
this.isPasswordChanged=false,
this.lastChangePasswordTime=null,
}
}


But I think it is quite obsolete because:




  1. When isPasswordChanged is false, lastChangePasswordTime must be null, and checking lastChangePasswordTime==null is almost identical to checking isPasswordChanged is false, so I prefer check lastChangePasswordTime==null directly


  2. When changing the logic here, I may forget to update both fields.



Note: when a user changes passwords, I would record the time like this:



this.lastChangePasswordTime=Date.now();


Is the additional Boolean field better than a null reference here?










share|improve this question




















  • 49





    This question is quite language-specific, because what constitutes a good solution largely depends on what your programming language offers. For example, in C++17 or Scala, you'd use std::optional or Option. In other languages, you may have to built an appropriate mechanism yourself, or you may actually resort to null or something similar because it's more idiomatic.

    – Christian Hackl
    Feb 26 at 8:53






  • 16





    Is there a reason you wouldn't want the lastChangePasswordTime set to password creation time (creation is a mod, after all)?

    – Kristian H
    Feb 26 at 19:10













  • @ChristianHackl hmm, agree that there are different "perfect" solutions, but i don't see any (major) language though where using a separate boolean would be a better idea in general than doing null/nil checks. Not totally sure about C/C++ as I haven't been active there for quite a while, though.

    – Frank Hopkins
    Feb 26 at 20:17











  • @FrankHopkins: An example would be languages where variables can be left uninitialised, e.g. C or C++. lastChangePasswordTime may be an uninitialised pointer there, and comparing it to anything would be undefined behaviour. Not a really compelling reason not to initialise the pointer to NULL / nullptr instead, especially not in modern C++ (where you wouldn't use a pointer at all), but who knows? Another example would be languages without pointers, or with bad support for pointers, maybe. (FORTRAN 77 comes to mind...)

    – Christian Hackl
    Feb 27 at 9:30











  • I would use an enum with 3 cases for this :)

    – J. Doe
    Feb 27 at 16:06
















35















For example, suppose I have a class, Member, which has a lastChangePasswordTime:



class Member{
.
.
.
constructor(){
this.lastChangePasswordTime=null,
}
}


whose lastChangePasswordTime can be meaningful absent, because some members may never change their passwords.



But according to If nulls are evil, what should be used when a value can be meaningfully absent? and https://softwareengineering.stackexchange.com/a/12836/248528, I shouldn't use null to represent a meaningfully absent value. So I try to add a Boolean flag:



class Member{
.
.
.
constructor(){
this.isPasswordChanged=false,
this.lastChangePasswordTime=null,
}
}


But I think it is quite obsolete because:




  1. When isPasswordChanged is false, lastChangePasswordTime must be null, and checking lastChangePasswordTime==null is almost identical to checking isPasswordChanged is false, so I prefer check lastChangePasswordTime==null directly


  2. When changing the logic here, I may forget to update both fields.



Note: when a user changes passwords, I would record the time like this:



this.lastChangePasswordTime=Date.now();


Is the additional Boolean field better than a null reference here?










share|improve this question




















  • 49





    This question is quite language-specific, because what constitutes a good solution largely depends on what your programming language offers. For example, in C++17 or Scala, you'd use std::optional or Option. In other languages, you may have to built an appropriate mechanism yourself, or you may actually resort to null or something similar because it's more idiomatic.

    – Christian Hackl
    Feb 26 at 8:53






  • 16





    Is there a reason you wouldn't want the lastChangePasswordTime set to password creation time (creation is a mod, after all)?

    – Kristian H
    Feb 26 at 19:10













  • @ChristianHackl hmm, agree that there are different "perfect" solutions, but i don't see any (major) language though where using a separate boolean would be a better idea in general than doing null/nil checks. Not totally sure about C/C++ as I haven't been active there for quite a while, though.

    – Frank Hopkins
    Feb 26 at 20:17











  • @FrankHopkins: An example would be languages where variables can be left uninitialised, e.g. C or C++. lastChangePasswordTime may be an uninitialised pointer there, and comparing it to anything would be undefined behaviour. Not a really compelling reason not to initialise the pointer to NULL / nullptr instead, especially not in modern C++ (where you wouldn't use a pointer at all), but who knows? Another example would be languages without pointers, or with bad support for pointers, maybe. (FORTRAN 77 comes to mind...)

    – Christian Hackl
    Feb 27 at 9:30











  • I would use an enum with 3 cases for this :)

    – J. Doe
    Feb 27 at 16:06














35












35








35


4






For example, suppose I have a class, Member, which has a lastChangePasswordTime:



class Member{
.
.
.
constructor(){
this.lastChangePasswordTime=null,
}
}


whose lastChangePasswordTime can be meaningful absent, because some members may never change their passwords.



But according to If nulls are evil, what should be used when a value can be meaningfully absent? and https://softwareengineering.stackexchange.com/a/12836/248528, I shouldn't use null to represent a meaningfully absent value. So I try to add a Boolean flag:



class Member{
.
.
.
constructor(){
this.isPasswordChanged=false,
this.lastChangePasswordTime=null,
}
}


But I think it is quite obsolete because:




  1. When isPasswordChanged is false, lastChangePasswordTime must be null, and checking lastChangePasswordTime==null is almost identical to checking isPasswordChanged is false, so I prefer check lastChangePasswordTime==null directly


  2. When changing the logic here, I may forget to update both fields.



Note: when a user changes passwords, I would record the time like this:



this.lastChangePasswordTime=Date.now();


Is the additional Boolean field better than a null reference here?










share|improve this question
















For example, suppose I have a class, Member, which has a lastChangePasswordTime:



class Member{
.
.
.
constructor(){
this.lastChangePasswordTime=null,
}
}


whose lastChangePasswordTime can be meaningful absent, because some members may never change their passwords.



But according to If nulls are evil, what should be used when a value can be meaningfully absent? and https://softwareengineering.stackexchange.com/a/12836/248528, I shouldn't use null to represent a meaningfully absent value. So I try to add a Boolean flag:



class Member{
.
.
.
constructor(){
this.isPasswordChanged=false,
this.lastChangePasswordTime=null,
}
}


But I think it is quite obsolete because:




  1. When isPasswordChanged is false, lastChangePasswordTime must be null, and checking lastChangePasswordTime==null is almost identical to checking isPasswordChanged is false, so I prefer check lastChangePasswordTime==null directly


  2. When changing the logic here, I may forget to update both fields.



Note: when a user changes passwords, I would record the time like this:



this.lastChangePasswordTime=Date.now();


Is the additional Boolean field better than a null reference here?







null boolean






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Feb 28 at 5:16







mmmaaa

















asked Feb 26 at 7:42









mmmaaammmaaa

2,62741723




2,62741723








  • 49





    This question is quite language-specific, because what constitutes a good solution largely depends on what your programming language offers. For example, in C++17 or Scala, you'd use std::optional or Option. In other languages, you may have to built an appropriate mechanism yourself, or you may actually resort to null or something similar because it's more idiomatic.

    – Christian Hackl
    Feb 26 at 8:53






  • 16





    Is there a reason you wouldn't want the lastChangePasswordTime set to password creation time (creation is a mod, after all)?

    – Kristian H
    Feb 26 at 19:10













  • @ChristianHackl hmm, agree that there are different "perfect" solutions, but i don't see any (major) language though where using a separate boolean would be a better idea in general than doing null/nil checks. Not totally sure about C/C++ as I haven't been active there for quite a while, though.

    – Frank Hopkins
    Feb 26 at 20:17











  • @FrankHopkins: An example would be languages where variables can be left uninitialised, e.g. C or C++. lastChangePasswordTime may be an uninitialised pointer there, and comparing it to anything would be undefined behaviour. Not a really compelling reason not to initialise the pointer to NULL / nullptr instead, especially not in modern C++ (where you wouldn't use a pointer at all), but who knows? Another example would be languages without pointers, or with bad support for pointers, maybe. (FORTRAN 77 comes to mind...)

    – Christian Hackl
    Feb 27 at 9:30











  • I would use an enum with 3 cases for this :)

    – J. Doe
    Feb 27 at 16:06














  • 49





    This question is quite language-specific, because what constitutes a good solution largely depends on what your programming language offers. For example, in C++17 or Scala, you'd use std::optional or Option. In other languages, you may have to built an appropriate mechanism yourself, or you may actually resort to null or something similar because it's more idiomatic.

    – Christian Hackl
    Feb 26 at 8:53






  • 16





    Is there a reason you wouldn't want the lastChangePasswordTime set to password creation time (creation is a mod, after all)?

    – Kristian H
    Feb 26 at 19:10













  • @ChristianHackl hmm, agree that there are different "perfect" solutions, but i don't see any (major) language though where using a separate boolean would be a better idea in general than doing null/nil checks. Not totally sure about C/C++ as I haven't been active there for quite a while, though.

    – Frank Hopkins
    Feb 26 at 20:17











  • @FrankHopkins: An example would be languages where variables can be left uninitialised, e.g. C or C++. lastChangePasswordTime may be an uninitialised pointer there, and comparing it to anything would be undefined behaviour. Not a really compelling reason not to initialise the pointer to NULL / nullptr instead, especially not in modern C++ (where you wouldn't use a pointer at all), but who knows? Another example would be languages without pointers, or with bad support for pointers, maybe. (FORTRAN 77 comes to mind...)

    – Christian Hackl
    Feb 27 at 9:30











  • I would use an enum with 3 cases for this :)

    – J. Doe
    Feb 27 at 16:06








49




49





This question is quite language-specific, because what constitutes a good solution largely depends on what your programming language offers. For example, in C++17 or Scala, you'd use std::optional or Option. In other languages, you may have to built an appropriate mechanism yourself, or you may actually resort to null or something similar because it's more idiomatic.

– Christian Hackl
Feb 26 at 8:53





This question is quite language-specific, because what constitutes a good solution largely depends on what your programming language offers. For example, in C++17 or Scala, you'd use std::optional or Option. In other languages, you may have to built an appropriate mechanism yourself, or you may actually resort to null or something similar because it's more idiomatic.

– Christian Hackl
Feb 26 at 8:53




16




16





Is there a reason you wouldn't want the lastChangePasswordTime set to password creation time (creation is a mod, after all)?

– Kristian H
Feb 26 at 19:10







Is there a reason you wouldn't want the lastChangePasswordTime set to password creation time (creation is a mod, after all)?

– Kristian H
Feb 26 at 19:10















@ChristianHackl hmm, agree that there are different "perfect" solutions, but i don't see any (major) language though where using a separate boolean would be a better idea in general than doing null/nil checks. Not totally sure about C/C++ as I haven't been active there for quite a while, though.

– Frank Hopkins
Feb 26 at 20:17





@ChristianHackl hmm, agree that there are different "perfect" solutions, but i don't see any (major) language though where using a separate boolean would be a better idea in general than doing null/nil checks. Not totally sure about C/C++ as I haven't been active there for quite a while, though.

– Frank Hopkins
Feb 26 at 20:17













@FrankHopkins: An example would be languages where variables can be left uninitialised, e.g. C or C++. lastChangePasswordTime may be an uninitialised pointer there, and comparing it to anything would be undefined behaviour. Not a really compelling reason not to initialise the pointer to NULL / nullptr instead, especially not in modern C++ (where you wouldn't use a pointer at all), but who knows? Another example would be languages without pointers, or with bad support for pointers, maybe. (FORTRAN 77 comes to mind...)

– Christian Hackl
Feb 27 at 9:30





@FrankHopkins: An example would be languages where variables can be left uninitialised, e.g. C or C++. lastChangePasswordTime may be an uninitialised pointer there, and comparing it to anything would be undefined behaviour. Not a really compelling reason not to initialise the pointer to NULL / nullptr instead, especially not in modern C++ (where you wouldn't use a pointer at all), but who knows? Another example would be languages without pointers, or with bad support for pointers, maybe. (FORTRAN 77 comes to mind...)

– Christian Hackl
Feb 27 at 9:30













I would use an enum with 3 cases for this :)

– J. Doe
Feb 27 at 16:06





I would use an enum with 3 cases for this :)

– J. Doe
Feb 27 at 16:06










8 Answers
8






active

oldest

votes


















69














I don't see why, if you have a meaningfully absent value, null should not be used if you are deliberate and careful about it.



If your goal is to surround the nullable value to prevent accidentally referencing it, I would suggest creating the isPasswordChanged value as a function or property that returns the result of a null check, for example:



class Member {
DateTime lastChangePasswordTime = null;
bool isPasswordChanged() { return lastChangePasswordTime != null; }

}


In my opinion, doing it this way:




  • Gives better code readability than a null-check would, which might lose context.

  • Removes the need for you having to actually worry about maintaining the isPasswordChanged value that you mention.


The way that you persist the data (presumably in a database) would be responsible for ensuring that the nulls are preserved.






share|improve this answer



















  • 29





    +1 for the opening. Wanton usage of null is generally disapproved of only in cases where null is an unexpected outcome, i.e. where it wouldn't make sense (to a consumer). If null is meaningful, then it's not an unexpected outcome.

    – Flater
    Feb 26 at 9:29






  • 26





    I would put it a little stronger as never have two variables that maintain the same state. It will fail. Hiding a null value, assuming the null value makes sense inside the instance, from the outside is a very good thing. In this case where you may later decide that 1970-01-01 denotes that the password has never been changed. Then the logic of the rest of the program does not have to care.

    – Bent
    Feb 26 at 10:24






  • 3





    You could forget to call isPasswordChanged just like you can forget to check if it's null. I see nothing gained here.

    – Gherman
    Feb 26 at 17:01






  • 8





    @Gherman If the consumer doesn't get the concept that null is meaningful or that he needs to check for the value being present, he is lost either way, but if the method is used, it is clear to everyone reading the code why there is a check and that there is a reasonable chance that the value is null/not present. Otherwise it is unclear if it was just a developer adding a null check just "because why not" or whether it's part of the concept. Sure, one can find out, but one way you have the information directly the other you need to look into the implementation.

    – Frank Hopkins
    Feb 26 at 19:55








  • 2





    @FrankHopkins: Good point, but if concurrency is used, even the inspection of a single variable may require locking.

    – Christian Hackl
    Feb 27 at 5:30



















62














nulls aren't evil. Using them without thinking is. This is a case where null is exactly the correct answer - there is no date.



Note that your solution creates more problems. What is the meaning of the date being set to something, but the isPasswordChanged is false? You've just created a case of conflicting information that you need to catch and treat specially, while a null value has a clearly defined, unambiguous meaning and cannot be in conflict to other information.



So no, your solution isn't better. Allowing for a null value is the right approach here. People who claim that null is always evil no matter the context don't understand why null exists.






share|improve this answer



















  • 16





    Historically, null exists because Tony Hoare made the billion-dollar mistake in 1965. People who claim that null is "evil" are over-simplifying the topic, of course, but it's a good thing that modern languages or programming styles are moving away from null, replacing it with dedicated option types.

    – Christian Hackl
    Feb 26 at 12:24






  • 8





    @ChristianHackl: just out of historical interest - die Hoare ever say what the better practical alternative would have been (without switching to a completely new paradigm)?

    – AnoE
    Feb 26 at 13:44








  • 5





    @AnoE: Interesting question. Don't know about what Hoare had to say on that, but null-free programming is often a reality these days in modern, well-designed programming languages.

    – Christian Hackl
    Feb 26 at 13:55






  • 9





    @Tom wat? In languages like C# and Java, the DateTime field is a pointer. The whole concept of null only makes sense for pointers!

    – Todd Sewell
    Feb 26 at 16:09






  • 16





    @Tom: Null pointers are only dangerous on languages and implementations that allow them to be blindly indexed and dereferenced, with whatever hilarity may result. In a language which traps attempts to index or dereference a null pointer, it will be often less dangerous than a pointer to a dummy object. There are many situations where having a program abnormally terminate may be preferable to having it produce meaningless numbers, and on systems that trap them, null pointers are the right recipe for that.

    – supercat
    Feb 26 at 17:19



















27














Depending on your programming language, there might be good alternatives, such as an optional data type. In C++(17), this would be std::optional. It can either be absent or have an arbitrary value of the underlying data type.






share|improve this answer



















  • 8





    There's Optional in java too; the meaning of a null Optional being up to you...

    – Matthieu M.
    Feb 26 at 11:22






  • 1





    Came here to connect with Optional as well. I'd encode this as a type in a language which had them.

    – Zipp
    Feb 26 at 18:38






  • 2





    @FrankHopkins It's a shame that nothing in Java prevents you from writing Optional<Date> lastPasswordChangeTime = null;, but I wouldn't give up just because of that. Instead, I would instill a very firmly held team rule, that no optional values are ever allowed to be assign null. Optional buys you too many nice features to give up on that easily. You can easily assign default values (orElse or with lazy evaluation: orElseGet), throw errors (orElseThrow), transform values in a null safe way (map, flatmap), etc.

    – Alexander
    Feb 26 at 20:15






  • 3





    @FrankHopkins Checking isPresent is almost always a code smell, in my experience, and a pretty reliable sign that the devs who are using these optionals are "missing the point". Indeed, it gives basically no benefit over ref == null, but it's also not something you should be using often. Even if the team is unstable, a static analysis tool can lay down the law, like a linter or FindBugs, which can catch most cases.

    – Alexander
    Feb 26 at 20:29








  • 3





    @FrankHopkins: It may be that the Java community just needs a little paradigm shift, which may yet take many years. If you look at Scala, for example, it supports null because the language is 100% compatible to Java, but nobody uses it, and Option[T] is all over the place, with excellent functional-programming support like map, flatMap, pattern matching and so on, which goes far, far beyond == null checks. You are right that in theory, an option type sounds like little more than a glorified pointer, but reality proves that argument wrong.

    – Christian Hackl
    Feb 27 at 5:28



















11














Correctly using null



There are different ways of using null. The most common and semantically correct way is to use it when you may or may not have a single value. In this case a value either equals null or is something meaningful like a record from database or something.



In these situations you then mostly use it like this (in pseudo-code):



if (value is null) {
doSomethingAboutIt();
return;
}

doSomethingUseful(value);


Problem



And it has a very big problem. The problem is that by the time you invoke doSomethingUseful the value may not have been checked for null! If it wasn't then the program will likely crash. And the user may not even see any good error messages, being left with something like "horrible error: wanted value but got null!"(after update: although there may be even less informative error like Segmentation fault. Core dumped., or worse yet, no error and incorrect manipulation on null in some cases)



Forgetting to write checks for null and handling null situations is an extremely common bug. This is why Tony Hoare who invented null said at a software conference called QCon London in 2009 that he made the billion-dollar mistake in 1965:
https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare



Avoiding the problem



Some technologies and languages make checking for null impossible to forget in different ways, reducing amount of bugs.



For example Haskell has the Maybe monad instead of nulls. Suppose that DatabaseRecord is a user-defined type. In Haskell a value of type Maybe DatabaseRecord can be equal Just <somevalue> or it may be equal to Nothing. You can then use it in different ways but no matter how you use it you cannot apply some operation on Nothing without knowing it.



For instance this function called zeroAsDefault returns x for Just x and 0 for Nothing:



zeroAsDefault :: Maybe Int -> Int
zeroAsDefault mx = case mx of
Nothing -> 0
Just x -> x


Christian Hackl says C++17 and Scala have their own ways. So you may want to try to find out if your language has anything like that and use it.



Nulls are still in wide use



If you don't have anything better then using null is fine. Just keep watching out for it. Type declarations in functions will help you somewhat anyway.



Also that may sound not very progressive but you should check if your colleagues want to use null or something else. They may be conservative and may not want to use new data structures for some reasons. For instance supporting older versions of a language. Such things should be declared in project's coding standards and properly discussed with the team.



On your proposal



You suggest using a separate boolean field. But you have to check it anyway and still may forget to check it. So there is nothing won here. If you can even forget something else, like updating both values each time, then it's even worse. If the problem of forgetting to check for null is not solved then there is no point. Avoiding null is difficult and you should not do it in such a way that makes it worse.



How not to use null



Finally there are common ways to use null incorrectly. One such way is to use it in place of empty data structures such as arrays and strings. Empty array is a proper array like any other! It is almost always important and useful for data structures, that can fit multiple values, to be able to be empty, i.e. has 0 length.



From algebra standpoint an empty string for strings is much like 0 for numbers, i.e. identity:



a+0=a
concat(str, '')=str


Empty string enables strings in general to become a monoid:
https://en.wikipedia.org/wiki/Monoid
If you don't get it it's not that important for you.



Now let's see why it's important for programming with this example:



for (element in array) {
doSomething(element);
}


If we pass an empty array in here the code will work fine. It will just do nothing. However if we pass a null here then we will likely get a crash with an error like "can't loop through null, sorry". We could wrap it in if but that's less clean and again, you might forget to check it



How to handle null



What doSomethingAboutIt() should be doing and especially weather it should throw an exception is another complicated issue. In short it depends on weather null was acceptable input value for given task and what is expected in response. Exceptions are for events that were not expected. I will not go further into that topic. The answer very is long already.






share|improve this answer





















  • 5





    Actually, horrible error: wanted value but got null! is much better than the more typical Segmentation fault. Core dumped....

    – Toby Speight
    Feb 26 at 17:57






  • 2





    @TobySpeight True, but I would prefer something that lays inside user's terms like Error: the product you want to buy is out of stock.

    – Gherman
    Feb 26 at 18:10











  • Sure - I was just observing that it could be (and often is) even worse. I completely agree on what would be better! And your answer is pretty much what I would have said to this question: +1.

    – Toby Speight
    Feb 26 at 20:35








  • 2





    @Gherman: Passing null where null is not allowed is a programming error, i.e. a bug in the code. A product being out of stock is part of the ordinary business logic and not a bug. You cannot, and should not try to, translate the detection of a bug to a normal message in the user interface. Crashing immediately and not executing more code is the preferred course of action, especially if it's an important application (e.g. one that performs real financial transactions).

    – Christian Hackl
    Feb 27 at 9:41






  • 1





    @EricDuminil We want to remove(or reduce) possibility of making a mistake, not remove null itself entirely, even from the background.

    – Gherman
    Feb 28 at 12:55



















4














In addition to all of the very good answers previously given, I'd add that every time you're tempted to let a field be null, think carefully if it might be a list type. A nullable type is equivalently a list of 0 or 1 elements, and often this can be generalized to a list of N elements. Specifically in this case, you might want to consider lastChangePasswordTime being a list of passwordChangeTimes.






share|improve this answer
























  • That's an excellent point. The same is often true for option types; an option can be seen as special case of a sequence.

    – Christian Hackl
    Feb 27 at 10:24



















2














Ask yourself this: which behavior requires the field lastChangePasswordTime?



If you need that field for a method IsPasswordExpired() to determine if a Member should be prompted to change their password every so often, I would set the field to the time the Member was initially created.
The IsPasswordExpired() implementation is the same for new and existing members.



class Member{
private DateTime lastChangePasswordTime;

public Member(DateTime lastChangePasswordTime) {
// set value, maybe check for null
}

public bool IsPasswordExpired() {
DateTime limit = DateTime.Now.AddMonths(-3);
return lastChangePasswordTime < limit;
}
}


If you have a separate requirement that newly created members have to update their password, I would add a separated boolean field called passwordShouldBeChanged and set it to true upon creation. I would then change the functionality of the IsPasswordExpired() method to include a check for that field (and rename the method to ShouldChangePassword).



class Member{
private DateTime lastChangePasswordTime;
private bool passwordShouldBeChanged;

public Member(DateTime lastChangePasswordTime, bool passwordShouldBeChanged) {
// set values, maybe check for nulls
}

public bool ShouldChangePassword() {
return PasswordExpired(lastChangePasswordTime) || passwordShouldBeChanged;
}

private static bool PasswordExpired(DateTime lastChangePasswordTime) {
DateTime limit = DateTime.Now.AddMonths(-3);
return lastChangePasswordTime < limit;
}
}


Make your intentions explicit in code.






share|improve this answer































    2














    First, nulls being evil is dogma and as usual with dogma it works best as a guideline and not as pass/no pass test.



    Secondly, you can redefine your situation in a way that it makes sense that the value can never be null. InititialPasswordChanged is a Boolean initially set to false, PasswordSetTime is the date and time when the current password was set.



    Note that while this does come at a slight cost, you can now ALWAYS calculate how long it has been since a password was last set.






    share|improve this answer































      1














      First, both are 'safe/sane/correct' if the caller checks before use.
      This issue is what happens if they don't. Which is better: "some flavour of null error" or "using an invalid value".



      But there really is no 1 answer that's right here. It really depends on what you are worried about.



      If crashes are really bad but the answer isn't critical / has an excepted default value, then maybe a boolean as a flag is better. If using the wrong answer is a real problem but crashing is not so bad, then null is better.



      For the majority of the 'typical' cases, fast failure and forcing the callers to check is the fastest way to sane code and hence I think null should be the default choice, but I wouldn't put too much faith in the "X is the root of all evil" evangelists. They normally haven't anticipated all the use cases.






      share|improve this answer








      New contributor




      ANone is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.




















        Your Answer








        StackExchange.ready(function() {
        var channelOptions = {
        tags: "".split(" "),
        id: "131"
        };
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using("snippets", function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: false,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: null,
        bindNavPrevention: true,
        postfix: "",
        imageUploader: {
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        },
        onDemand: false,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        });


        }
        });














        draft saved

        draft discarded


















        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f387720%2fis-a-new-boolean-field-better-than-a-null-reference-when-a-value-can-be-meaningf%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown




















        StackExchange.ready(function () {
        $("#show-editor-button input, #show-editor-button button").click(function () {
        var showEditor = function() {
        $("#show-editor-button").hide();
        $("#post-form").removeClass("dno");
        StackExchange.editor.finallyInit();
        };

        var useFancy = $(this).data('confirm-use-fancy');
        if(useFancy == 'True') {
        var popupTitle = $(this).data('confirm-fancy-title');
        var popupBody = $(this).data('confirm-fancy-body');
        var popupAccept = $(this).data('confirm-fancy-accept-button');

        $(this).loadPopup({
        url: '/post/self-answer-popup',
        loaded: function(popup) {
        var pTitle = $(popup).find('h2');
        var pBody = $(popup).find('.popup-body');
        var pSubmit = $(popup).find('.popup-submit');

        pTitle.text(popupTitle);
        pBody.html(popupBody);
        pSubmit.val(popupAccept).click(showEditor);
        }
        })
        } else{
        var confirmText = $(this).data('confirm-text');
        if (confirmText ? confirm(confirmText) : true) {
        showEditor();
        }
        }
        });
        });






        8 Answers
        8






        active

        oldest

        votes








        8 Answers
        8






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        69














        I don't see why, if you have a meaningfully absent value, null should not be used if you are deliberate and careful about it.



        If your goal is to surround the nullable value to prevent accidentally referencing it, I would suggest creating the isPasswordChanged value as a function or property that returns the result of a null check, for example:



        class Member {
        DateTime lastChangePasswordTime = null;
        bool isPasswordChanged() { return lastChangePasswordTime != null; }

        }


        In my opinion, doing it this way:




        • Gives better code readability than a null-check would, which might lose context.

        • Removes the need for you having to actually worry about maintaining the isPasswordChanged value that you mention.


        The way that you persist the data (presumably in a database) would be responsible for ensuring that the nulls are preserved.






        share|improve this answer



















        • 29





          +1 for the opening. Wanton usage of null is generally disapproved of only in cases where null is an unexpected outcome, i.e. where it wouldn't make sense (to a consumer). If null is meaningful, then it's not an unexpected outcome.

          – Flater
          Feb 26 at 9:29






        • 26





          I would put it a little stronger as never have two variables that maintain the same state. It will fail. Hiding a null value, assuming the null value makes sense inside the instance, from the outside is a very good thing. In this case where you may later decide that 1970-01-01 denotes that the password has never been changed. Then the logic of the rest of the program does not have to care.

          – Bent
          Feb 26 at 10:24






        • 3





          You could forget to call isPasswordChanged just like you can forget to check if it's null. I see nothing gained here.

          – Gherman
          Feb 26 at 17:01






        • 8





          @Gherman If the consumer doesn't get the concept that null is meaningful or that he needs to check for the value being present, he is lost either way, but if the method is used, it is clear to everyone reading the code why there is a check and that there is a reasonable chance that the value is null/not present. Otherwise it is unclear if it was just a developer adding a null check just "because why not" or whether it's part of the concept. Sure, one can find out, but one way you have the information directly the other you need to look into the implementation.

          – Frank Hopkins
          Feb 26 at 19:55








        • 2





          @FrankHopkins: Good point, but if concurrency is used, even the inspection of a single variable may require locking.

          – Christian Hackl
          Feb 27 at 5:30
















        69














        I don't see why, if you have a meaningfully absent value, null should not be used if you are deliberate and careful about it.



        If your goal is to surround the nullable value to prevent accidentally referencing it, I would suggest creating the isPasswordChanged value as a function or property that returns the result of a null check, for example:



        class Member {
        DateTime lastChangePasswordTime = null;
        bool isPasswordChanged() { return lastChangePasswordTime != null; }

        }


        In my opinion, doing it this way:




        • Gives better code readability than a null-check would, which might lose context.

        • Removes the need for you having to actually worry about maintaining the isPasswordChanged value that you mention.


        The way that you persist the data (presumably in a database) would be responsible for ensuring that the nulls are preserved.






        share|improve this answer



















        • 29





          +1 for the opening. Wanton usage of null is generally disapproved of only in cases where null is an unexpected outcome, i.e. where it wouldn't make sense (to a consumer). If null is meaningful, then it's not an unexpected outcome.

          – Flater
          Feb 26 at 9:29






        • 26





          I would put it a little stronger as never have two variables that maintain the same state. It will fail. Hiding a null value, assuming the null value makes sense inside the instance, from the outside is a very good thing. In this case where you may later decide that 1970-01-01 denotes that the password has never been changed. Then the logic of the rest of the program does not have to care.

          – Bent
          Feb 26 at 10:24






        • 3





          You could forget to call isPasswordChanged just like you can forget to check if it's null. I see nothing gained here.

          – Gherman
          Feb 26 at 17:01






        • 8





          @Gherman If the consumer doesn't get the concept that null is meaningful or that he needs to check for the value being present, he is lost either way, but if the method is used, it is clear to everyone reading the code why there is a check and that there is a reasonable chance that the value is null/not present. Otherwise it is unclear if it was just a developer adding a null check just "because why not" or whether it's part of the concept. Sure, one can find out, but one way you have the information directly the other you need to look into the implementation.

          – Frank Hopkins
          Feb 26 at 19:55








        • 2





          @FrankHopkins: Good point, but if concurrency is used, even the inspection of a single variable may require locking.

          – Christian Hackl
          Feb 27 at 5:30














        69












        69








        69







        I don't see why, if you have a meaningfully absent value, null should not be used if you are deliberate and careful about it.



        If your goal is to surround the nullable value to prevent accidentally referencing it, I would suggest creating the isPasswordChanged value as a function or property that returns the result of a null check, for example:



        class Member {
        DateTime lastChangePasswordTime = null;
        bool isPasswordChanged() { return lastChangePasswordTime != null; }

        }


        In my opinion, doing it this way:




        • Gives better code readability than a null-check would, which might lose context.

        • Removes the need for you having to actually worry about maintaining the isPasswordChanged value that you mention.


        The way that you persist the data (presumably in a database) would be responsible for ensuring that the nulls are preserved.






        share|improve this answer













        I don't see why, if you have a meaningfully absent value, null should not be used if you are deliberate and careful about it.



        If your goal is to surround the nullable value to prevent accidentally referencing it, I would suggest creating the isPasswordChanged value as a function or property that returns the result of a null check, for example:



        class Member {
        DateTime lastChangePasswordTime = null;
        bool isPasswordChanged() { return lastChangePasswordTime != null; }

        }


        In my opinion, doing it this way:




        • Gives better code readability than a null-check would, which might lose context.

        • Removes the need for you having to actually worry about maintaining the isPasswordChanged value that you mention.


        The way that you persist the data (presumably in a database) would be responsible for ensuring that the nulls are preserved.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Feb 26 at 8:50









        TZHXTZHX

        4,85222032




        4,85222032








        • 29





          +1 for the opening. Wanton usage of null is generally disapproved of only in cases where null is an unexpected outcome, i.e. where it wouldn't make sense (to a consumer). If null is meaningful, then it's not an unexpected outcome.

          – Flater
          Feb 26 at 9:29






        • 26





          I would put it a little stronger as never have two variables that maintain the same state. It will fail. Hiding a null value, assuming the null value makes sense inside the instance, from the outside is a very good thing. In this case where you may later decide that 1970-01-01 denotes that the password has never been changed. Then the logic of the rest of the program does not have to care.

          – Bent
          Feb 26 at 10:24






        • 3





          You could forget to call isPasswordChanged just like you can forget to check if it's null. I see nothing gained here.

          – Gherman
          Feb 26 at 17:01






        • 8





          @Gherman If the consumer doesn't get the concept that null is meaningful or that he needs to check for the value being present, he is lost either way, but if the method is used, it is clear to everyone reading the code why there is a check and that there is a reasonable chance that the value is null/not present. Otherwise it is unclear if it was just a developer adding a null check just "because why not" or whether it's part of the concept. Sure, one can find out, but one way you have the information directly the other you need to look into the implementation.

          – Frank Hopkins
          Feb 26 at 19:55








        • 2





          @FrankHopkins: Good point, but if concurrency is used, even the inspection of a single variable may require locking.

          – Christian Hackl
          Feb 27 at 5:30














        • 29





          +1 for the opening. Wanton usage of null is generally disapproved of only in cases where null is an unexpected outcome, i.e. where it wouldn't make sense (to a consumer). If null is meaningful, then it's not an unexpected outcome.

          – Flater
          Feb 26 at 9:29






        • 26





          I would put it a little stronger as never have two variables that maintain the same state. It will fail. Hiding a null value, assuming the null value makes sense inside the instance, from the outside is a very good thing. In this case where you may later decide that 1970-01-01 denotes that the password has never been changed. Then the logic of the rest of the program does not have to care.

          – Bent
          Feb 26 at 10:24






        • 3





          You could forget to call isPasswordChanged just like you can forget to check if it's null. I see nothing gained here.

          – Gherman
          Feb 26 at 17:01






        • 8





          @Gherman If the consumer doesn't get the concept that null is meaningful or that he needs to check for the value being present, he is lost either way, but if the method is used, it is clear to everyone reading the code why there is a check and that there is a reasonable chance that the value is null/not present. Otherwise it is unclear if it was just a developer adding a null check just "because why not" or whether it's part of the concept. Sure, one can find out, but one way you have the information directly the other you need to look into the implementation.

          – Frank Hopkins
          Feb 26 at 19:55








        • 2





          @FrankHopkins: Good point, but if concurrency is used, even the inspection of a single variable may require locking.

          – Christian Hackl
          Feb 27 at 5:30








        29




        29





        +1 for the opening. Wanton usage of null is generally disapproved of only in cases where null is an unexpected outcome, i.e. where it wouldn't make sense (to a consumer). If null is meaningful, then it's not an unexpected outcome.

        – Flater
        Feb 26 at 9:29





        +1 for the opening. Wanton usage of null is generally disapproved of only in cases where null is an unexpected outcome, i.e. where it wouldn't make sense (to a consumer). If null is meaningful, then it's not an unexpected outcome.

        – Flater
        Feb 26 at 9:29




        26




        26





        I would put it a little stronger as never have two variables that maintain the same state. It will fail. Hiding a null value, assuming the null value makes sense inside the instance, from the outside is a very good thing. In this case where you may later decide that 1970-01-01 denotes that the password has never been changed. Then the logic of the rest of the program does not have to care.

        – Bent
        Feb 26 at 10:24





        I would put it a little stronger as never have two variables that maintain the same state. It will fail. Hiding a null value, assuming the null value makes sense inside the instance, from the outside is a very good thing. In this case where you may later decide that 1970-01-01 denotes that the password has never been changed. Then the logic of the rest of the program does not have to care.

        – Bent
        Feb 26 at 10:24




        3




        3





        You could forget to call isPasswordChanged just like you can forget to check if it's null. I see nothing gained here.

        – Gherman
        Feb 26 at 17:01





        You could forget to call isPasswordChanged just like you can forget to check if it's null. I see nothing gained here.

        – Gherman
        Feb 26 at 17:01




        8




        8





        @Gherman If the consumer doesn't get the concept that null is meaningful or that he needs to check for the value being present, he is lost either way, but if the method is used, it is clear to everyone reading the code why there is a check and that there is a reasonable chance that the value is null/not present. Otherwise it is unclear if it was just a developer adding a null check just "because why not" or whether it's part of the concept. Sure, one can find out, but one way you have the information directly the other you need to look into the implementation.

        – Frank Hopkins
        Feb 26 at 19:55







        @Gherman If the consumer doesn't get the concept that null is meaningful or that he needs to check for the value being present, he is lost either way, but if the method is used, it is clear to everyone reading the code why there is a check and that there is a reasonable chance that the value is null/not present. Otherwise it is unclear if it was just a developer adding a null check just "because why not" or whether it's part of the concept. Sure, one can find out, but one way you have the information directly the other you need to look into the implementation.

        – Frank Hopkins
        Feb 26 at 19:55






        2




        2





        @FrankHopkins: Good point, but if concurrency is used, even the inspection of a single variable may require locking.

        – Christian Hackl
        Feb 27 at 5:30





        @FrankHopkins: Good point, but if concurrency is used, even the inspection of a single variable may require locking.

        – Christian Hackl
        Feb 27 at 5:30













        62














        nulls aren't evil. Using them without thinking is. This is a case where null is exactly the correct answer - there is no date.



        Note that your solution creates more problems. What is the meaning of the date being set to something, but the isPasswordChanged is false? You've just created a case of conflicting information that you need to catch and treat specially, while a null value has a clearly defined, unambiguous meaning and cannot be in conflict to other information.



        So no, your solution isn't better. Allowing for a null value is the right approach here. People who claim that null is always evil no matter the context don't understand why null exists.






        share|improve this answer



















        • 16





          Historically, null exists because Tony Hoare made the billion-dollar mistake in 1965. People who claim that null is "evil" are over-simplifying the topic, of course, but it's a good thing that modern languages or programming styles are moving away from null, replacing it with dedicated option types.

          – Christian Hackl
          Feb 26 at 12:24






        • 8





          @ChristianHackl: just out of historical interest - die Hoare ever say what the better practical alternative would have been (without switching to a completely new paradigm)?

          – AnoE
          Feb 26 at 13:44








        • 5





          @AnoE: Interesting question. Don't know about what Hoare had to say on that, but null-free programming is often a reality these days in modern, well-designed programming languages.

          – Christian Hackl
          Feb 26 at 13:55






        • 9





          @Tom wat? In languages like C# and Java, the DateTime field is a pointer. The whole concept of null only makes sense for pointers!

          – Todd Sewell
          Feb 26 at 16:09






        • 16





          @Tom: Null pointers are only dangerous on languages and implementations that allow them to be blindly indexed and dereferenced, with whatever hilarity may result. In a language which traps attempts to index or dereference a null pointer, it will be often less dangerous than a pointer to a dummy object. There are many situations where having a program abnormally terminate may be preferable to having it produce meaningless numbers, and on systems that trap them, null pointers are the right recipe for that.

          – supercat
          Feb 26 at 17:19
















        62














        nulls aren't evil. Using them without thinking is. This is a case where null is exactly the correct answer - there is no date.



        Note that your solution creates more problems. What is the meaning of the date being set to something, but the isPasswordChanged is false? You've just created a case of conflicting information that you need to catch and treat specially, while a null value has a clearly defined, unambiguous meaning and cannot be in conflict to other information.



        So no, your solution isn't better. Allowing for a null value is the right approach here. People who claim that null is always evil no matter the context don't understand why null exists.






        share|improve this answer



















        • 16





          Historically, null exists because Tony Hoare made the billion-dollar mistake in 1965. People who claim that null is "evil" are over-simplifying the topic, of course, but it's a good thing that modern languages or programming styles are moving away from null, replacing it with dedicated option types.

          – Christian Hackl
          Feb 26 at 12:24






        • 8





          @ChristianHackl: just out of historical interest - die Hoare ever say what the better practical alternative would have been (without switching to a completely new paradigm)?

          – AnoE
          Feb 26 at 13:44








        • 5





          @AnoE: Interesting question. Don't know about what Hoare had to say on that, but null-free programming is often a reality these days in modern, well-designed programming languages.

          – Christian Hackl
          Feb 26 at 13:55






        • 9





          @Tom wat? In languages like C# and Java, the DateTime field is a pointer. The whole concept of null only makes sense for pointers!

          – Todd Sewell
          Feb 26 at 16:09






        • 16





          @Tom: Null pointers are only dangerous on languages and implementations that allow them to be blindly indexed and dereferenced, with whatever hilarity may result. In a language which traps attempts to index or dereference a null pointer, it will be often less dangerous than a pointer to a dummy object. There are many situations where having a program abnormally terminate may be preferable to having it produce meaningless numbers, and on systems that trap them, null pointers are the right recipe for that.

          – supercat
          Feb 26 at 17:19














        62












        62








        62







        nulls aren't evil. Using them without thinking is. This is a case where null is exactly the correct answer - there is no date.



        Note that your solution creates more problems. What is the meaning of the date being set to something, but the isPasswordChanged is false? You've just created a case of conflicting information that you need to catch and treat specially, while a null value has a clearly defined, unambiguous meaning and cannot be in conflict to other information.



        So no, your solution isn't better. Allowing for a null value is the right approach here. People who claim that null is always evil no matter the context don't understand why null exists.






        share|improve this answer













        nulls aren't evil. Using them without thinking is. This is a case where null is exactly the correct answer - there is no date.



        Note that your solution creates more problems. What is the meaning of the date being set to something, but the isPasswordChanged is false? You've just created a case of conflicting information that you need to catch and treat specially, while a null value has a clearly defined, unambiguous meaning and cannot be in conflict to other information.



        So no, your solution isn't better. Allowing for a null value is the right approach here. People who claim that null is always evil no matter the context don't understand why null exists.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Feb 26 at 11:09









        TomTom

        70934




        70934








        • 16





          Historically, null exists because Tony Hoare made the billion-dollar mistake in 1965. People who claim that null is "evil" are over-simplifying the topic, of course, but it's a good thing that modern languages or programming styles are moving away from null, replacing it with dedicated option types.

          – Christian Hackl
          Feb 26 at 12:24






        • 8





          @ChristianHackl: just out of historical interest - die Hoare ever say what the better practical alternative would have been (without switching to a completely new paradigm)?

          – AnoE
          Feb 26 at 13:44








        • 5





          @AnoE: Interesting question. Don't know about what Hoare had to say on that, but null-free programming is often a reality these days in modern, well-designed programming languages.

          – Christian Hackl
          Feb 26 at 13:55






        • 9





          @Tom wat? In languages like C# and Java, the DateTime field is a pointer. The whole concept of null only makes sense for pointers!

          – Todd Sewell
          Feb 26 at 16:09






        • 16





          @Tom: Null pointers are only dangerous on languages and implementations that allow them to be blindly indexed and dereferenced, with whatever hilarity may result. In a language which traps attempts to index or dereference a null pointer, it will be often less dangerous than a pointer to a dummy object. There are many situations where having a program abnormally terminate may be preferable to having it produce meaningless numbers, and on systems that trap them, null pointers are the right recipe for that.

          – supercat
          Feb 26 at 17:19














        • 16





          Historically, null exists because Tony Hoare made the billion-dollar mistake in 1965. People who claim that null is "evil" are over-simplifying the topic, of course, but it's a good thing that modern languages or programming styles are moving away from null, replacing it with dedicated option types.

          – Christian Hackl
          Feb 26 at 12:24






        • 8





          @ChristianHackl: just out of historical interest - die Hoare ever say what the better practical alternative would have been (without switching to a completely new paradigm)?

          – AnoE
          Feb 26 at 13:44








        • 5





          @AnoE: Interesting question. Don't know about what Hoare had to say on that, but null-free programming is often a reality these days in modern, well-designed programming languages.

          – Christian Hackl
          Feb 26 at 13:55






        • 9





          @Tom wat? In languages like C# and Java, the DateTime field is a pointer. The whole concept of null only makes sense for pointers!

          – Todd Sewell
          Feb 26 at 16:09






        • 16





          @Tom: Null pointers are only dangerous on languages and implementations that allow them to be blindly indexed and dereferenced, with whatever hilarity may result. In a language which traps attempts to index or dereference a null pointer, it will be often less dangerous than a pointer to a dummy object. There are many situations where having a program abnormally terminate may be preferable to having it produce meaningless numbers, and on systems that trap them, null pointers are the right recipe for that.

          – supercat
          Feb 26 at 17:19








        16




        16





        Historically, null exists because Tony Hoare made the billion-dollar mistake in 1965. People who claim that null is "evil" are over-simplifying the topic, of course, but it's a good thing that modern languages or programming styles are moving away from null, replacing it with dedicated option types.

        – Christian Hackl
        Feb 26 at 12:24





        Historically, null exists because Tony Hoare made the billion-dollar mistake in 1965. People who claim that null is "evil" are over-simplifying the topic, of course, but it's a good thing that modern languages or programming styles are moving away from null, replacing it with dedicated option types.

        – Christian Hackl
        Feb 26 at 12:24




        8




        8





        @ChristianHackl: just out of historical interest - die Hoare ever say what the better practical alternative would have been (without switching to a completely new paradigm)?

        – AnoE
        Feb 26 at 13:44







        @ChristianHackl: just out of historical interest - die Hoare ever say what the better practical alternative would have been (without switching to a completely new paradigm)?

        – AnoE
        Feb 26 at 13:44






        5




        5





        @AnoE: Interesting question. Don't know about what Hoare had to say on that, but null-free programming is often a reality these days in modern, well-designed programming languages.

        – Christian Hackl
        Feb 26 at 13:55





        @AnoE: Interesting question. Don't know about what Hoare had to say on that, but null-free programming is often a reality these days in modern, well-designed programming languages.

        – Christian Hackl
        Feb 26 at 13:55




        9




        9





        @Tom wat? In languages like C# and Java, the DateTime field is a pointer. The whole concept of null only makes sense for pointers!

        – Todd Sewell
        Feb 26 at 16:09





        @Tom wat? In languages like C# and Java, the DateTime field is a pointer. The whole concept of null only makes sense for pointers!

        – Todd Sewell
        Feb 26 at 16:09




        16




        16





        @Tom: Null pointers are only dangerous on languages and implementations that allow them to be blindly indexed and dereferenced, with whatever hilarity may result. In a language which traps attempts to index or dereference a null pointer, it will be often less dangerous than a pointer to a dummy object. There are many situations where having a program abnormally terminate may be preferable to having it produce meaningless numbers, and on systems that trap them, null pointers are the right recipe for that.

        – supercat
        Feb 26 at 17:19





        @Tom: Null pointers are only dangerous on languages and implementations that allow them to be blindly indexed and dereferenced, with whatever hilarity may result. In a language which traps attempts to index or dereference a null pointer, it will be often less dangerous than a pointer to a dummy object. There are many situations where having a program abnormally terminate may be preferable to having it produce meaningless numbers, and on systems that trap them, null pointers are the right recipe for that.

        – supercat
        Feb 26 at 17:19











        27














        Depending on your programming language, there might be good alternatives, such as an optional data type. In C++(17), this would be std::optional. It can either be absent or have an arbitrary value of the underlying data type.






        share|improve this answer



















        • 8





          There's Optional in java too; the meaning of a null Optional being up to you...

          – Matthieu M.
          Feb 26 at 11:22






        • 1





          Came here to connect with Optional as well. I'd encode this as a type in a language which had them.

          – Zipp
          Feb 26 at 18:38






        • 2





          @FrankHopkins It's a shame that nothing in Java prevents you from writing Optional<Date> lastPasswordChangeTime = null;, but I wouldn't give up just because of that. Instead, I would instill a very firmly held team rule, that no optional values are ever allowed to be assign null. Optional buys you too many nice features to give up on that easily. You can easily assign default values (orElse or with lazy evaluation: orElseGet), throw errors (orElseThrow), transform values in a null safe way (map, flatmap), etc.

          – Alexander
          Feb 26 at 20:15






        • 3





          @FrankHopkins Checking isPresent is almost always a code smell, in my experience, and a pretty reliable sign that the devs who are using these optionals are "missing the point". Indeed, it gives basically no benefit over ref == null, but it's also not something you should be using often. Even if the team is unstable, a static analysis tool can lay down the law, like a linter or FindBugs, which can catch most cases.

          – Alexander
          Feb 26 at 20:29








        • 3





          @FrankHopkins: It may be that the Java community just needs a little paradigm shift, which may yet take many years. If you look at Scala, for example, it supports null because the language is 100% compatible to Java, but nobody uses it, and Option[T] is all over the place, with excellent functional-programming support like map, flatMap, pattern matching and so on, which goes far, far beyond == null checks. You are right that in theory, an option type sounds like little more than a glorified pointer, but reality proves that argument wrong.

          – Christian Hackl
          Feb 27 at 5:28
















        27














        Depending on your programming language, there might be good alternatives, such as an optional data type. In C++(17), this would be std::optional. It can either be absent or have an arbitrary value of the underlying data type.






        share|improve this answer



















        • 8





          There's Optional in java too; the meaning of a null Optional being up to you...

          – Matthieu M.
          Feb 26 at 11:22






        • 1





          Came here to connect with Optional as well. I'd encode this as a type in a language which had them.

          – Zipp
          Feb 26 at 18:38






        • 2





          @FrankHopkins It's a shame that nothing in Java prevents you from writing Optional<Date> lastPasswordChangeTime = null;, but I wouldn't give up just because of that. Instead, I would instill a very firmly held team rule, that no optional values are ever allowed to be assign null. Optional buys you too many nice features to give up on that easily. You can easily assign default values (orElse or with lazy evaluation: orElseGet), throw errors (orElseThrow), transform values in a null safe way (map, flatmap), etc.

          – Alexander
          Feb 26 at 20:15






        • 3





          @FrankHopkins Checking isPresent is almost always a code smell, in my experience, and a pretty reliable sign that the devs who are using these optionals are "missing the point". Indeed, it gives basically no benefit over ref == null, but it's also not something you should be using often. Even if the team is unstable, a static analysis tool can lay down the law, like a linter or FindBugs, which can catch most cases.

          – Alexander
          Feb 26 at 20:29








        • 3





          @FrankHopkins: It may be that the Java community just needs a little paradigm shift, which may yet take many years. If you look at Scala, for example, it supports null because the language is 100% compatible to Java, but nobody uses it, and Option[T] is all over the place, with excellent functional-programming support like map, flatMap, pattern matching and so on, which goes far, far beyond == null checks. You are right that in theory, an option type sounds like little more than a glorified pointer, but reality proves that argument wrong.

          – Christian Hackl
          Feb 27 at 5:28














        27












        27








        27







        Depending on your programming language, there might be good alternatives, such as an optional data type. In C++(17), this would be std::optional. It can either be absent or have an arbitrary value of the underlying data type.






        share|improve this answer













        Depending on your programming language, there might be good alternatives, such as an optional data type. In C++(17), this would be std::optional. It can either be absent or have an arbitrary value of the underlying data type.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Feb 26 at 8:17









        dasmydasmy

        46027




        46027








        • 8





          There's Optional in java too; the meaning of a null Optional being up to you...

          – Matthieu M.
          Feb 26 at 11:22






        • 1





          Came here to connect with Optional as well. I'd encode this as a type in a language which had them.

          – Zipp
          Feb 26 at 18:38






        • 2





          @FrankHopkins It's a shame that nothing in Java prevents you from writing Optional<Date> lastPasswordChangeTime = null;, but I wouldn't give up just because of that. Instead, I would instill a very firmly held team rule, that no optional values are ever allowed to be assign null. Optional buys you too many nice features to give up on that easily. You can easily assign default values (orElse or with lazy evaluation: orElseGet), throw errors (orElseThrow), transform values in a null safe way (map, flatmap), etc.

          – Alexander
          Feb 26 at 20:15






        • 3





          @FrankHopkins Checking isPresent is almost always a code smell, in my experience, and a pretty reliable sign that the devs who are using these optionals are "missing the point". Indeed, it gives basically no benefit over ref == null, but it's also not something you should be using often. Even if the team is unstable, a static analysis tool can lay down the law, like a linter or FindBugs, which can catch most cases.

          – Alexander
          Feb 26 at 20:29








        • 3





          @FrankHopkins: It may be that the Java community just needs a little paradigm shift, which may yet take many years. If you look at Scala, for example, it supports null because the language is 100% compatible to Java, but nobody uses it, and Option[T] is all over the place, with excellent functional-programming support like map, flatMap, pattern matching and so on, which goes far, far beyond == null checks. You are right that in theory, an option type sounds like little more than a glorified pointer, but reality proves that argument wrong.

          – Christian Hackl
          Feb 27 at 5:28














        • 8





          There's Optional in java too; the meaning of a null Optional being up to you...

          – Matthieu M.
          Feb 26 at 11:22






        • 1





          Came here to connect with Optional as well. I'd encode this as a type in a language which had them.

          – Zipp
          Feb 26 at 18:38






        • 2





          @FrankHopkins It's a shame that nothing in Java prevents you from writing Optional<Date> lastPasswordChangeTime = null;, but I wouldn't give up just because of that. Instead, I would instill a very firmly held team rule, that no optional values are ever allowed to be assign null. Optional buys you too many nice features to give up on that easily. You can easily assign default values (orElse or with lazy evaluation: orElseGet), throw errors (orElseThrow), transform values in a null safe way (map, flatmap), etc.

          – Alexander
          Feb 26 at 20:15






        • 3





          @FrankHopkins Checking isPresent is almost always a code smell, in my experience, and a pretty reliable sign that the devs who are using these optionals are "missing the point". Indeed, it gives basically no benefit over ref == null, but it's also not something you should be using often. Even if the team is unstable, a static analysis tool can lay down the law, like a linter or FindBugs, which can catch most cases.

          – Alexander
          Feb 26 at 20:29








        • 3





          @FrankHopkins: It may be that the Java community just needs a little paradigm shift, which may yet take many years. If you look at Scala, for example, it supports null because the language is 100% compatible to Java, but nobody uses it, and Option[T] is all over the place, with excellent functional-programming support like map, flatMap, pattern matching and so on, which goes far, far beyond == null checks. You are right that in theory, an option type sounds like little more than a glorified pointer, but reality proves that argument wrong.

          – Christian Hackl
          Feb 27 at 5:28








        8




        8





        There's Optional in java too; the meaning of a null Optional being up to you...

        – Matthieu M.
        Feb 26 at 11:22





        There's Optional in java too; the meaning of a null Optional being up to you...

        – Matthieu M.
        Feb 26 at 11:22




        1




        1





        Came here to connect with Optional as well. I'd encode this as a type in a language which had them.

        – Zipp
        Feb 26 at 18:38





        Came here to connect with Optional as well. I'd encode this as a type in a language which had them.

        – Zipp
        Feb 26 at 18:38




        2




        2





        @FrankHopkins It's a shame that nothing in Java prevents you from writing Optional<Date> lastPasswordChangeTime = null;, but I wouldn't give up just because of that. Instead, I would instill a very firmly held team rule, that no optional values are ever allowed to be assign null. Optional buys you too many nice features to give up on that easily. You can easily assign default values (orElse or with lazy evaluation: orElseGet), throw errors (orElseThrow), transform values in a null safe way (map, flatmap), etc.

        – Alexander
        Feb 26 at 20:15





        @FrankHopkins It's a shame that nothing in Java prevents you from writing Optional<Date> lastPasswordChangeTime = null;, but I wouldn't give up just because of that. Instead, I would instill a very firmly held team rule, that no optional values are ever allowed to be assign null. Optional buys you too many nice features to give up on that easily. You can easily assign default values (orElse or with lazy evaluation: orElseGet), throw errors (orElseThrow), transform values in a null safe way (map, flatmap), etc.

        – Alexander
        Feb 26 at 20:15




        3




        3





        @FrankHopkins Checking isPresent is almost always a code smell, in my experience, and a pretty reliable sign that the devs who are using these optionals are "missing the point". Indeed, it gives basically no benefit over ref == null, but it's also not something you should be using often. Even if the team is unstable, a static analysis tool can lay down the law, like a linter or FindBugs, which can catch most cases.

        – Alexander
        Feb 26 at 20:29







        @FrankHopkins Checking isPresent is almost always a code smell, in my experience, and a pretty reliable sign that the devs who are using these optionals are "missing the point". Indeed, it gives basically no benefit over ref == null, but it's also not something you should be using often. Even if the team is unstable, a static analysis tool can lay down the law, like a linter or FindBugs, which can catch most cases.

        – Alexander
        Feb 26 at 20:29






        3




        3





        @FrankHopkins: It may be that the Java community just needs a little paradigm shift, which may yet take many years. If you look at Scala, for example, it supports null because the language is 100% compatible to Java, but nobody uses it, and Option[T] is all over the place, with excellent functional-programming support like map, flatMap, pattern matching and so on, which goes far, far beyond == null checks. You are right that in theory, an option type sounds like little more than a glorified pointer, but reality proves that argument wrong.

        – Christian Hackl
        Feb 27 at 5:28





        @FrankHopkins: It may be that the Java community just needs a little paradigm shift, which may yet take many years. If you look at Scala, for example, it supports null because the language is 100% compatible to Java, but nobody uses it, and Option[T] is all over the place, with excellent functional-programming support like map, flatMap, pattern matching and so on, which goes far, far beyond == null checks. You are right that in theory, an option type sounds like little more than a glorified pointer, but reality proves that argument wrong.

        – Christian Hackl
        Feb 27 at 5:28











        11














        Correctly using null



        There are different ways of using null. The most common and semantically correct way is to use it when you may or may not have a single value. In this case a value either equals null or is something meaningful like a record from database or something.



        In these situations you then mostly use it like this (in pseudo-code):



        if (value is null) {
        doSomethingAboutIt();
        return;
        }

        doSomethingUseful(value);


        Problem



        And it has a very big problem. The problem is that by the time you invoke doSomethingUseful the value may not have been checked for null! If it wasn't then the program will likely crash. And the user may not even see any good error messages, being left with something like "horrible error: wanted value but got null!"(after update: although there may be even less informative error like Segmentation fault. Core dumped., or worse yet, no error and incorrect manipulation on null in some cases)



        Forgetting to write checks for null and handling null situations is an extremely common bug. This is why Tony Hoare who invented null said at a software conference called QCon London in 2009 that he made the billion-dollar mistake in 1965:
        https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare



        Avoiding the problem



        Some technologies and languages make checking for null impossible to forget in different ways, reducing amount of bugs.



        For example Haskell has the Maybe monad instead of nulls. Suppose that DatabaseRecord is a user-defined type. In Haskell a value of type Maybe DatabaseRecord can be equal Just <somevalue> or it may be equal to Nothing. You can then use it in different ways but no matter how you use it you cannot apply some operation on Nothing without knowing it.



        For instance this function called zeroAsDefault returns x for Just x and 0 for Nothing:



        zeroAsDefault :: Maybe Int -> Int
        zeroAsDefault mx = case mx of
        Nothing -> 0
        Just x -> x


        Christian Hackl says C++17 and Scala have their own ways. So you may want to try to find out if your language has anything like that and use it.



        Nulls are still in wide use



        If you don't have anything better then using null is fine. Just keep watching out for it. Type declarations in functions will help you somewhat anyway.



        Also that may sound not very progressive but you should check if your colleagues want to use null or something else. They may be conservative and may not want to use new data structures for some reasons. For instance supporting older versions of a language. Such things should be declared in project's coding standards and properly discussed with the team.



        On your proposal



        You suggest using a separate boolean field. But you have to check it anyway and still may forget to check it. So there is nothing won here. If you can even forget something else, like updating both values each time, then it's even worse. If the problem of forgetting to check for null is not solved then there is no point. Avoiding null is difficult and you should not do it in such a way that makes it worse.



        How not to use null



        Finally there are common ways to use null incorrectly. One such way is to use it in place of empty data structures such as arrays and strings. Empty array is a proper array like any other! It is almost always important and useful for data structures, that can fit multiple values, to be able to be empty, i.e. has 0 length.



        From algebra standpoint an empty string for strings is much like 0 for numbers, i.e. identity:



        a+0=a
        concat(str, '')=str


        Empty string enables strings in general to become a monoid:
        https://en.wikipedia.org/wiki/Monoid
        If you don't get it it's not that important for you.



        Now let's see why it's important for programming with this example:



        for (element in array) {
        doSomething(element);
        }


        If we pass an empty array in here the code will work fine. It will just do nothing. However if we pass a null here then we will likely get a crash with an error like "can't loop through null, sorry". We could wrap it in if but that's less clean and again, you might forget to check it



        How to handle null



        What doSomethingAboutIt() should be doing and especially weather it should throw an exception is another complicated issue. In short it depends on weather null was acceptable input value for given task and what is expected in response. Exceptions are for events that were not expected. I will not go further into that topic. The answer very is long already.






        share|improve this answer





















        • 5





          Actually, horrible error: wanted value but got null! is much better than the more typical Segmentation fault. Core dumped....

          – Toby Speight
          Feb 26 at 17:57






        • 2





          @TobySpeight True, but I would prefer something that lays inside user's terms like Error: the product you want to buy is out of stock.

          – Gherman
          Feb 26 at 18:10











        • Sure - I was just observing that it could be (and often is) even worse. I completely agree on what would be better! And your answer is pretty much what I would have said to this question: +1.

          – Toby Speight
          Feb 26 at 20:35








        • 2





          @Gherman: Passing null where null is not allowed is a programming error, i.e. a bug in the code. A product being out of stock is part of the ordinary business logic and not a bug. You cannot, and should not try to, translate the detection of a bug to a normal message in the user interface. Crashing immediately and not executing more code is the preferred course of action, especially if it's an important application (e.g. one that performs real financial transactions).

          – Christian Hackl
          Feb 27 at 9:41






        • 1





          @EricDuminil We want to remove(or reduce) possibility of making a mistake, not remove null itself entirely, even from the background.

          – Gherman
          Feb 28 at 12:55
















        11














        Correctly using null



        There are different ways of using null. The most common and semantically correct way is to use it when you may or may not have a single value. In this case a value either equals null or is something meaningful like a record from database or something.



        In these situations you then mostly use it like this (in pseudo-code):



        if (value is null) {
        doSomethingAboutIt();
        return;
        }

        doSomethingUseful(value);


        Problem



        And it has a very big problem. The problem is that by the time you invoke doSomethingUseful the value may not have been checked for null! If it wasn't then the program will likely crash. And the user may not even see any good error messages, being left with something like "horrible error: wanted value but got null!"(after update: although there may be even less informative error like Segmentation fault. Core dumped., or worse yet, no error and incorrect manipulation on null in some cases)



        Forgetting to write checks for null and handling null situations is an extremely common bug. This is why Tony Hoare who invented null said at a software conference called QCon London in 2009 that he made the billion-dollar mistake in 1965:
        https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare



        Avoiding the problem



        Some technologies and languages make checking for null impossible to forget in different ways, reducing amount of bugs.



        For example Haskell has the Maybe monad instead of nulls. Suppose that DatabaseRecord is a user-defined type. In Haskell a value of type Maybe DatabaseRecord can be equal Just <somevalue> or it may be equal to Nothing. You can then use it in different ways but no matter how you use it you cannot apply some operation on Nothing without knowing it.



        For instance this function called zeroAsDefault returns x for Just x and 0 for Nothing:



        zeroAsDefault :: Maybe Int -> Int
        zeroAsDefault mx = case mx of
        Nothing -> 0
        Just x -> x


        Christian Hackl says C++17 and Scala have their own ways. So you may want to try to find out if your language has anything like that and use it.



        Nulls are still in wide use



        If you don't have anything better then using null is fine. Just keep watching out for it. Type declarations in functions will help you somewhat anyway.



        Also that may sound not very progressive but you should check if your colleagues want to use null or something else. They may be conservative and may not want to use new data structures for some reasons. For instance supporting older versions of a language. Such things should be declared in project's coding standards and properly discussed with the team.



        On your proposal



        You suggest using a separate boolean field. But you have to check it anyway and still may forget to check it. So there is nothing won here. If you can even forget something else, like updating both values each time, then it's even worse. If the problem of forgetting to check for null is not solved then there is no point. Avoiding null is difficult and you should not do it in such a way that makes it worse.



        How not to use null



        Finally there are common ways to use null incorrectly. One such way is to use it in place of empty data structures such as arrays and strings. Empty array is a proper array like any other! It is almost always important and useful for data structures, that can fit multiple values, to be able to be empty, i.e. has 0 length.



        From algebra standpoint an empty string for strings is much like 0 for numbers, i.e. identity:



        a+0=a
        concat(str, '')=str


        Empty string enables strings in general to become a monoid:
        https://en.wikipedia.org/wiki/Monoid
        If you don't get it it's not that important for you.



        Now let's see why it's important for programming with this example:



        for (element in array) {
        doSomething(element);
        }


        If we pass an empty array in here the code will work fine. It will just do nothing. However if we pass a null here then we will likely get a crash with an error like "can't loop through null, sorry". We could wrap it in if but that's less clean and again, you might forget to check it



        How to handle null



        What doSomethingAboutIt() should be doing and especially weather it should throw an exception is another complicated issue. In short it depends on weather null was acceptable input value for given task and what is expected in response. Exceptions are for events that were not expected. I will not go further into that topic. The answer very is long already.






        share|improve this answer





















        • 5





          Actually, horrible error: wanted value but got null! is much better than the more typical Segmentation fault. Core dumped....

          – Toby Speight
          Feb 26 at 17:57






        • 2





          @TobySpeight True, but I would prefer something that lays inside user's terms like Error: the product you want to buy is out of stock.

          – Gherman
          Feb 26 at 18:10











        • Sure - I was just observing that it could be (and often is) even worse. I completely agree on what would be better! And your answer is pretty much what I would have said to this question: +1.

          – Toby Speight
          Feb 26 at 20:35








        • 2





          @Gherman: Passing null where null is not allowed is a programming error, i.e. a bug in the code. A product being out of stock is part of the ordinary business logic and not a bug. You cannot, and should not try to, translate the detection of a bug to a normal message in the user interface. Crashing immediately and not executing more code is the preferred course of action, especially if it's an important application (e.g. one that performs real financial transactions).

          – Christian Hackl
          Feb 27 at 9:41






        • 1





          @EricDuminil We want to remove(or reduce) possibility of making a mistake, not remove null itself entirely, even from the background.

          – Gherman
          Feb 28 at 12:55














        11












        11








        11







        Correctly using null



        There are different ways of using null. The most common and semantically correct way is to use it when you may or may not have a single value. In this case a value either equals null or is something meaningful like a record from database or something.



        In these situations you then mostly use it like this (in pseudo-code):



        if (value is null) {
        doSomethingAboutIt();
        return;
        }

        doSomethingUseful(value);


        Problem



        And it has a very big problem. The problem is that by the time you invoke doSomethingUseful the value may not have been checked for null! If it wasn't then the program will likely crash. And the user may not even see any good error messages, being left with something like "horrible error: wanted value but got null!"(after update: although there may be even less informative error like Segmentation fault. Core dumped., or worse yet, no error and incorrect manipulation on null in some cases)



        Forgetting to write checks for null and handling null situations is an extremely common bug. This is why Tony Hoare who invented null said at a software conference called QCon London in 2009 that he made the billion-dollar mistake in 1965:
        https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare



        Avoiding the problem



        Some technologies and languages make checking for null impossible to forget in different ways, reducing amount of bugs.



        For example Haskell has the Maybe monad instead of nulls. Suppose that DatabaseRecord is a user-defined type. In Haskell a value of type Maybe DatabaseRecord can be equal Just <somevalue> or it may be equal to Nothing. You can then use it in different ways but no matter how you use it you cannot apply some operation on Nothing without knowing it.



        For instance this function called zeroAsDefault returns x for Just x and 0 for Nothing:



        zeroAsDefault :: Maybe Int -> Int
        zeroAsDefault mx = case mx of
        Nothing -> 0
        Just x -> x


        Christian Hackl says C++17 and Scala have their own ways. So you may want to try to find out if your language has anything like that and use it.



        Nulls are still in wide use



        If you don't have anything better then using null is fine. Just keep watching out for it. Type declarations in functions will help you somewhat anyway.



        Also that may sound not very progressive but you should check if your colleagues want to use null or something else. They may be conservative and may not want to use new data structures for some reasons. For instance supporting older versions of a language. Such things should be declared in project's coding standards and properly discussed with the team.



        On your proposal



        You suggest using a separate boolean field. But you have to check it anyway and still may forget to check it. So there is nothing won here. If you can even forget something else, like updating both values each time, then it's even worse. If the problem of forgetting to check for null is not solved then there is no point. Avoiding null is difficult and you should not do it in such a way that makes it worse.



        How not to use null



        Finally there are common ways to use null incorrectly. One such way is to use it in place of empty data structures such as arrays and strings. Empty array is a proper array like any other! It is almost always important and useful for data structures, that can fit multiple values, to be able to be empty, i.e. has 0 length.



        From algebra standpoint an empty string for strings is much like 0 for numbers, i.e. identity:



        a+0=a
        concat(str, '')=str


        Empty string enables strings in general to become a monoid:
        https://en.wikipedia.org/wiki/Monoid
        If you don't get it it's not that important for you.



        Now let's see why it's important for programming with this example:



        for (element in array) {
        doSomething(element);
        }


        If we pass an empty array in here the code will work fine. It will just do nothing. However if we pass a null here then we will likely get a crash with an error like "can't loop through null, sorry". We could wrap it in if but that's less clean and again, you might forget to check it



        How to handle null



        What doSomethingAboutIt() should be doing and especially weather it should throw an exception is another complicated issue. In short it depends on weather null was acceptable input value for given task and what is expected in response. Exceptions are for events that were not expected. I will not go further into that topic. The answer very is long already.






        share|improve this answer















        Correctly using null



        There are different ways of using null. The most common and semantically correct way is to use it when you may or may not have a single value. In this case a value either equals null or is something meaningful like a record from database or something.



        In these situations you then mostly use it like this (in pseudo-code):



        if (value is null) {
        doSomethingAboutIt();
        return;
        }

        doSomethingUseful(value);


        Problem



        And it has a very big problem. The problem is that by the time you invoke doSomethingUseful the value may not have been checked for null! If it wasn't then the program will likely crash. And the user may not even see any good error messages, being left with something like "horrible error: wanted value but got null!"(after update: although there may be even less informative error like Segmentation fault. Core dumped., or worse yet, no error and incorrect manipulation on null in some cases)



        Forgetting to write checks for null and handling null situations is an extremely common bug. This is why Tony Hoare who invented null said at a software conference called QCon London in 2009 that he made the billion-dollar mistake in 1965:
        https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare



        Avoiding the problem



        Some technologies and languages make checking for null impossible to forget in different ways, reducing amount of bugs.



        For example Haskell has the Maybe monad instead of nulls. Suppose that DatabaseRecord is a user-defined type. In Haskell a value of type Maybe DatabaseRecord can be equal Just <somevalue> or it may be equal to Nothing. You can then use it in different ways but no matter how you use it you cannot apply some operation on Nothing without knowing it.



        For instance this function called zeroAsDefault returns x for Just x and 0 for Nothing:



        zeroAsDefault :: Maybe Int -> Int
        zeroAsDefault mx = case mx of
        Nothing -> 0
        Just x -> x


        Christian Hackl says C++17 and Scala have their own ways. So you may want to try to find out if your language has anything like that and use it.



        Nulls are still in wide use



        If you don't have anything better then using null is fine. Just keep watching out for it. Type declarations in functions will help you somewhat anyway.



        Also that may sound not very progressive but you should check if your colleagues want to use null or something else. They may be conservative and may not want to use new data structures for some reasons. For instance supporting older versions of a language. Such things should be declared in project's coding standards and properly discussed with the team.



        On your proposal



        You suggest using a separate boolean field. But you have to check it anyway and still may forget to check it. So there is nothing won here. If you can even forget something else, like updating both values each time, then it's even worse. If the problem of forgetting to check for null is not solved then there is no point. Avoiding null is difficult and you should not do it in such a way that makes it worse.



        How not to use null



        Finally there are common ways to use null incorrectly. One such way is to use it in place of empty data structures such as arrays and strings. Empty array is a proper array like any other! It is almost always important and useful for data structures, that can fit multiple values, to be able to be empty, i.e. has 0 length.



        From algebra standpoint an empty string for strings is much like 0 for numbers, i.e. identity:



        a+0=a
        concat(str, '')=str


        Empty string enables strings in general to become a monoid:
        https://en.wikipedia.org/wiki/Monoid
        If you don't get it it's not that important for you.



        Now let's see why it's important for programming with this example:



        for (element in array) {
        doSomething(element);
        }


        If we pass an empty array in here the code will work fine. It will just do nothing. However if we pass a null here then we will likely get a crash with an error like "can't loop through null, sorry". We could wrap it in if but that's less clean and again, you might forget to check it



        How to handle null



        What doSomethingAboutIt() should be doing and especially weather it should throw an exception is another complicated issue. In short it depends on weather null was acceptable input value for given task and what is expected in response. Exceptions are for events that were not expected. I will not go further into that topic. The answer very is long already.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Feb 27 at 15:32

























        answered Feb 26 at 16:59









        GhermanGherman

        493511




        493511








        • 5





          Actually, horrible error: wanted value but got null! is much better than the more typical Segmentation fault. Core dumped....

          – Toby Speight
          Feb 26 at 17:57






        • 2





          @TobySpeight True, but I would prefer something that lays inside user's terms like Error: the product you want to buy is out of stock.

          – Gherman
          Feb 26 at 18:10











        • Sure - I was just observing that it could be (and often is) even worse. I completely agree on what would be better! And your answer is pretty much what I would have said to this question: +1.

          – Toby Speight
          Feb 26 at 20:35








        • 2





          @Gherman: Passing null where null is not allowed is a programming error, i.e. a bug in the code. A product being out of stock is part of the ordinary business logic and not a bug. You cannot, and should not try to, translate the detection of a bug to a normal message in the user interface. Crashing immediately and not executing more code is the preferred course of action, especially if it's an important application (e.g. one that performs real financial transactions).

          – Christian Hackl
          Feb 27 at 9:41






        • 1





          @EricDuminil We want to remove(or reduce) possibility of making a mistake, not remove null itself entirely, even from the background.

          – Gherman
          Feb 28 at 12:55














        • 5





          Actually, horrible error: wanted value but got null! is much better than the more typical Segmentation fault. Core dumped....

          – Toby Speight
          Feb 26 at 17:57






        • 2





          @TobySpeight True, but I would prefer something that lays inside user's terms like Error: the product you want to buy is out of stock.

          – Gherman
          Feb 26 at 18:10











        • Sure - I was just observing that it could be (and often is) even worse. I completely agree on what would be better! And your answer is pretty much what I would have said to this question: +1.

          – Toby Speight
          Feb 26 at 20:35








        • 2





          @Gherman: Passing null where null is not allowed is a programming error, i.e. a bug in the code. A product being out of stock is part of the ordinary business logic and not a bug. You cannot, and should not try to, translate the detection of a bug to a normal message in the user interface. Crashing immediately and not executing more code is the preferred course of action, especially if it's an important application (e.g. one that performs real financial transactions).

          – Christian Hackl
          Feb 27 at 9:41






        • 1





          @EricDuminil We want to remove(or reduce) possibility of making a mistake, not remove null itself entirely, even from the background.

          – Gherman
          Feb 28 at 12:55








        5




        5





        Actually, horrible error: wanted value but got null! is much better than the more typical Segmentation fault. Core dumped....

        – Toby Speight
        Feb 26 at 17:57





        Actually, horrible error: wanted value but got null! is much better than the more typical Segmentation fault. Core dumped....

        – Toby Speight
        Feb 26 at 17:57




        2




        2





        @TobySpeight True, but I would prefer something that lays inside user's terms like Error: the product you want to buy is out of stock.

        – Gherman
        Feb 26 at 18:10





        @TobySpeight True, but I would prefer something that lays inside user's terms like Error: the product you want to buy is out of stock.

        – Gherman
        Feb 26 at 18:10













        Sure - I was just observing that it could be (and often is) even worse. I completely agree on what would be better! And your answer is pretty much what I would have said to this question: +1.

        – Toby Speight
        Feb 26 at 20:35







        Sure - I was just observing that it could be (and often is) even worse. I completely agree on what would be better! And your answer is pretty much what I would have said to this question: +1.

        – Toby Speight
        Feb 26 at 20:35






        2




        2





        @Gherman: Passing null where null is not allowed is a programming error, i.e. a bug in the code. A product being out of stock is part of the ordinary business logic and not a bug. You cannot, and should not try to, translate the detection of a bug to a normal message in the user interface. Crashing immediately and not executing more code is the preferred course of action, especially if it's an important application (e.g. one that performs real financial transactions).

        – Christian Hackl
        Feb 27 at 9:41





        @Gherman: Passing null where null is not allowed is a programming error, i.e. a bug in the code. A product being out of stock is part of the ordinary business logic and not a bug. You cannot, and should not try to, translate the detection of a bug to a normal message in the user interface. Crashing immediately and not executing more code is the preferred course of action, especially if it's an important application (e.g. one that performs real financial transactions).

        – Christian Hackl
        Feb 27 at 9:41




        1




        1





        @EricDuminil We want to remove(or reduce) possibility of making a mistake, not remove null itself entirely, even from the background.

        – Gherman
        Feb 28 at 12:55





        @EricDuminil We want to remove(or reduce) possibility of making a mistake, not remove null itself entirely, even from the background.

        – Gherman
        Feb 28 at 12:55











        4














        In addition to all of the very good answers previously given, I'd add that every time you're tempted to let a field be null, think carefully if it might be a list type. A nullable type is equivalently a list of 0 or 1 elements, and often this can be generalized to a list of N elements. Specifically in this case, you might want to consider lastChangePasswordTime being a list of passwordChangeTimes.






        share|improve this answer
























        • That's an excellent point. The same is often true for option types; an option can be seen as special case of a sequence.

          – Christian Hackl
          Feb 27 at 10:24
















        4














        In addition to all of the very good answers previously given, I'd add that every time you're tempted to let a field be null, think carefully if it might be a list type. A nullable type is equivalently a list of 0 or 1 elements, and often this can be generalized to a list of N elements. Specifically in this case, you might want to consider lastChangePasswordTime being a list of passwordChangeTimes.






        share|improve this answer
























        • That's an excellent point. The same is often true for option types; an option can be seen as special case of a sequence.

          – Christian Hackl
          Feb 27 at 10:24














        4












        4








        4







        In addition to all of the very good answers previously given, I'd add that every time you're tempted to let a field be null, think carefully if it might be a list type. A nullable type is equivalently a list of 0 or 1 elements, and often this can be generalized to a list of N elements. Specifically in this case, you might want to consider lastChangePasswordTime being a list of passwordChangeTimes.






        share|improve this answer













        In addition to all of the very good answers previously given, I'd add that every time you're tempted to let a field be null, think carefully if it might be a list type. A nullable type is equivalently a list of 0 or 1 elements, and often this can be generalized to a list of N elements. Specifically in this case, you might want to consider lastChangePasswordTime being a list of passwordChangeTimes.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Feb 26 at 16:22









        JoelJoel

        1816




        1816













        • That's an excellent point. The same is often true for option types; an option can be seen as special case of a sequence.

          – Christian Hackl
          Feb 27 at 10:24



















        • That's an excellent point. The same is often true for option types; an option can be seen as special case of a sequence.

          – Christian Hackl
          Feb 27 at 10:24

















        That's an excellent point. The same is often true for option types; an option can be seen as special case of a sequence.

        – Christian Hackl
        Feb 27 at 10:24





        That's an excellent point. The same is often true for option types; an option can be seen as special case of a sequence.

        – Christian Hackl
        Feb 27 at 10:24











        2














        Ask yourself this: which behavior requires the field lastChangePasswordTime?



        If you need that field for a method IsPasswordExpired() to determine if a Member should be prompted to change their password every so often, I would set the field to the time the Member was initially created.
        The IsPasswordExpired() implementation is the same for new and existing members.



        class Member{
        private DateTime lastChangePasswordTime;

        public Member(DateTime lastChangePasswordTime) {
        // set value, maybe check for null
        }

        public bool IsPasswordExpired() {
        DateTime limit = DateTime.Now.AddMonths(-3);
        return lastChangePasswordTime < limit;
        }
        }


        If you have a separate requirement that newly created members have to update their password, I would add a separated boolean field called passwordShouldBeChanged and set it to true upon creation. I would then change the functionality of the IsPasswordExpired() method to include a check for that field (and rename the method to ShouldChangePassword).



        class Member{
        private DateTime lastChangePasswordTime;
        private bool passwordShouldBeChanged;

        public Member(DateTime lastChangePasswordTime, bool passwordShouldBeChanged) {
        // set values, maybe check for nulls
        }

        public bool ShouldChangePassword() {
        return PasswordExpired(lastChangePasswordTime) || passwordShouldBeChanged;
        }

        private static bool PasswordExpired(DateTime lastChangePasswordTime) {
        DateTime limit = DateTime.Now.AddMonths(-3);
        return lastChangePasswordTime < limit;
        }
        }


        Make your intentions explicit in code.






        share|improve this answer




























          2














          Ask yourself this: which behavior requires the field lastChangePasswordTime?



          If you need that field for a method IsPasswordExpired() to determine if a Member should be prompted to change their password every so often, I would set the field to the time the Member was initially created.
          The IsPasswordExpired() implementation is the same for new and existing members.



          class Member{
          private DateTime lastChangePasswordTime;

          public Member(DateTime lastChangePasswordTime) {
          // set value, maybe check for null
          }

          public bool IsPasswordExpired() {
          DateTime limit = DateTime.Now.AddMonths(-3);
          return lastChangePasswordTime < limit;
          }
          }


          If you have a separate requirement that newly created members have to update their password, I would add a separated boolean field called passwordShouldBeChanged and set it to true upon creation. I would then change the functionality of the IsPasswordExpired() method to include a check for that field (and rename the method to ShouldChangePassword).



          class Member{
          private DateTime lastChangePasswordTime;
          private bool passwordShouldBeChanged;

          public Member(DateTime lastChangePasswordTime, bool passwordShouldBeChanged) {
          // set values, maybe check for nulls
          }

          public bool ShouldChangePassword() {
          return PasswordExpired(lastChangePasswordTime) || passwordShouldBeChanged;
          }

          private static bool PasswordExpired(DateTime lastChangePasswordTime) {
          DateTime limit = DateTime.Now.AddMonths(-3);
          return lastChangePasswordTime < limit;
          }
          }


          Make your intentions explicit in code.






          share|improve this answer


























            2












            2








            2







            Ask yourself this: which behavior requires the field lastChangePasswordTime?



            If you need that field for a method IsPasswordExpired() to determine if a Member should be prompted to change their password every so often, I would set the field to the time the Member was initially created.
            The IsPasswordExpired() implementation is the same for new and existing members.



            class Member{
            private DateTime lastChangePasswordTime;

            public Member(DateTime lastChangePasswordTime) {
            // set value, maybe check for null
            }

            public bool IsPasswordExpired() {
            DateTime limit = DateTime.Now.AddMonths(-3);
            return lastChangePasswordTime < limit;
            }
            }


            If you have a separate requirement that newly created members have to update their password, I would add a separated boolean field called passwordShouldBeChanged and set it to true upon creation. I would then change the functionality of the IsPasswordExpired() method to include a check for that field (and rename the method to ShouldChangePassword).



            class Member{
            private DateTime lastChangePasswordTime;
            private bool passwordShouldBeChanged;

            public Member(DateTime lastChangePasswordTime, bool passwordShouldBeChanged) {
            // set values, maybe check for nulls
            }

            public bool ShouldChangePassword() {
            return PasswordExpired(lastChangePasswordTime) || passwordShouldBeChanged;
            }

            private static bool PasswordExpired(DateTime lastChangePasswordTime) {
            DateTime limit = DateTime.Now.AddMonths(-3);
            return lastChangePasswordTime < limit;
            }
            }


            Make your intentions explicit in code.






            share|improve this answer













            Ask yourself this: which behavior requires the field lastChangePasswordTime?



            If you need that field for a method IsPasswordExpired() to determine if a Member should be prompted to change their password every so often, I would set the field to the time the Member was initially created.
            The IsPasswordExpired() implementation is the same for new and existing members.



            class Member{
            private DateTime lastChangePasswordTime;

            public Member(DateTime lastChangePasswordTime) {
            // set value, maybe check for null
            }

            public bool IsPasswordExpired() {
            DateTime limit = DateTime.Now.AddMonths(-3);
            return lastChangePasswordTime < limit;
            }
            }


            If you have a separate requirement that newly created members have to update their password, I would add a separated boolean field called passwordShouldBeChanged and set it to true upon creation. I would then change the functionality of the IsPasswordExpired() method to include a check for that field (and rename the method to ShouldChangePassword).



            class Member{
            private DateTime lastChangePasswordTime;
            private bool passwordShouldBeChanged;

            public Member(DateTime lastChangePasswordTime, bool passwordShouldBeChanged) {
            // set values, maybe check for nulls
            }

            public bool ShouldChangePassword() {
            return PasswordExpired(lastChangePasswordTime) || passwordShouldBeChanged;
            }

            private static bool PasswordExpired(DateTime lastChangePasswordTime) {
            DateTime limit = DateTime.Now.AddMonths(-3);
            return lastChangePasswordTime < limit;
            }
            }


            Make your intentions explicit in code.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Feb 26 at 14:18









            Rik DRik D

            32029




            32029























                2














                First, nulls being evil is dogma and as usual with dogma it works best as a guideline and not as pass/no pass test.



                Secondly, you can redefine your situation in a way that it makes sense that the value can never be null. InititialPasswordChanged is a Boolean initially set to false, PasswordSetTime is the date and time when the current password was set.



                Note that while this does come at a slight cost, you can now ALWAYS calculate how long it has been since a password was last set.






                share|improve this answer




























                  2














                  First, nulls being evil is dogma and as usual with dogma it works best as a guideline and not as pass/no pass test.



                  Secondly, you can redefine your situation in a way that it makes sense that the value can never be null. InititialPasswordChanged is a Boolean initially set to false, PasswordSetTime is the date and time when the current password was set.



                  Note that while this does come at a slight cost, you can now ALWAYS calculate how long it has been since a password was last set.






                  share|improve this answer


























                    2












                    2








                    2







                    First, nulls being evil is dogma and as usual with dogma it works best as a guideline and not as pass/no pass test.



                    Secondly, you can redefine your situation in a way that it makes sense that the value can never be null. InititialPasswordChanged is a Boolean initially set to false, PasswordSetTime is the date and time when the current password was set.



                    Note that while this does come at a slight cost, you can now ALWAYS calculate how long it has been since a password was last set.






                    share|improve this answer













                    First, nulls being evil is dogma and as usual with dogma it works best as a guideline and not as pass/no pass test.



                    Secondly, you can redefine your situation in a way that it makes sense that the value can never be null. InititialPasswordChanged is a Boolean initially set to false, PasswordSetTime is the date and time when the current password was set.



                    Note that while this does come at a slight cost, you can now ALWAYS calculate how long it has been since a password was last set.







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Feb 27 at 11:39









                    jmorenojmoreno

                    8,88712244




                    8,88712244























                        1














                        First, both are 'safe/sane/correct' if the caller checks before use.
                        This issue is what happens if they don't. Which is better: "some flavour of null error" or "using an invalid value".



                        But there really is no 1 answer that's right here. It really depends on what you are worried about.



                        If crashes are really bad but the answer isn't critical / has an excepted default value, then maybe a boolean as a flag is better. If using the wrong answer is a real problem but crashing is not so bad, then null is better.



                        For the majority of the 'typical' cases, fast failure and forcing the callers to check is the fastest way to sane code and hence I think null should be the default choice, but I wouldn't put too much faith in the "X is the root of all evil" evangelists. They normally haven't anticipated all the use cases.






                        share|improve this answer








                        New contributor




                        ANone is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                        Check out our Code of Conduct.

























                          1














                          First, both are 'safe/sane/correct' if the caller checks before use.
                          This issue is what happens if they don't. Which is better: "some flavour of null error" or "using an invalid value".



                          But there really is no 1 answer that's right here. It really depends on what you are worried about.



                          If crashes are really bad but the answer isn't critical / has an excepted default value, then maybe a boolean as a flag is better. If using the wrong answer is a real problem but crashing is not so bad, then null is better.



                          For the majority of the 'typical' cases, fast failure and forcing the callers to check is the fastest way to sane code and hence I think null should be the default choice, but I wouldn't put too much faith in the "X is the root of all evil" evangelists. They normally haven't anticipated all the use cases.






                          share|improve this answer








                          New contributor




                          ANone is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                          Check out our Code of Conduct.























                            1












                            1








                            1







                            First, both are 'safe/sane/correct' if the caller checks before use.
                            This issue is what happens if they don't. Which is better: "some flavour of null error" or "using an invalid value".



                            But there really is no 1 answer that's right here. It really depends on what you are worried about.



                            If crashes are really bad but the answer isn't critical / has an excepted default value, then maybe a boolean as a flag is better. If using the wrong answer is a real problem but crashing is not so bad, then null is better.



                            For the majority of the 'typical' cases, fast failure and forcing the callers to check is the fastest way to sane code and hence I think null should be the default choice, but I wouldn't put too much faith in the "X is the root of all evil" evangelists. They normally haven't anticipated all the use cases.






                            share|improve this answer








                            New contributor




                            ANone is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                            Check out our Code of Conduct.










                            First, both are 'safe/sane/correct' if the caller checks before use.
                            This issue is what happens if they don't. Which is better: "some flavour of null error" or "using an invalid value".



                            But there really is no 1 answer that's right here. It really depends on what you are worried about.



                            If crashes are really bad but the answer isn't critical / has an excepted default value, then maybe a boolean as a flag is better. If using the wrong answer is a real problem but crashing is not so bad, then null is better.



                            For the majority of the 'typical' cases, fast failure and forcing the callers to check is the fastest way to sane code and hence I think null should be the default choice, but I wouldn't put too much faith in the "X is the root of all evil" evangelists. They normally haven't anticipated all the use cases.







                            share|improve this answer








                            New contributor




                            ANone is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                            Check out our Code of Conduct.









                            share|improve this answer



                            share|improve this answer






                            New contributor




                            ANone is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                            Check out our Code of Conduct.









                            answered Feb 27 at 16:15









                            ANoneANone

                            24413




                            24413




                            New contributor




                            ANone is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                            Check out our Code of Conduct.





                            New contributor





                            ANone is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                            Check out our Code of Conduct.






                            ANone is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                            Check out our Code of Conduct.






























                                draft saved

                                draft discarded




















































                                Thanks for contributing an answer to Software Engineering Stack Exchange!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f387720%2fis-a-new-boolean-field-better-than-a-null-reference-when-a-value-can-be-meaningf%23new-answer', 'question_page');
                                }
                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown











                                Popular posts from this blog

                                Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

                                ComboBox Display Member on multiple fields

                                Is it possible to collect Nectar points via Trainline?