kengorab/abra-lang

Boolean operations on Option types

Closed this issue · 0 comments

Bool? in if-/while-conditions

A Bool? should be able to be used as an if-/while-condition, without requiring a second level
of indirection. Right now, the following code is required:

val bools = [false, true]
if bools[0] |boolValue| {
  if boolValue {
    ...
  }
}

This is annoying since it requires an additional if-block for no good reason; a value of type Bool?
which does not hold a value (ie. it holds None) should be treated equivalently to false. Therefore
the code now becomes this:

val bools = [false, true]
if bools[0] |boolValue| {
  // This block will only be hit if bools[0] is _not_ None _and_ is `true`; `boolValue` will only ever be `true`
}

This does introduce a breaking change however; if we wanted to simply test whether the 0th value existed in a boolean
array (without caring about whether it's true or false), we no longer can:

val bools = [false, true]
if bools[0] {
  // This block will never be entered, since bools[0] _exists_, but is `false`
}

This seems like a niche scenario, and should probably be addressed in other ways (this is also a problem in other
languages with falsiness like javascript, python, ruby, clojure, and others).
This also means that the following code won't work as expected either:

val bools = [true, true, false, true]
var i = 0
while bools[i] {
  i += 1
}
println(i) // i == 2, since it stops at the `false` value

Bool? in boolean operators

Negate (!)

If the boolean negate (!) operator is applied to a value of any Option type, it should evaluate
to false if it's equal to None, and true otherwise.

val arr: Int[] = [1]
!arr[0] // => false
!arr[1] // => true

And/Or (&&/||)

If the boolean and/or (&&/||) operators are applied to a value of any Option type, they should evaluate
to false if it's equal to None, and true otherwise.

val arr: Int[] = [1]
arr[0] && true // => true
arr[0] && false // => false
arr[1] && true // => false
arr[1] && false // => false

arr[0] || true // => true
arr[0] || false // => true
arr[1] || true // => true
arr[1] || false // => false