論理値の概要#

論理値は、真TRUEまたは偽FALSEの2つの値を持つデータ構造です。

それぞれ、組み込み定数TRUEおよびFALSEによって参照されます。

$ xa 'TRUE'
# TRUE

$ xa 'FALSE'
# FALSE

論理値化#

論理値化演算子?valueは、値の論理値化を行います。

$ xa '?1'
# TRUE

$ xa '?0'
# FALSE

値のタイプごとの論理値化#

値のタイプによってどのように論理値化が行われるかが異なります。

全般的に、ある値のタイプにおいて、最も単純な値がFALSEで、それ以外はTRUEです。

値のタイプ TRUEになるもの FALSEになるもの
NULL なし NULL
数値 0に等しくない値 0に等しい値
論理値 TRUE FALSE
文字列 空文字列以外 空文字列
ストリーム いずれかの要素がTRUE すべての要素がFALSE
空ストリーム
配列 空でない配列 空配列
オブジェクト 1個以上のエントリーがあるもの
※オーバーライド可能
エントリーが1個もないもの
※オーバーライド可能

いくつかの、直観的にはFALSEのように感じられる値がTRUEになることがあります。

  • 文字列"FALSE"
  • 文字列"0"
  • 配列[FALSE]
  • オブジェクト{a: NULL}

論理値化のオーバーライド#

論理値化は、値の?_メソッドを参照します。

オブジェクトの?_メソッドをオーバーライドすることで、論理値化の処理を変更することができます。

$ xa '
  Class := {
    `?_`: this -> this.value > 100
  }

  ?Class{value: 50},
  ?Class{value: 200},
'
# FALSE
# TRUE

否定論理値化#

否定論理値化演算子!valueは、値の論理値化を行い、その否定を返します。

$ xa '!TRUE'
# FALSE

$ xa '!FALSE'
# TRUE

$ xa '!1'
# FALSE

論理演算子#

論理積演算子#

論理積演算子boolean && booleanは、左辺が論理値化によってFALSEと評価される場合は左辺を返し、そうでない場合は右辺を返します。


両辺が論理値である場合、その結果は論理積演算と等価となります。

左辺値 右辺値 返却値
FALSE FALSE FALSE
FALSE TRUE FALSE
TRUE FALSE FALSE
TRUE TRUE TRUE

論理和演算子#

論理和演算子boolean || booleanは、左辺が論理値化によってTRUEと評価される場合は左辺を返し、そうでない場合は右辺を返します。


両辺が論理値である場合、その結果は論理和演算と等価となります。

左辺値 右辺値 返却値
FALSE FALSE FALSE
FALSE TRUE TRUE
TRUE FALSE TRUE
TRUE TRUE TRUE

論理演算子による条件分岐#

論理演算子は、条件分岐の手段としても利用できます。

右辺の値が使われない場合、その値は評価自体が行われません。

演算子 右辺が評価される条件
condition && then conditionの論理値化がTRUEである場合
condition \|\| else conditionの論理値化がFALSEである場合
$ xa -q '
  check := value -> (
    value %% 2 && OUT("$value is divisible by 2")
    value %% 3 || OUT("$value is not divisible by 3")
  )

  check(4)
  check(9)
'
# 4 is divisible by 2
# 4 is not divisible by 3

条件演算子#

三項演算子#

三項演算子condition ? then : elseは、条件分岐のための演算子です。

conditionの論理値化がTRUEとして評価される場合はthen、そうでない場合はelseを返します。

$ xa 'TRUE ? "Yes" : "No"'
# Yes

$ xa 'FALSE ? "Yes" : "No"'
# No

三項演算子も論理演算子と同様に不要な項は評価自体が行われないため、if文のように使うことができます。

$ xa -q '
  check := value -> (
    value %% 2 ? (
      OUT << "$value is even"
    ) : (
      OUT << "$value is odd"
    )
  )

  check(4)
  check(9)
'
# 4 is even
# 9 is odd

三項演算子の記法#

三項演算子は入れ子にしたり、演算子の前で改行することができます。

$ xa '
  get_name := is_parent, is_man ->
    is_parent
      ? is_man
        ? "King"
        : "Queen"
      : is_man
        ? "Prince"
        : "Princess"

  get_name(TRUE; TRUE),
  get_name(TRUE; FALSE),
  get_name(FALSE; TRUE),
  get_name(FALSE; FALSE),
'
# King
# Queen
# Prince
# Princess

前置コロン#

前置コロン: formulaは、何もしない演算子です。

これは三項演算子condition ? then : else: elseの部分と同一の働きを持つため、使い方によっては三項演算子の連鎖の可読性に寄与します。

:formulaの間に改行を入れることはできません。

$ xa '
  score := 85

  : score >= 90 ? "A"
  : score >= 80 ? "B"
  : "C"
'
# B

$ xa '
  score := 85

  : "C"
'
# C

エルビス演算子#

エルビス演算子value ?: defaultは、valueNULLである場合にdefault、そうでなければvalueを返す演算子です。

$ xa '"Orange" ?: "Apple"'
# Orange

$ xa 'NULL ?: "Apple"'
# Apple

valueがストリームである場合、エルビス演算子は各要素に対して適用されます。

エルビス演算子は戻り値のストリームを解決しません。

$ xa '(1, NULL, 3) ?: "default"'
# 1
# default
# 3

$ xa '(NULL,) ?: "default"'
# default

defaultがストリームを返した場合、戻り値のストリームは平坦化されます。

$ xa '(1, NULL, 3) ?: ("A", "B")'
# 1
# A
# B
# 3