Is a new Boolean field better than a null reference when a value can be meaningfully absent?2019 Community...
Dilemma of explaining to interviewer that he is the reason for declining second interview
Why exactly do action photographers need high fps burst cameras?
Making him into a bully (how to show mild violence)
If I delete my router's history can my ISP still provide it to my parents?
Eww, those bytes are gross
Why would space fleets be aligned?
Why is it that Bernie Sanders is always called a "socialist"?
How can prove this integral
Avoid page break between paragraphs
What is the wife of a henpecked husband called?
Why avoid shared user accounts?
Citing paywalled articles accessed via illegal web sharing
How would an AI self awareness kill switch work?
Early credit roll before the end of the film
Crontab: Ubuntu running script (noob)
Am I a Rude Number?
Why did the villain in the first Men in Black movie care about Earth's Cockroaches?
False written accusations not made public - is there law to cover this?
Clues on how to solve these types of problems within 2-3 minutes for competitive exams
What's a good word to describe a public place that looks like it wouldn't be rough?
How should I handle players who ignore the session zero agreement?
Constexpr if with a non-bool condition
How do you catch Smeargle in Pokemon Go?
Is it possible to grant users sftp access without shell access? If yes, how is it implemented?
Is a new Boolean field better than a null reference when a value can be meaningfully absent?
2019 Community Moderator ElectionIf nulls are evil, what should be used when a value can be meaningfully absent?Should I store False as Null in a boolean database field?Why is a Boolean value stored as a byte inside of a computer when it only requires one bitHandling “unspecified” values in softwareWhen do the benefits of nullable value types outweigh the cost of null pointers?Do any languages make evaluation of the right-hand of an “AND” operation optional?If nulls are evil, what should be used when a value can be meaningfully absent?C# 8 non-nullable references and the Try pattern
For example, suppose I have a class, Member
, which has a lastChangePasswordTime:
class Member{
.
.
.
constructor(){
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?, I shouldn't use null to represent a meaningfully absent value. So I try to add a Boolean flag:
class Member{
.
.
.
constructor(){
isPasswordChanged:false,
lastChangePasswordTime=null,
}
}
But I think it is quite obsolete because:
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
When changing the logic here, I may forget to update both fields.
Is the additional Boolean field better than a null reference here?
null boolean
add a comment |
For example, suppose I have a class, Member
, which has a lastChangePasswordTime:
class Member{
.
.
.
constructor(){
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?, I shouldn't use null to represent a meaningfully absent value. So I try to add a Boolean flag:
class Member{
.
.
.
constructor(){
isPasswordChanged:false,
lastChangePasswordTime=null,
}
}
But I think it is quite obsolete because:
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
When changing the logic here, I may forget to update both fields.
Is the additional Boolean field better than a null reference here?
null boolean
35
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 usestd::optional
orOption
. In other languages, you may have to built an appropriate mechanism yourself, or you may actually resort tonull
or something similar because it's more idiomatic.
– Christian Hackl
yesterday
9
Is there a reason you wouldn't want the lastChangePasswordTime set to password creation time (creation is a mod, after all)?
– Kristian H
22 hours ago
@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
21 hours ago
@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 toNULL
/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
8 hours ago
I would use an enum with 3 cases for this :)
– J. Doe
1 hour ago
add a comment |
For example, suppose I have a class, Member
, which has a lastChangePasswordTime:
class Member{
.
.
.
constructor(){
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?, I shouldn't use null to represent a meaningfully absent value. So I try to add a Boolean flag:
class Member{
.
.
.
constructor(){
isPasswordChanged:false,
lastChangePasswordTime=null,
}
}
But I think it is quite obsolete because:
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
When changing the logic here, I may forget to update both fields.
Is the additional Boolean field better than a null reference here?
null boolean
For example, suppose I have a class, Member
, which has a lastChangePasswordTime:
class Member{
.
.
.
constructor(){
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?, I shouldn't use null to represent a meaningfully absent value. So I try to add a Boolean flag:
class Member{
.
.
.
constructor(){
isPasswordChanged:false,
lastChangePasswordTime=null,
}
}
But I think it is quite obsolete because:
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
When changing the logic here, I may forget to update both fields.
Is the additional Boolean field better than a null reference here?
null boolean
null boolean
edited 2 hours ago
Peter Mortensen
1,11521114
1,11521114
asked yesterday
mmmaaammmaaa
2,56041623
2,56041623
35
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 usestd::optional
orOption
. In other languages, you may have to built an appropriate mechanism yourself, or you may actually resort tonull
or something similar because it's more idiomatic.
– Christian Hackl
yesterday
9
Is there a reason you wouldn't want the lastChangePasswordTime set to password creation time (creation is a mod, after all)?
– Kristian H
22 hours ago
@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
21 hours ago
@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 toNULL
/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
8 hours ago
I would use an enum with 3 cases for this :)
– J. Doe
1 hour ago
add a comment |
35
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 usestd::optional
orOption
. In other languages, you may have to built an appropriate mechanism yourself, or you may actually resort tonull
or something similar because it's more idiomatic.
– Christian Hackl
yesterday
9
Is there a reason you wouldn't want the lastChangePasswordTime set to password creation time (creation is a mod, after all)?
– Kristian H
22 hours ago
@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
21 hours ago
@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 toNULL
/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
8 hours ago
I would use an enum with 3 cases for this :)
– J. Doe
1 hour ago
35
35
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
yesterday
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
yesterday
9
9
Is there a reason you wouldn't want the lastChangePasswordTime set to password creation time (creation is a mod, after all)?
– Kristian H
22 hours ago
Is there a reason you wouldn't want the lastChangePasswordTime set to password creation time (creation is a mod, after all)?
– Kristian H
22 hours ago
@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
21 hours ago
@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
21 hours ago
@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
8 hours ago
@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
8 hours ago
I would use an enum with 3 cases for this :)
– J. Doe
1 hour ago
I would use an enum with 3 cases for this :)
– J. Doe
1 hour ago
add a comment |
9 Answers
9
active
oldest
votes
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.
21
+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
yesterday
14
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
yesterday
2
You could forget to callisPasswordChanged
just like you can forget to check if it's null. I see nothing gained here.
– Gherman
yesterday
4
@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
22 hours ago
@Gherman IMO it provides a benefit in the readability of the code by providing more meaning/context — of course if you are writing new code against the class it doesn’t force you to use it. Giving the null-condition a meaningful name does more good than harm.
– TZHX
22 hours ago
|
show 7 more comments
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.
New contributor
11
Historically,null
exists because Tony Hoare made the billion-dollar mistake in 1965. People who claim thatnull
is "evil" are over-simplifying the topic, of course, but it's a good thing that modern languages or programming styles are moving away fromnull
, replacing it with dedicated option types.
– Christian Hackl
yesterday
3
@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
yesterday
3
@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
yesterday
5
@Tom wat? In languages like C# and Java, theDateTime
field is a pointer. The whole concept ofnull
only makes sense for pointers!
– Todd Sewell
yesterday
10
@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
yesterday
|
show 8 more comments
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.
6
There'sOptional
in java too; the meaning of a nullOptional
being up to you...
– Matthieu M.
yesterday
1
Came here to connect with Optional as well. I'd encode this as a type in a language which had them.
– Zipp
23 hours ago
2
@FrankHopkins It's a shame that nothing in Java prevents you from writingOptional<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 assignnull
. 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
21 hours ago
2
@FrankHopkins CheckingisPresent
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 overref == 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
21 hours ago
2
@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 supportsnull
because the language is 100% compatible to Java, but nobody uses it, andOption[T]
is all over the place, with excellent functional-programming support likemap
,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
12 hours ago
|
show 8 more comments
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.
5
Actually,horrible error: wanted value but got null!
is much better than the more typicalSegmentation fault. Core dumped.
...
– Toby Speight
yesterday
2
@TobySpeight True, but I would prefer something that lays inside user's terms likeError: the product you want to buy is out of stock
.
– Gherman
23 hours ago
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
21 hours ago
1
@Gherman: Passingnull
wherenull
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
8 hours ago
@ChristianHackl I gave example code with handlingnull
case. Handling null in such a case often is comprised of throwing a business logic-level exception. This is why I compared these errors. I am talking about avoiding programming errors, not just making errors better.
– Gherman
7 hours ago
|
show 3 more comments
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
.
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
7 hours ago
add a comment |
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.
add a comment |
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.
add a comment |
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.
New contributor
add a comment |
If you just want things to get done, then the use of null is OK.
If you also want to follow good practices (and eventually quality standards, e.g. for safety reasons), then null is not a good choice, because it can be ambiguous. The programming language already defined it for some purposes, and the purpose "calendar date not specified" is not one of them. Some numeric values (zero, -1, 0xdeadbeef...) are not very good either for similar reasons.
It would be a better practice to set the initial value of a variable to a special known unambiguous value - usually something very big or very small, which cannot happen in reality.
In your particular example, you may be able to use "Jan 1, 1500" (or anything that will not break the software in the future).
To be even more meaningful and elegant, you can combine specific value for the data (the "Jan 1, 1500" in my example) with a boolean regarding the initialization of the data ("isPasswordChanged:false" in your example), as you specified in the question.
if (isPasswordChanged == false)
is a lot more meaningful than
if (lastChangePasswordTime == "Jan. 1, 1500")
The choice of the value may also be "dictated" by the logic of the application. For example, you want the initial value of the date to mean that the password is already expired. In that case, you must surely not use a date from the future - your software will have unexpected results.
New contributor
7
Using "special valid values" to represent an undefined or unknown state is not a good practice, quality standard or safety measure in any project I've ever worked for. Quite the opposite, actually. Can you cite a source which says that this is good practice?
– Christian Hackl
yesterday
3
"It would be a better practice to set the initial value of a variable to a special known unambiguous value - usually something very big or very small, which cannot happen in reality." -- Or won't happen in reality until it does. That has all the pitfalls of using a magic number. Using a low value to guarantee an initial expired condition when there's a built-in value that means "no value" doesn't make a lot of sense, either.
– Blrfl
yesterday
While I do not have a reference at hand right now, I wrote automotive software for a long time. The example in the question is wrong in the first place because there is no match between the type of the variable and the type of the value - some implicit conversion occurs. And implicit conversions are one hack of debugging nightmare. I am aware that many details and practices are not considered when writing "high level software", but it does not mean it is good.
– virolino
yesterday
2
Of course a date pointer isn't made to hold a date. That much is clear. A date pointer is made to point at a date or at nothing, so it's perfectly reasonable to make it represent an unknown date by pointing at nothing. Not really perfect because of type safety reasons (see all my other comments here), but more reasonable than magic numbers. By the way, there is no conversion from aT
pointer or fromnullptr
to aT
.
– Christian Hackl
yesterday
3
Null specifically means absence of a value, which is precisely the correct thing to use in this case.
– 17 of 26
yesterday
|
show 5 more comments
protected by gnat 9 hours ago
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?
9 Answers
9
active
oldest
votes
9 Answers
9
active
oldest
votes
active
oldest
votes
active
oldest
votes
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.
21
+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
yesterday
14
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
yesterday
2
You could forget to callisPasswordChanged
just like you can forget to check if it's null. I see nothing gained here.
– Gherman
yesterday
4
@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
22 hours ago
@Gherman IMO it provides a benefit in the readability of the code by providing more meaning/context — of course if you are writing new code against the class it doesn’t force you to use it. Giving the null-condition a meaningful name does more good than harm.
– TZHX
22 hours ago
|
show 7 more comments
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.
21
+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
yesterday
14
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
yesterday
2
You could forget to callisPasswordChanged
just like you can forget to check if it's null. I see nothing gained here.
– Gherman
yesterday
4
@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
22 hours ago
@Gherman IMO it provides a benefit in the readability of the code by providing more meaning/context — of course if you are writing new code against the class it doesn’t force you to use it. Giving the null-condition a meaningful name does more good than harm.
– TZHX
22 hours ago
|
show 7 more comments
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.
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.
answered yesterday
TZHXTZHX
4,59721932
4,59721932
21
+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
yesterday
14
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
yesterday
2
You could forget to callisPasswordChanged
just like you can forget to check if it's null. I see nothing gained here.
– Gherman
yesterday
4
@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
22 hours ago
@Gherman IMO it provides a benefit in the readability of the code by providing more meaning/context — of course if you are writing new code against the class it doesn’t force you to use it. Giving the null-condition a meaningful name does more good than harm.
– TZHX
22 hours ago
|
show 7 more comments
21
+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
yesterday
14
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
yesterday
2
You could forget to callisPasswordChanged
just like you can forget to check if it's null. I see nothing gained here.
– Gherman
yesterday
4
@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
22 hours ago
@Gherman IMO it provides a benefit in the readability of the code by providing more meaning/context — of course if you are writing new code against the class it doesn’t force you to use it. Giving the null-condition a meaningful name does more good than harm.
– TZHX
22 hours ago
21
21
+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
yesterday
+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
yesterday
14
14
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
yesterday
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
yesterday
2
2
You could forget to call
isPasswordChanged
just like you can forget to check if it's null. I see nothing gained here.– Gherman
yesterday
You could forget to call
isPasswordChanged
just like you can forget to check if it's null. I see nothing gained here.– Gherman
yesterday
4
4
@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
22 hours ago
@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
22 hours ago
@Gherman IMO it provides a benefit in the readability of the code by providing more meaning/context — of course if you are writing new code against the class it doesn’t force you to use it. Giving the null-condition a meaningful name does more good than harm.
– TZHX
22 hours ago
@Gherman IMO it provides a benefit in the readability of the code by providing more meaning/context — of course if you are writing new code against the class it doesn’t force you to use it. Giving the null-condition a meaningful name does more good than harm.
– TZHX
22 hours ago
|
show 7 more comments
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.
New contributor
11
Historically,null
exists because Tony Hoare made the billion-dollar mistake in 1965. People who claim thatnull
is "evil" are over-simplifying the topic, of course, but it's a good thing that modern languages or programming styles are moving away fromnull
, replacing it with dedicated option types.
– Christian Hackl
yesterday
3
@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
yesterday
3
@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
yesterday
5
@Tom wat? In languages like C# and Java, theDateTime
field is a pointer. The whole concept ofnull
only makes sense for pointers!
– Todd Sewell
yesterday
10
@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
yesterday
|
show 8 more comments
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.
New contributor
11
Historically,null
exists because Tony Hoare made the billion-dollar mistake in 1965. People who claim thatnull
is "evil" are over-simplifying the topic, of course, but it's a good thing that modern languages or programming styles are moving away fromnull
, replacing it with dedicated option types.
– Christian Hackl
yesterday
3
@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
yesterday
3
@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
yesterday
5
@Tom wat? In languages like C# and Java, theDateTime
field is a pointer. The whole concept ofnull
only makes sense for pointers!
– Todd Sewell
yesterday
10
@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
yesterday
|
show 8 more comments
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.
New contributor
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.
New contributor
New contributor
answered yesterday
TomTom
45934
45934
New contributor
New contributor
11
Historically,null
exists because Tony Hoare made the billion-dollar mistake in 1965. People who claim thatnull
is "evil" are over-simplifying the topic, of course, but it's a good thing that modern languages or programming styles are moving away fromnull
, replacing it with dedicated option types.
– Christian Hackl
yesterday
3
@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
yesterday
3
@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
yesterday
5
@Tom wat? In languages like C# and Java, theDateTime
field is a pointer. The whole concept ofnull
only makes sense for pointers!
– Todd Sewell
yesterday
10
@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
yesterday
|
show 8 more comments
11
Historically,null
exists because Tony Hoare made the billion-dollar mistake in 1965. People who claim thatnull
is "evil" are over-simplifying the topic, of course, but it's a good thing that modern languages or programming styles are moving away fromnull
, replacing it with dedicated option types.
– Christian Hackl
yesterday
3
@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
yesterday
3
@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
yesterday
5
@Tom wat? In languages like C# and Java, theDateTime
field is a pointer. The whole concept ofnull
only makes sense for pointers!
– Todd Sewell
yesterday
10
@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
yesterday
11
11
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
yesterday
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
yesterday
3
3
@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
yesterday
@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
yesterday
3
3
@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
yesterday
@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
yesterday
5
5
@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
yesterday
@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
yesterday
10
10
@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
yesterday
@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
yesterday
|
show 8 more comments
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.
6
There'sOptional
in java too; the meaning of a nullOptional
being up to you...
– Matthieu M.
yesterday
1
Came here to connect with Optional as well. I'd encode this as a type in a language which had them.
– Zipp
23 hours ago
2
@FrankHopkins It's a shame that nothing in Java prevents you from writingOptional<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 assignnull
. 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
21 hours ago
2
@FrankHopkins CheckingisPresent
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 overref == 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
21 hours ago
2
@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 supportsnull
because the language is 100% compatible to Java, but nobody uses it, andOption[T]
is all over the place, with excellent functional-programming support likemap
,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
12 hours ago
|
show 8 more comments
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.
6
There'sOptional
in java too; the meaning of a nullOptional
being up to you...
– Matthieu M.
yesterday
1
Came here to connect with Optional as well. I'd encode this as a type in a language which had them.
– Zipp
23 hours ago
2
@FrankHopkins It's a shame that nothing in Java prevents you from writingOptional<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 assignnull
. 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
21 hours ago
2
@FrankHopkins CheckingisPresent
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 overref == 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
21 hours ago
2
@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 supportsnull
because the language is 100% compatible to Java, but nobody uses it, andOption[T]
is all over the place, with excellent functional-programming support likemap
,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
12 hours ago
|
show 8 more comments
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.
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.
answered yesterday
dasmydasmy
3804
3804
6
There'sOptional
in java too; the meaning of a nullOptional
being up to you...
– Matthieu M.
yesterday
1
Came here to connect with Optional as well. I'd encode this as a type in a language which had them.
– Zipp
23 hours ago
2
@FrankHopkins It's a shame that nothing in Java prevents you from writingOptional<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 assignnull
. 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
21 hours ago
2
@FrankHopkins CheckingisPresent
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 overref == 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
21 hours ago
2
@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 supportsnull
because the language is 100% compatible to Java, but nobody uses it, andOption[T]
is all over the place, with excellent functional-programming support likemap
,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
12 hours ago
|
show 8 more comments
6
There'sOptional
in java too; the meaning of a nullOptional
being up to you...
– Matthieu M.
yesterday
1
Came here to connect with Optional as well. I'd encode this as a type in a language which had them.
– Zipp
23 hours ago
2
@FrankHopkins It's a shame that nothing in Java prevents you from writingOptional<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 assignnull
. 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
21 hours ago
2
@FrankHopkins CheckingisPresent
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 overref == 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
21 hours ago
2
@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 supportsnull
because the language is 100% compatible to Java, but nobody uses it, andOption[T]
is all over the place, with excellent functional-programming support likemap
,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
12 hours ago
6
6
There's
Optional
in java too; the meaning of a null Optional
being up to you...– Matthieu M.
yesterday
There's
Optional
in java too; the meaning of a null Optional
being up to you...– Matthieu M.
yesterday
1
1
Came here to connect with Optional as well. I'd encode this as a type in a language which had them.
– Zipp
23 hours ago
Came here to connect with Optional as well. I'd encode this as a type in a language which had them.
– Zipp
23 hours ago
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
21 hours ago
@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
21 hours ago
2
2
@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
21 hours ago
@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
21 hours ago
2
2
@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
12 hours ago
@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
12 hours ago
|
show 8 more comments
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.
5
Actually,horrible error: wanted value but got null!
is much better than the more typicalSegmentation fault. Core dumped.
...
– Toby Speight
yesterday
2
@TobySpeight True, but I would prefer something that lays inside user's terms likeError: the product you want to buy is out of stock
.
– Gherman
23 hours ago
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
21 hours ago
1
@Gherman: Passingnull
wherenull
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
8 hours ago
@ChristianHackl I gave example code with handlingnull
case. Handling null in such a case often is comprised of throwing a business logic-level exception. This is why I compared these errors. I am talking about avoiding programming errors, not just making errors better.
– Gherman
7 hours ago
|
show 3 more comments
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.
5
Actually,horrible error: wanted value but got null!
is much better than the more typicalSegmentation fault. Core dumped.
...
– Toby Speight
yesterday
2
@TobySpeight True, but I would prefer something that lays inside user's terms likeError: the product you want to buy is out of stock
.
– Gherman
23 hours ago
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
21 hours ago
1
@Gherman: Passingnull
wherenull
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
8 hours ago
@ChristianHackl I gave example code with handlingnull
case. Handling null in such a case often is comprised of throwing a business logic-level exception. This is why I compared these errors. I am talking about avoiding programming errors, not just making errors better.
– Gherman
7 hours ago
|
show 3 more comments
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.
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.
edited 2 hours ago
answered yesterday
GhermanGherman
443410
443410
5
Actually,horrible error: wanted value but got null!
is much better than the more typicalSegmentation fault. Core dumped.
...
– Toby Speight
yesterday
2
@TobySpeight True, but I would prefer something that lays inside user's terms likeError: the product you want to buy is out of stock
.
– Gherman
23 hours ago
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
21 hours ago
1
@Gherman: Passingnull
wherenull
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
8 hours ago
@ChristianHackl I gave example code with handlingnull
case. Handling null in such a case often is comprised of throwing a business logic-level exception. This is why I compared these errors. I am talking about avoiding programming errors, not just making errors better.
– Gherman
7 hours ago
|
show 3 more comments
5
Actually,horrible error: wanted value but got null!
is much better than the more typicalSegmentation fault. Core dumped.
...
– Toby Speight
yesterday
2
@TobySpeight True, but I would prefer something that lays inside user's terms likeError: the product you want to buy is out of stock
.
– Gherman
23 hours ago
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
21 hours ago
1
@Gherman: Passingnull
wherenull
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
8 hours ago
@ChristianHackl I gave example code with handlingnull
case. Handling null in such a case often is comprised of throwing a business logic-level exception. This is why I compared these errors. I am talking about avoiding programming errors, not just making errors better.
– Gherman
7 hours ago
5
5
Actually,
horrible error: wanted value but got null!
is much better than the more typical Segmentation fault. Core dumped.
...– Toby Speight
yesterday
Actually,
horrible error: wanted value but got null!
is much better than the more typical Segmentation fault. Core dumped.
...– Toby Speight
yesterday
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
23 hours ago
@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
23 hours ago
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
21 hours ago
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
21 hours ago
1
1
@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
8 hours ago
@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
8 hours ago
@ChristianHackl I gave example code with handling
null
case. Handling null in such a case often is comprised of throwing a business logic-level exception. This is why I compared these errors. I am talking about avoiding programming errors, not just making errors better.– Gherman
7 hours ago
@ChristianHackl I gave example code with handling
null
case. Handling null in such a case often is comprised of throwing a business logic-level exception. This is why I compared these errors. I am talking about avoiding programming errors, not just making errors better.– Gherman
7 hours ago
|
show 3 more comments
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
.
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
7 hours ago
add a comment |
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
.
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
7 hours ago
add a comment |
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
.
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
.
answered yesterday
JoelJoel
1716
1716
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
7 hours ago
add a comment |
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
7 hours ago
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
7 hours ago
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
7 hours ago
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered yesterday
Rik DRik D
30017
30017
add a comment |
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered 6 hours ago
jmorenojmoreno
8,87712244
8,87712244
add a comment |
add a comment |
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.
New contributor
add a comment |
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.
New contributor
add a comment |
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.
New contributor
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.
New contributor
New contributor
answered 1 hour ago
ANoneANone
291
291
New contributor
New contributor
add a comment |
add a comment |
If you just want things to get done, then the use of null is OK.
If you also want to follow good practices (and eventually quality standards, e.g. for safety reasons), then null is not a good choice, because it can be ambiguous. The programming language already defined it for some purposes, and the purpose "calendar date not specified" is not one of them. Some numeric values (zero, -1, 0xdeadbeef...) are not very good either for similar reasons.
It would be a better practice to set the initial value of a variable to a special known unambiguous value - usually something very big or very small, which cannot happen in reality.
In your particular example, you may be able to use "Jan 1, 1500" (or anything that will not break the software in the future).
To be even more meaningful and elegant, you can combine specific value for the data (the "Jan 1, 1500" in my example) with a boolean regarding the initialization of the data ("isPasswordChanged:false" in your example), as you specified in the question.
if (isPasswordChanged == false)
is a lot more meaningful than
if (lastChangePasswordTime == "Jan. 1, 1500")
The choice of the value may also be "dictated" by the logic of the application. For example, you want the initial value of the date to mean that the password is already expired. In that case, you must surely not use a date from the future - your software will have unexpected results.
New contributor
7
Using "special valid values" to represent an undefined or unknown state is not a good practice, quality standard or safety measure in any project I've ever worked for. Quite the opposite, actually. Can you cite a source which says that this is good practice?
– Christian Hackl
yesterday
3
"It would be a better practice to set the initial value of a variable to a special known unambiguous value - usually something very big or very small, which cannot happen in reality." -- Or won't happen in reality until it does. That has all the pitfalls of using a magic number. Using a low value to guarantee an initial expired condition when there's a built-in value that means "no value" doesn't make a lot of sense, either.
– Blrfl
yesterday
While I do not have a reference at hand right now, I wrote automotive software for a long time. The example in the question is wrong in the first place because there is no match between the type of the variable and the type of the value - some implicit conversion occurs. And implicit conversions are one hack of debugging nightmare. I am aware that many details and practices are not considered when writing "high level software", but it does not mean it is good.
– virolino
yesterday
2
Of course a date pointer isn't made to hold a date. That much is clear. A date pointer is made to point at a date or at nothing, so it's perfectly reasonable to make it represent an unknown date by pointing at nothing. Not really perfect because of type safety reasons (see all my other comments here), but more reasonable than magic numbers. By the way, there is no conversion from aT
pointer or fromnullptr
to aT
.
– Christian Hackl
yesterday
3
Null specifically means absence of a value, which is precisely the correct thing to use in this case.
– 17 of 26
yesterday
|
show 5 more comments
If you just want things to get done, then the use of null is OK.
If you also want to follow good practices (and eventually quality standards, e.g. for safety reasons), then null is not a good choice, because it can be ambiguous. The programming language already defined it for some purposes, and the purpose "calendar date not specified" is not one of them. Some numeric values (zero, -1, 0xdeadbeef...) are not very good either for similar reasons.
It would be a better practice to set the initial value of a variable to a special known unambiguous value - usually something very big or very small, which cannot happen in reality.
In your particular example, you may be able to use "Jan 1, 1500" (or anything that will not break the software in the future).
To be even more meaningful and elegant, you can combine specific value for the data (the "Jan 1, 1500" in my example) with a boolean regarding the initialization of the data ("isPasswordChanged:false" in your example), as you specified in the question.
if (isPasswordChanged == false)
is a lot more meaningful than
if (lastChangePasswordTime == "Jan. 1, 1500")
The choice of the value may also be "dictated" by the logic of the application. For example, you want the initial value of the date to mean that the password is already expired. In that case, you must surely not use a date from the future - your software will have unexpected results.
New contributor
7
Using "special valid values" to represent an undefined or unknown state is not a good practice, quality standard or safety measure in any project I've ever worked for. Quite the opposite, actually. Can you cite a source which says that this is good practice?
– Christian Hackl
yesterday
3
"It would be a better practice to set the initial value of a variable to a special known unambiguous value - usually something very big or very small, which cannot happen in reality." -- Or won't happen in reality until it does. That has all the pitfalls of using a magic number. Using a low value to guarantee an initial expired condition when there's a built-in value that means "no value" doesn't make a lot of sense, either.
– Blrfl
yesterday
While I do not have a reference at hand right now, I wrote automotive software for a long time. The example in the question is wrong in the first place because there is no match between the type of the variable and the type of the value - some implicit conversion occurs. And implicit conversions are one hack of debugging nightmare. I am aware that many details and practices are not considered when writing "high level software", but it does not mean it is good.
– virolino
yesterday
2
Of course a date pointer isn't made to hold a date. That much is clear. A date pointer is made to point at a date or at nothing, so it's perfectly reasonable to make it represent an unknown date by pointing at nothing. Not really perfect because of type safety reasons (see all my other comments here), but more reasonable than magic numbers. By the way, there is no conversion from aT
pointer or fromnullptr
to aT
.
– Christian Hackl
yesterday
3
Null specifically means absence of a value, which is precisely the correct thing to use in this case.
– 17 of 26
yesterday
|
show 5 more comments
If you just want things to get done, then the use of null is OK.
If you also want to follow good practices (and eventually quality standards, e.g. for safety reasons), then null is not a good choice, because it can be ambiguous. The programming language already defined it for some purposes, and the purpose "calendar date not specified" is not one of them. Some numeric values (zero, -1, 0xdeadbeef...) are not very good either for similar reasons.
It would be a better practice to set the initial value of a variable to a special known unambiguous value - usually something very big or very small, which cannot happen in reality.
In your particular example, you may be able to use "Jan 1, 1500" (or anything that will not break the software in the future).
To be even more meaningful and elegant, you can combine specific value for the data (the "Jan 1, 1500" in my example) with a boolean regarding the initialization of the data ("isPasswordChanged:false" in your example), as you specified in the question.
if (isPasswordChanged == false)
is a lot more meaningful than
if (lastChangePasswordTime == "Jan. 1, 1500")
The choice of the value may also be "dictated" by the logic of the application. For example, you want the initial value of the date to mean that the password is already expired. In that case, you must surely not use a date from the future - your software will have unexpected results.
New contributor
If you just want things to get done, then the use of null is OK.
If you also want to follow good practices (and eventually quality standards, e.g. for safety reasons), then null is not a good choice, because it can be ambiguous. The programming language already defined it for some purposes, and the purpose "calendar date not specified" is not one of them. Some numeric values (zero, -1, 0xdeadbeef...) are not very good either for similar reasons.
It would be a better practice to set the initial value of a variable to a special known unambiguous value - usually something very big or very small, which cannot happen in reality.
In your particular example, you may be able to use "Jan 1, 1500" (or anything that will not break the software in the future).
To be even more meaningful and elegant, you can combine specific value for the data (the "Jan 1, 1500" in my example) with a boolean regarding the initialization of the data ("isPasswordChanged:false" in your example), as you specified in the question.
if (isPasswordChanged == false)
is a lot more meaningful than
if (lastChangePasswordTime == "Jan. 1, 1500")
The choice of the value may also be "dictated" by the logic of the application. For example, you want the initial value of the date to mean that the password is already expired. In that case, you must surely not use a date from the future - your software will have unexpected results.
New contributor
New contributor
answered yesterday
virolinovirolino
952
952
New contributor
New contributor
7
Using "special valid values" to represent an undefined or unknown state is not a good practice, quality standard or safety measure in any project I've ever worked for. Quite the opposite, actually. Can you cite a source which says that this is good practice?
– Christian Hackl
yesterday
3
"It would be a better practice to set the initial value of a variable to a special known unambiguous value - usually something very big or very small, which cannot happen in reality." -- Or won't happen in reality until it does. That has all the pitfalls of using a magic number. Using a low value to guarantee an initial expired condition when there's a built-in value that means "no value" doesn't make a lot of sense, either.
– Blrfl
yesterday
While I do not have a reference at hand right now, I wrote automotive software for a long time. The example in the question is wrong in the first place because there is no match between the type of the variable and the type of the value - some implicit conversion occurs. And implicit conversions are one hack of debugging nightmare. I am aware that many details and practices are not considered when writing "high level software", but it does not mean it is good.
– virolino
yesterday
2
Of course a date pointer isn't made to hold a date. That much is clear. A date pointer is made to point at a date or at nothing, so it's perfectly reasonable to make it represent an unknown date by pointing at nothing. Not really perfect because of type safety reasons (see all my other comments here), but more reasonable than magic numbers. By the way, there is no conversion from aT
pointer or fromnullptr
to aT
.
– Christian Hackl
yesterday
3
Null specifically means absence of a value, which is precisely the correct thing to use in this case.
– 17 of 26
yesterday
|
show 5 more comments
7
Using "special valid values" to represent an undefined or unknown state is not a good practice, quality standard or safety measure in any project I've ever worked for. Quite the opposite, actually. Can you cite a source which says that this is good practice?
– Christian Hackl
yesterday
3
"It would be a better practice to set the initial value of a variable to a special known unambiguous value - usually something very big or very small, which cannot happen in reality." -- Or won't happen in reality until it does. That has all the pitfalls of using a magic number. Using a low value to guarantee an initial expired condition when there's a built-in value that means "no value" doesn't make a lot of sense, either.
– Blrfl
yesterday
While I do not have a reference at hand right now, I wrote automotive software for a long time. The example in the question is wrong in the first place because there is no match between the type of the variable and the type of the value - some implicit conversion occurs. And implicit conversions are one hack of debugging nightmare. I am aware that many details and practices are not considered when writing "high level software", but it does not mean it is good.
– virolino
yesterday
2
Of course a date pointer isn't made to hold a date. That much is clear. A date pointer is made to point at a date or at nothing, so it's perfectly reasonable to make it represent an unknown date by pointing at nothing. Not really perfect because of type safety reasons (see all my other comments here), but more reasonable than magic numbers. By the way, there is no conversion from aT
pointer or fromnullptr
to aT
.
– Christian Hackl
yesterday
3
Null specifically means absence of a value, which is precisely the correct thing to use in this case.
– 17 of 26
yesterday
7
7
Using "special valid values" to represent an undefined or unknown state is not a good practice, quality standard or safety measure in any project I've ever worked for. Quite the opposite, actually. Can you cite a source which says that this is good practice?
– Christian Hackl
yesterday
Using "special valid values" to represent an undefined or unknown state is not a good practice, quality standard or safety measure in any project I've ever worked for. Quite the opposite, actually. Can you cite a source which says that this is good practice?
– Christian Hackl
yesterday
3
3
"It would be a better practice to set the initial value of a variable to a special known unambiguous value - usually something very big or very small, which cannot happen in reality." -- Or won't happen in reality until it does. That has all the pitfalls of using a magic number. Using a low value to guarantee an initial expired condition when there's a built-in value that means "no value" doesn't make a lot of sense, either.
– Blrfl
yesterday
"It would be a better practice to set the initial value of a variable to a special known unambiguous value - usually something very big or very small, which cannot happen in reality." -- Or won't happen in reality until it does. That has all the pitfalls of using a magic number. Using a low value to guarantee an initial expired condition when there's a built-in value that means "no value" doesn't make a lot of sense, either.
– Blrfl
yesterday
While I do not have a reference at hand right now, I wrote automotive software for a long time. The example in the question is wrong in the first place because there is no match between the type of the variable and the type of the value - some implicit conversion occurs. And implicit conversions are one hack of debugging nightmare. I am aware that many details and practices are not considered when writing "high level software", but it does not mean it is good.
– virolino
yesterday
While I do not have a reference at hand right now, I wrote automotive software for a long time. The example in the question is wrong in the first place because there is no match between the type of the variable and the type of the value - some implicit conversion occurs. And implicit conversions are one hack of debugging nightmare. I am aware that many details and practices are not considered when writing "high level software", but it does not mean it is good.
– virolino
yesterday
2
2
Of course a date pointer isn't made to hold a date. That much is clear. A date pointer is made to point at a date or at nothing, so it's perfectly reasonable to make it represent an unknown date by pointing at nothing. Not really perfect because of type safety reasons (see all my other comments here), but more reasonable than magic numbers. By the way, there is no conversion from a
T
pointer or from nullptr
to a T
.– Christian Hackl
yesterday
Of course a date pointer isn't made to hold a date. That much is clear. A date pointer is made to point at a date or at nothing, so it's perfectly reasonable to make it represent an unknown date by pointing at nothing. Not really perfect because of type safety reasons (see all my other comments here), but more reasonable than magic numbers. By the way, there is no conversion from a
T
pointer or from nullptr
to a T
.– Christian Hackl
yesterday
3
3
Null specifically means absence of a value, which is precisely the correct thing to use in this case.
– 17 of 26
yesterday
Null specifically means absence of a value, which is precisely the correct thing to use in this case.
– 17 of 26
yesterday
|
show 5 more comments
protected by gnat 9 hours ago
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?
35
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
orOption
. In other languages, you may have to built an appropriate mechanism yourself, or you may actually resort tonull
or something similar because it's more idiomatic.– Christian Hackl
yesterday
9
Is there a reason you wouldn't want the lastChangePasswordTime set to password creation time (creation is a mod, after all)?
– Kristian H
22 hours ago
@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
21 hours ago
@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 toNULL
/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
8 hours ago
I would use an enum with 3 cases for this :)
– J. Doe
1 hour ago