This chapter covers how to build expressions for evaluating values and combining those results logically in a conditional expression (typically used for the control blocks described in the next chapter):

Evaluations

Acorn offers many operators and methods for evaluating values against specific criteria:

Note: Evaluation operators have lower precedence than arithmetic operators, but higher than assignment.

Equivalence Operators

The '==' operator returns true if two values have the same content and type. '!=' (not equal) is true if they do not. For example:

x == 3.0        # Returns true if the local variable x's value is 3.0
x+1 != y        # Returns true if x is not exactly 1 greater than y
2 == 2.0        # Returns false, because the Integer vs. Float types do not match
true != false   # Returns true

The equality check is not always exact or rapid, depending on the value's type. Since floating point calculations are imprecise and can introduce "rounding errors", two Float values will be declared "equal" if they are sufficiently close. Large, complex value types, such as lists, can take time, as it requires comparing every element in the list for equivalence.

The '===' operator offers a rapid way to determine if two values are literally the same value. Two floats would have to match exactly, with no margin for calculation error. Two List or Text values would have to point to the same List or Text value, as a copy made of a list would not be exactly equal using the '===' operator.

Comparison Operators

Comparison operators determine whether one value is greater or less than some other value. They only work well on value types that are comparable (such as Integer, Float and Text).

x >= 2          # Returns true if x is greater than or equal to 2 (>, <, <= are variants)
2 <= 2.0        # Returns false any time the types do not agree

Float values are compared using the same closeness criteria described above. For one Float value to be less than another, it must be less by at least the comparable closeness.

All comparison operators use the '<=>' method to perform the comparison. It returns an Integer (rather than true or false): -1 if less, 0 if equal, and 1 if greater. It returns 'null' if two values are not comparable. Any Type that implements this method becomes comparable:

# Make frosty comparable to other values
frosty
	# Comparison returns 1, as frosty is always the greatest!
	'<=>': [x]
		1

frosty > Float.Infinity  # true

The rocket-ship operator can be used directly:

-2 <=> 4      # Returns -1

Pattern Matching Operator

The '~~' pattern match operator determines whether a specific value matches a particular pattern. A pattern is any value that can responds to the '~~' method with a non-null value. Thus, all sorts of pattern-matchers can be built, such as set membership, types used, regular expression, search selectors (e.g., for parts), parsers, input decoders, translaters, information analysis, etc.

These examples use a Range as a pattern.

5 ~~ 1 .. 7   # Returns true, since 5 is within the range between 1 and 7

Some important notes about pattern matching:

Evaluation Methods

Beyond the evaluation operators listed above, there are many type-specific methods which can be used to evaluate values. This is particularly true for any method whose name ends with a question-mark (indicating it returns a true or false value). For example:

list.empty?   # Returns true if list has no members, false otherwise

Conditional Expressions

A conditional expression evaluates to some value whose "truth" is used to determine the sequence of statement execution for a control block or clause. Such expressions are considered false if its evaluated value is either false or null. Any other value of any type, including true, 0 and "" will be considered true.

A conditional expression can be as simple as a single literal or variable value. More commonly, it involves the use of one of the evaluation operators or methods described above. The boolean operators described below can be used to logically transform multiple evaluations into a single value that is considered true or false for control flow purposes.

Boolean Operators

Acorn has three boolean operators: and ('&&'), or ('||') and not ('!'). One can use either the word or the symbol. For example:

0==3 or not 2<3 and 3==3   # Returns true ('and' is evaluated before 'or')
0==3 || !2<3 && 3==3       # equivalent to above

The logical operators work mostly how you would expect:

Note: In case it is not obvious by now, these boolean operators are not the same as the boolean bit-arithmetic operators found in other languages. There should not be much need for them in Acorn, but they are provided as Integer methods (.not, .and, .or, .xor, .shl, .shr) if they are needed.

Note 2: If a comparison operator or boolean operator is used outside the context of a control structure that wants a conditional expression (e.g., if), in most cases it will evaluate to a value of 'true' or 'false'. If the conditional expression just uses 'and' or 'or' operators, its value will be the last value evaluated in that expression.

_