Operators

Implicit intersection (@)

Implemented; no recorded answers are attributed to this entry

Handled by the formula layer, which owns references; answers are recorded through whole formulas, not attributed to the operator. How we measure this · See the Rust code

No local names are recorded for this entry.

What it does

@A

@A reduces its operand to a single value, using the position of the calling cell to decide which one.

  1. Already a single item — returned unchanged.
  2. A reference or range — scalarized relative to the caller: the same-row or same-column cell of that range, chosen against the formula's anchor. A two-dimensional range yields #VALUE! on the admitted native baseline.
  3. An array payload rather than a reference identity — scalarized to the top-left item.
  4. A spill-capable expression — removing @ changes the publication surface from scalarization to spilling, subject to host spill rules.

Cases 2 and 3 differ in which item survives, and the difference is the reason the operator needs references visible: a range is scalarized positionally, an array is scalarized to its first element. An implementation that dereferences the operand before @ sees it cannot tell the two apart.

Why the character exists at all

Before dynamic arrays, a formula that handed a range to a scalar-shaped argument got this scalarization silently — "implicit intersection" is the historical name for the silent behaviour. When Excel gained dynamic arrays, the same expression started spilling instead. @ is the explicit marker that preserves the old meaning: it makes the intersection visible in the formula text so that legacy workbooks keep computing what they always computed. The contract puts it plainly: explicit @ "is a modern surface marker for implicit-intersection behavior that older Excel performed silently".

That is also why @ appears unbidden in formulas that were written years earlier: opening an old workbook in a dynamic-array build can surface the marker that was previously implicit. The character is a compatibility artifact, not a new feature.

One operator, several spellings

Chapter 05 records SINGLE(...) and _xlfn.SINGLE(...) as compatibility and serialization representations of this same operator identity — not separate semantics. The contract adds that the host baseline normalizes _xlfn.SINGLE(...) back onto explicit @ in the modern formula property. So a reader may encounter three spellings of one function.

Arguments

PositionNameMeaning
0AThe expression to scalarize. Required.

Arity is exactly 1; no optional arguments, no defaults. The operator is prefix.

Try it

Input cells (optional)

Example: {"B2": 3, "B3": 4}. A1 holds the formula. Other cells need values before a formula can read them.

Enter a formula, then calculate.

Runs locally in your browser with OneCalc. Its answer may differ from Excel. Use English function names and commas between arguments.

Quirks

Result and edge cases

Returns whatever single value the scalarization selects — a scalar of any kind, or an error. The kernel class is Custom; there is no meaningful signature in the numeric sense.

  • Scalar operand. Passthrough.
  • One-row or one-column range. The cell in the caller's column or row respectively.
  • A range that does not intersect the caller's row or column. The historical behaviour of silent implicit intersection was #VALUE! in this case; the contract's admitted lane records #VALUE! for the two-dimensional case, and this page does not extend that to every non-intersecting shape without evidence.
  • Two-dimensional range. #VALUE! on the admitted native baseline.
  • Array payload. Top-left element.
  • Empty array. Chapter 01 lists #CALC! as the error for an engine that cannot produce a value, including the empty-array case. Whether @ on an empty array reaches it is not recorded here.
  • Inside a lambda or a function argument. The "calling cell" for a nested evaluation is an execution-context question (chapter 04), not an operator question, and this page does not settle it.

Note one structural consequence: because the operator needs a workbook and a calling cell, it cannot be exercised by a value-only dispatch harness at all. The Handbook's mechanical battery records it as not dispatchable for exactly that reason — a fact about the harness, not about the operator.

Errors

ErrorCondition
#VALUE!The operand cannot be scalarized against the caller's position — recorded for the two-dimensional range case on the admitted baseline.
any incoming errorAn error operand propagates.

data/functions/FUNC.OP_IMPLICIT_INTERSECTION.json records no Microsoft documentation URL (docs is null).

How to implement

Notes for implementers

  • The presence of @ must survive parsing and binding into evaluation metadata even when the stored form omits the token. The contract states this as a hard requirement, and it is the single thing most likely to be got wrong: an evaluator that reconstructs @ from the stored formula text alone will lose it.
  • Keep reference identity distinct from array payload all the way to the operator. The two cases scalarize differently.
  • The calling cell's position is an input. Any caching keyed only on the operand is wrong.
  • Treat the three spellings as one identity with a normalization step, not as three functions.
  • This operator is HostSerialized: it is not safe to evaluate on an arbitrary worker thread the way the arithmetic operators are.

Rust code

Show the CalcFunc source of this function

Quoted from the public repository DnaCalc/DnaCalc, crates calc-func and calc-fml, at commit 9e1884369a67. Comments are the source's own. A kernel shared with other functions appears once, on its module page.

implicit · 15 lines · calc-fml/src/eval/refops.rs on GitHub
/// What implicit intersection takes of `value` for a formula at `at`: a reference to one cell, or
/// a value. An array's empty first element is the empty value.
pub(super) fn implicit(value: &CalcValue, at: CellKey) -> CalcValue {
    match value.core_ref() {
        CoreRef::Reference(reference) => match intersect_cell(reference, at) {
            Some(cell) => CalcValue::reference(ReferenceLike::cell(cell)),
            None => CalcValue::error(WorksheetErrorCode::Value),
        },
        CoreRef::Array(array) => array
            .get(0, 0)
            .cloned()
            .expect("an array holds at least one element"),
        _ => value.clone(),
    }
}
intersect_cell · 22 lines · calc-fml/src/eval/refops.rs on GitHub
/// The cell implicit intersection picks of `reference` for a formula at `at`, if any.
pub(super) fn intersect_cell(reference: &ReferenceLike, at: CellKey) -> Option<CellKey> {
    let [area] = reference.areas() else {
        return None;
    };
    let (top, left, bottom, right) = bounds(*area);
    let row = if top == bottom {
        top
    } else if (top..=bottom).contains(&at.row()) {
        at.row()
    } else {
        return None;
    };
    let column = if left == right {
        left
    } else if (left..=right).contains(&at.column()) {
        at.column()
    } else {
        return None;
    };
    CellKey::new(area.sheet(), row, column).ok()
}

Kernels shared with other functions

No implementation has been published with a Handbook test suite for this function.

Version differences

No comparison between specific Excel builds is recorded here yet. This does not establish that all builds behave alike.

Alternatives

Relationships

  • FUNC.OP_SPILL_REF — the other dynamic-array operator, and the opposite motion: # names a whole spilled region, @ refuses to spill.
  • FUNC.OP_INTERSECTION_REF — the explicit intersection of two references, spelled with a space. Despite the shared word, it is a different operation with different operands; confusing the two is common and this page names the confusion deliberately.
  • SINGLE, _xlfn.SINGLE — the same identity under compatibility and serialization spellings (chapter 05).
  • INDEX, INDIRECT, OFFSET, XLOOKUP — reference-returning functions whose results @ consumes; the contract treats them as supporting substrate that @ does not redefine.
  • TAKE(x,1,1), INDEX(x,1,1) — explicit alternatives when the intent is "the first element" rather than "the historically intersected element". They mean what they say; @ means something position-dependent.

Named variants

No named variants are recorded yet.

Suggest a correction or contribute an implementation · For agents