The expressive power of the class of functions that we can declare at
this point is very limited, because we have no way to make tests and
to perform different operations depending on the result of a test.
For instance, we cannot declare a function that computes the
absolute
value of a number by testing whether the number is negative or not,
and taking different actions in each case according
to the rule
\[
|x| = \left\{ \begin{array}{rl}
x & \mbox{if $x \geq 0$} \\
-x & \mbox{otherwise}
\end{array}
\right.
\]
This construct is a *case analysis* and can be expressed
in JavaScript using a *conditional expression* as follows:

function abs(x) { return x >= 0 ? x : -x; }

The word *predicate* is used for functions that return
*true* or *false*, as well as for expressions that
evaluate to *true* or *false*.
The absolute-value function `abs`
makes use of the
primitive
predicate `>=`.
This predicate takes two
numbers as arguments and tests whether the first number is
greater than or equal to the second number,
returning *true* or *false* accordingly.

JavaScript
provides a number of primitive predicates that work similar to
`>=`, including
`>`,
`<`,
`<=`, and
`===`.
In addition to these primitive
predicates, there are logical
composition operations, which enable us to construct compound
predicates.
The three most frequently used are these:

- $ \textit{expression}_1$
`&&`$\textit{expression}_2$The interpreter evaluates $\textit{expression}_1$. If it evaluates to *false*, the value of the whole expression is*false*, and $\textit{expression}_2$ is not evaluated. If $\textit{expression}_1$ evaluates to*true*, the value of the whole expression is the value of $\textit{expression}_2$. -
$\textit{expression}_1$
`||`$\textit{expression}_2$The interpreter evaluates $\textit{expression}_1$. If it evaluates to *true*, the value of the whole expresssion is*true*, and $\textit{expression}_2$ is not evaluated. If $\textit{expression}_1$ evaluates to*false*, the value of the whole expression is the value of $\textit{expression}_2$. -
`!`$\textit{expression}$The value of the expression is *true*when $\textit{expression}$ evaluates to*false*, and*false*otherwise.

minusoperator, an example of which is the expression

function not_equal(x, y) { return x > y || x < y; }

function not_equal(x, y) { return !(x >= y && x <= y); }

10;

5 + 3 + 4;

9 - 1;

6 / 2;

2 * 4 + (4 - 6);

const a = 3;

const b = a + 1;

a + b + a * b;

a === b;

b > a && b < a * b ? b : a;

a === 4 ? 6 : b === 4 ? 6 + 7 + a : 25;

2 + (b > a ? b : a);

(a > b ? a : a < b ? b : -1) * (a + 1);

a === 4 ? 6 : b === 4 ? 6 + 7 + a : 25;

a === 4 ? 6 : b === 4 ? 6 + 7 + a : 25;

There is currently no solution available for this exercise. This textbook adaptation is a community effort. Do consider contributing by providing a solution for this exercise, using a Pull Request in Github.

(5 + 4 + (2 - (3 - (6 + 4 / 5)))) / (3 * (6 - 2) * (2 - 7));

function f(x, y, z) { return square(x) + square(y) + square(z) - // subtract the square of the smallest square(x > y ? (y > z ? z : y) : (x > z ? z : x)); }

function plus(a, b) { return a + b; } function minus(a, b) { return a - b; } function a_plus_abs_b(a, b) { return (b >= 0 ? plus : minus)(a, b); }

- Evaluate the function expression of the application combination, resulting in the function to be applied.
- Evaluate the argument expressions of the combination.
- Evaluate the return expression of the function with each parameter replaced by the corresponding argument.

function p() { return p(); } function test(x, y) { return x === 0 ? 0 : y; }

test(0, p());

[1]
In JavaScript, other values are automcatically converted into
*true* and
*false*
according to *conversion rules*, but we choose not to make
use of these conversion rules in this book.

[2]
For an expression of the form
`a (b > 0 ? + : -) b`
the JavaScript interpreter would not know the precedence of
the operator
between `a` and
`b`, and therefore
such expressions are not allowed.

1.1.6
Conditional Expressions and Predicates