Truth and Nullability
tactics
9 Feb 2010
I find it natural to accept null as false in a condition. However, it does create a weird issue when you're dealing with the Bool? type.
ivan
9 Feb 2010
Probably the question is how to interpret !a, is it a == false or a != true
However in the particular case above I'd write something like this
switch([a == null, b == null])
{
case [true, true]: {//don't do anything}
case [true, false]: {//warn about a}
case [false, true]: {//warn about b}
case [false, false]: {//do work}
}
msl
9 Feb 2010
That's very cool. I need to get my head out of java-switch-thinking...
brian
9 Feb 2010
I definitely think we want to keep truth conditions limited to Bool. If there was one thing we learned moving from C to Java, it was that not there was huge advantages in static typing by not allowing any old expression to be used in conditions such as:
if (a = b)
My personal experience is that now I tend to use things like ?: more often rather than explicit null checks.
msl
10 Feb 2010
My personal experience is that now I tend to use things like
?:more often rather than explicit null checks.
I did consider the elvis operator and null safe calls but I couldn't come up with a "nice" way to express the same conditions... About the best I could come up with is something like (written on my phone, so not sure if it actually works):
if (a ?: b ?: "" == "") // do nothing else if (a ?: b == b) // warn about a being null else if (b ?: a == a) // warn about a being null else // do stuff
The behavior of this is dependent on "" being an invalid value for a/b... if either of those values could be "" then the first case incorrectly (for the desired logic - correctly for what's written) evaluates to true?
Any suggestions for a better approach?
qualidafial
12 Feb 2010
I think it would be useful to have a short expression for evaluating whether an object is non-null. Something like foo? evaluating to foo != null would be nice, but that syntax might be hard or impossible to distinguish from ternary expressions.
msl
12 Feb 2010
I like the consistency with type definitions:
Str? foo
if (foo?) {
// don't use foo
}
but that's an opinion given with no consideration whatsoever to how it might effect the language :)
Akcelisto
12 Feb 2010
May be:
foo!? for foo != null
foo=? for foo == null
helium
12 Feb 2010
foo? looks OK. You can negate boolean values using the ! operator, so !foo? would be true if foo is null. No need to invent new operators that look like an interrobang ‽
KevinKelley
12 Feb 2010
Actually sounds pretty cool... foo? should mean "is there a foo", though, not "is foo null", imo.
Seems like this is an analog to the if statement with no else branch. We have ?: as an expression-analog to the if...else statement, but we don't have an expression for just the if.
helium
12 Feb 2010
@KevinKelley: ? analog to ?: to test for "if not null"?
x := y ? z
x is z if y is not null otherwise x is null? When would that be useful?
qualidafial
12 Feb 2010
That's not what I'm suggesting. What I meant is to make foo? shorthand for foo != null, since null checks are such a common pattern in code.
andy
12 Feb 2010
I like the ideas in this thread. However I think if you added foo? - it would have to resolve to foo == null - to be consistent with the type system:
Str? foo // def to null
if (foo?) echo("foo is null)
if (!foo?) echo("foo is not null")
I admit the common case doesn't look as nice - but I think consistency and expectation trump that.
KevinKelley
12 Feb 2010
When would that be useful?
I guess, when the z part needs to use the y but can't handle a null:
x := y? z(y)
instead of
x := (y!=null)? z(y) : null
The null-safe operators and elvis cut out a lot of the need for if (x!=null), but they don't cover every situation.
KevinKelley
12 Feb 2010
Just for grins, I grepped 605 occurrences of "!= *null" in my working fan dir, and 702 in the 1.0.51 Fantom src.
tcolar
12 Feb 2010
Since i'm working on a fan parser)for the IDE) right now and there is already a lot of difficult thing to deal with when it comes to ? i would prefer this not to happen.
- How will the parser know whether str? is a nullable type or an expression of whether the str variable is null
- I think it could also get confused big time with ternary expressions if the expression after y? contains a column (map)
Syntaxic sugar is nice, until you write a parser :)
brian
13 Feb 2010
I think we are about wrapped up for language changes for now (other than maybe the using syntax for scripts), because I want to give guys like tcolar a chance to get their IDEs caught up and let things settle down.
That doesn't mean this isn't a good discussion for something we add to 1.1. I am total agreement that there is a huge amount of code that uses these constructs:
if (x == null) ... if (x != null) ...
I would definitely like to have a syntax for this common case. However, note this tends to be a statement/flow control problem, not an expression problem (which the ?: tackles). So I'd more inclined to use some keyword or combo with if that was easy to parse:
ifxxx (x) .... if? (x) ... if ?(x) ... if (x)? ...
DanielFath
13 Feb 2010
I have a question. Is if (x)? same as
if ((foo)?) //1st case if (foo)? //2nd case
Of the bat the first problem I see is how do you combine these examples with some other boolean expression (i.e. how do you write if (x==null && y<z))
msl
9 Feb 2010
Hi All,
I'm writing some code that deals with user input where there are a range of possible combinations of values and find myself doing things like this quite a bit:
Str? a Str? b // Parse input if (a == null && b == null) { // don't do anything } if (a != null && b == null) { log.warn("b must be defined with a") } if (a == null && b != null) { log.warn("a must be defined with b") } if (a != null && b != null) { // do stuff }I'm wondering whether this is a situation that other people find they're commonly bumping into with nullable types and whether there's a nice middle ground between "the only thing that's true/false is a Bool" (fantom) and "almost anything can be true/false if you know the rules" (python)?
In short, I'm wondering whether a null object should be considered false? With the examples above:
Str? a Str? b // Parse input if (!a && !b) { // don't do anything } if (a && !b) { log.warn("b must be defined with a") } if (!a && b) { log.warn("a must be defined with b") } if (a && b) { // do stuff }I guess the edge case here is handling of
Bool?but I can't think of a scenario (in my current mindset) where this handling would go against the desired logic (and if you do need a true/false/null three-way check you can still do so):Bool? b if (b == null) { // b is null } else if (b) { // b is not null and true } else if (!b) { // b is not null and false }Martin