Expression model
Expression is the library's primary symbolic scalar representation. Rather than thinking of it as a generic AST node, it is better understood as a typed internal value: each expression has a required type and value, with additional fields present only when that form of expression needs them.
NUM, VAR, EXP, FUN, GRP, PRD, SUM, and INF reflect how expressions are represented and canonicalized internally. They are implementation details rather than a general classification of mathematical objects.Anatomy of an Expression
type and value identify the stored node. Other fields are representation-dependent. In particular, multiplier and power can be absent from storage even though getMultiplier() and getPower() still provide the effective values algorithms should use.
Rational.Optional storageFUN nodes.FUN onlyEXP nodes.EXP onlyWhy the multiplier matters
Numeric coefficients are usually kept outside the symbolic child structure. That is why a contributor should not picture 2*x simply as a product node containing the children 2 and x.
2*xOrdinary mathematical notation.
multiplier = 2value = xpower = 1The numeric coefficient can live on the symbolic node.
like terms combine structurallyArithmetic can reason about the symbolic base separately from its coefficient.
The expression groups
The type field identifies how an Expression is represented internally. These groups are organizational categories used by Nerdamer's canonicalization logic; they are not general mathematical classifications.
Plain numeric value
Stores plain numeric values.
3/2Variable representation
Stores symbols or variables whose powers fit the variable representation.
x^2Separate exponential node
Stores bases with powers that require a separate exponential node. It is not the same thing as the function exp(...).
Function call
Stores function calls and their argument expressions.
sin(x)Common-base sum
Stores sums with a common base but differing powers.
x + x^ycos(x) - 3*cos(x)^2Symbolic product
Stores products of non-numeric symbolic factors. Numeric coefficients are normally moved to the outer multiplier during parsing.
x*yOther sums
Stores sums that do not fit the common-base grouping. For example, 1 + x + x^2 contains a numeric term and a grouped polynomial-like component.
Infinite value
Stores infinite values.
InfinityHow grouping drives canonicalization
Nerdamer does more than place parsed input into a tree of addition and multiplication nodes. Arithmetic assigns symbolic expressions canonical lookup identities, separates numeric coefficients from symbolic structure where possible, and uses keyed child collections to combine compatible terms and factors as expressions are built.
Like terms combine without a later collection pass
For a simple variable term, the numeric coefficient normally lives in the outer multiplier. This lets addition recognize equal symbolic structure directly.
2*x + 3*x
x:
multiplier = 2
+
x:
multiplier = 3
→ 5*x
The two terms have the same symbolic value and the same power, so addition combines their multipliers. The parser does not need to preserve a binary tree such as Add(Mul(2,x), Mul(3,x)) and then run a separate like-term pass to discover the result.
GRP collects powers of a common symbolic base
The more unusual case occurs when two additive terms have the same canonical base but different powers. The ordinary lookup key matches, but the complete terms do not. Nerdamer represents that relationship explicitly with GRP.
x + x^2
GRP: common base x
power 1 → x
power 2 → x^2
Members of a group are keyed by power. A heterogeneous term cannot join that common-base group, so an expression such as 1 + x + x^2 is represented as a SUM containing the numeric term and the grouped polynomial-like component.
1 + x + x^2
SUM
# → 1
x → GRP
power 1 → x
power 2 → x^2
The base does not have to be a polynomial variable
GRP belongs to the general Expression model rather than to the separate polynomial classes. Any compatible symbolic expression can act as the common base. Functions are an important example.
cos(x) - 3*cos(x)^2
GRP: common base cos(x)
power 1 → cos(x)
power 2 → -3*cos(x)^2
The same idea also permits groups such as x + x^y. This is why GRP should not be read simply as “polynomial”: it is a generalized common-base collection inside ordinary symbolic expressions.
Products use the same keyed-structure idea
A PRD keeps the overall numeric coefficient outside its symbolic factor collection and uses canonical factor keys to find repeated bases. Matching factors can therefore combine their powers as the product is formed.
2*x*y*x^2
multiplier = 2
PRD
x → x^3
y → y
Keys are structural helpers, not serialized identities
Expression.keyValue() supplies the lookup key used by the addition and multiplication machinery. Atomic expressions generally use a multiplier-free identity; aggregate expressions derive their key from canonical children. When a shorter key collides with a different subexpression, the arithmetic code can fall back to a fuller subexpression key before inserting it. These keys exist to support expression combination and should not be treated as a persistent file format.
A node is canonical structure, not source text
Parsing normalizes expressions. Ordering, grouping, multipliers, and powers are chosen to make later symbolic operations predictable, so the tree is not intended to preserve the exact spelling of the input. That is why text() should be read as the canonical representation rather than a source-code round trip.
const expression = Expression.create('2*x + 1');
expression.text(); // "1+2*x"
expression.evaluate({ x: 3 }).text(); // "7"
Expression is only one parser result type
Most scalar mathematics lands here, but the parser's result union is wider. Algorithms that require an Expression should narrow or convert explicitly rather than assume every parsed value is scalar.
Expressionsymbolic scalarEquationLHS / RHS structureVectorordered valuesMatrixtwo-dimensional valuesCollectionordered aggregateValuesSetfinite setDictionarykey/value aggregateThe class documentation in Expression.ts describes the group meanings and representation fields directly.
The parser page explains how source notation is turned into these objects in the first place.
Parser internals