Booleans in Dart

(This is part 11 in an ongoing series about Dart. Read part 10, Numbers in Dart.)

Intro

This post will cover what is true, and false, in Dart. If you are coming from JavaScript, hopefully this short explanation about booleans in Dart will come as welcome relief.

Dart has a formal boolean type, named bool. There are only two objects of type bool: true and false.

Examples:

bool registered = false;
var verified    = true;

True

The only value that is true is the boolean value true. Unlike JavaScript, other values such as 1 or non-null object are not treated as true.

False

In a boolean context, everything that is not true is converted to false. JavaScript has six other falsey values such as empty string, zero, null object, undefined, or NaN. In Dart, if an object is not the boolean value true, it is evaluated as false.

Boolean conversion

What happens when you write the following code?

var name = 'Bob';
if (name) {
  print("you have a name!");
}

In JavaScript, the above will print "you have a name!" because name is a non-null object. However, in Dart, the above will not print because name is converted to false due to boolean conversion.

The conversion rules to boolean are quite simple. The spec outlines the logic as:


(bool v){
    assert(v != null);
    return v === true;
}(o)

In other words, that which is not true is false. If the value is not equal to and of the same type as true, then the value is converted to false.

This means that the following code will work in JavaScript but will not work in Dart:

// this won't print in Dart
if (1) {
  print("1 is converted to false in Dart, as is everything that is not the value true");
}

Compensating

Coming from JavaScript, you may be wondering how to check for conditions such as empty string or zero. The long form checks will still work.

Check for empty string:

var fullName = '';
if (fullName.isEmpty()) {
  print("Please enter a full name");
}

Checking for zero:

var hitPoints = 0;
if (hitPoints == 0) {
  print("Uh oh! Looks like you died.");
}

Checking for null:

var unicorn = null;
if (unicorn == null) {
  print("You didn't wish hard enough. Wish harder.");
}

Checking for NaN:

var iMeantToDoThis = 0 / 0;
if (iMeantToDoThis.isNaN()) {
  print("it's all on purpose");
}

JavaScript puzzler

Dart also differs from JavaScript with respect to its treatment of boolean expressions.

In JavaScript, boolean expressions will resolve to the value of the object that stops the evaluation. For instance:

var yourName = 'Bob';
var myName = '';
var someName = yourName && myName;
console.log(someName);
// prints '' (empty string!)

Both yourName and myName will be evaluated, and because yourName is truthy the next value must be evaluated. myName is an empty string, which is falsey, but that doesn't matter to the value of someName. The last value that is evaluated is returned, so someName is set to an empty string.

Dart answer

Dart simplifies the behavior, because the result of a boolean expression is a boolean. Therefore, the following Dart code reads more logically.


main() {
  var firstName = 'Bob';
  var middleName = '';
  var name = firstName && middleName;
  print(name); // false, because boolean conversion turns
               // firstName into false
  print(name is bool); // true!
}

Assigning default values

Dart's simplified boolean handling also means a few tricks from JavaScript or Ruby don't work.

For example, assigning a default value in Ruby is as simple as:

# ruby code which assigns 25 to hit_points if it was null
hit_points ||= 25

Assigning a default value in JavaScript looks like:

// works in JavaScript
var hitPoints = hitPoints || 25;

However, because Dart boolean expressions return a boolean, and not the last value, we need to write:

var hitPoints = (hitPoints != null) ? hitPoints : 25;

This is a bit easier in Dart with functions, as default values are supported with function arguments:

grabADrink([size='pint']) {
  print(size);
}

grabADrink(); // prints 'pint'

Summary

Dart has a true boolean type named bool, with only two values: true and false (and, I suppose, null). Due to Dart's boolean conversion rules, all values except true are converted to false. Dart's boolean expressions return the actual boolean result, not the last encountered value.

Next Steps

Read more of my Dart posts, try Dart in your browser, browse the API docs, or file an issue request. You may also continue to Part 12: Classes in Dart, Part One.

Dart is getting ready, please send us your feedback!

Popular posts from this blog

Lists and arrays in Dart

Converting Array to List in Scala

Null-aware operators in Dart