Evaluating Expressions

beginner

When we evaluate an arithmetic expression like:

(2 + 4 * 6) * (3 + 12);

we’re not just computing a result — we’re following a very specific process.

To understand this process, think like the evaluator itself.


The Evaluation Process

Every time you evaluate a combination like a + b, the evaluator does two things:

  1. First, it evaluates each part — both a and b.
  2. Then it applies the operator (like +) to the results.

This means the process of evaluating an expression includes evaluating its parts — which are often combinations themselves. So the rule is recursive by nature.


Expression Trees

We can imagine this process as a tree: each node is a combination, and each child is either a number or another combination. Evaluation proceeds from the leaves (numbers) upward to the root, combining results as it goes.

For (2 + 4 * 6) * (3 + 12):

graph TD
    root["*"]
    left["+"]
    right["+"]
    a["2"]
    mul["*"]
    b["3"]
    c["12"]
    d["4"]
    e["6"]

    root --> left
    root --> right
    left --> a
    left --> mul
    mul --> d
    mul --> e
    right --> b
    right --> c

    style root fill:transparent,stroke:#6e7685,color:#dfe2ea
    style left fill:transparent,stroke:#6e7685,color:#dfe2ea
    style right fill:transparent,stroke:#6e7685,color:#dfe2ea
    style mul fill:transparent,stroke:#6e7685,color:#dfe2ea
    style a fill:transparent,stroke:#9ecaff,color:#9ecaff
    style b fill:transparent,stroke:#9ecaff,color:#9ecaff
    style c fill:transparent,stroke:#9ecaff,color:#9ecaff
    style d fill:transparent,stroke:#9ecaff,color:#9ecaff
    style e fill:transparent,stroke:#9ecaff,color:#9ecaff

The leaves (numbers, in blue) are evaluated first. Then the results accumulate upward — each operator combines its children’s values until we reach the root.

This is called tree accumulation — a general technique for dealing with hierarchical structures.


What You’ll Do

In this problem, you’ll write rules for evaluating simple arithmetic expressions built from numbers and operators.

Your job is to fill in the pattern rules that tell the evaluator what to do when it sees:

  • A number
  • A combination like [2, "+", 3]
  • A nested expression like [2, "+", [4, "+", 6]]

NOTE

In our syntax, every combination is explicitly bounded by square brackets, so operator precedence never matters. The nesting is the precedence. For example, (2 + 4 * 6) becomes [2, "+", [4, "*", 6]] — the brackets make the structure unambiguous.


How the Evaluator Works

You’ll work with a function like this:

function evaluate(expr) {
  return match(expr, {
    "n": (n) => ...,
    "l + r": (l, r) => ...
  });
}

The evaluator already knows how to match the patterns. You just write what should happen when it sees a number or a combination.

Let’s begin.

Steps