To add to what Hendrik says, I think the overall point was that `\numexpr`

, `\dimexpr`

, *etc.* can be used in a full expansion context without leaving a stray `\relax`

or space:

```
\edef\example{\the\dimexpr 10 pt + 20 pt \relax}
```

gives `\example`

defined as `30pt`

with no unexpected tokens. That is in many ways much 'neater' than the alternative of leaving the `\relax`

in place. The same argument does not apply to TeX's setting of registers as that is never expandable, so the issue does not arise.

(Of course, for a definitive answer you would need to ask the members of the NTS team who actually wrote this code.)

I see two cases where `\the\numexpr...\relax`

works, but `\pdfstrcmp{}{...}`

will blow up, excluding the obvious case where `...`

is replaced by `0\relax\undefined`

, terminating the `\numexpr`

prematurely.

TeX interprets ``\a`

as a number, without expanding `\a`

. Hence, `\the\numexpr`\a\relax`

expands to `97`

(the character code of `a`

), whereas `\pdfstrcmp{}{`\a}`

blows up if `\a`

is not defined.

Using `\protected`

control sequences can also cause trouble, because those are forcefully expanded "from the left" in a `\numexpr`

, but will not be expanded by `\pdfstrcmp`

. Take for instance

```
\protected\def\gob#1{}
\the\numexpr 0\gob\undefined \relax
\pdfstrcmp{}{0\gob\undefined}
```

In the case of `\numexpr`

, `\gob`

is expanded and removes the `\undefined`

control sequence. In the second case, however, the `\edef`

-like expansion leaves the `\protected`

control sequence `\gob`

untouched, and goes on to expand `\undefined`

, which is, well, undefined.

The original goal I had was to define a macro which takes in an argument which can be either empty or an integer expression, and evaluates the integer expression or puts a default value in the case of an empty argument. It seemed illogical to perform expansion in the `\numexpr`

case but not for the emptyness test, and I was thinking of testing with `\pdfstrcmp{}{...}`

. That can't work. An uglier but more correct choice is the following:

```
\catcode`@=11
\def\evaluate#1{\expandafter\evaluate@\the\numexpr#1\z@\z@\relax}
\def\evaluate@#1\z@#2\relax{#1}
\evaluate{1+2+3}
\evaluate{\empty}
\evaluate{\@gobble\a}
\evaluate{`\a}
```

If the argument to `\evaluate`

is empty or expands to an empty argument, the `\numexpr`

expansion will go through all of it and reach the first `\z@`

, evaluating that to `0`

(default value), then stop because `\z@`

does not make sense in an integer expression there. The auxiliary cleans up.

On the other hand, if the argument to `\evaluate`

is a correct integer expression, it is evaluated, and `\numexpr`

stops expanding when encountering the first `\z@`

, and the cleaning up macro removes both `\z@`

.

I just thought of a better way: "`f`

-expand" (expand fully from the left, stopping at the first non-expandable token, removing it in case it is a space) the argument before testing for emptyness:

```
\def\evaluate#1{\expandafter\evaluate@\expandafter{\romannumeral-`0#1}}
\def\evaluate@#1{\the\numexpr\ifcat X\detokenize{#1}X\z@\fi#1\relax}
```

If the argument is empty or will expand to become empty, `\romannumeral-`0#1`

expands to nothing, and the test in `\evaluate@`

is true, which means we insert `\z@`

(default value). Otherwise `#1`

is evaluated.

## Best Answer

The four expression primitives (

`\numexpr`

,`\dimexpr`

,`\glueexpr`

,`\muexpr`

) can be used anywhere that a register of the same type can be. This means that`\numexpr`

produces integers,`\dimexpr`

produces dimensions,`\glueexpr`

produces glue expressions and`\muexpr`

produces muskip values. As such, something like the example in the questioncannot yield a real number as the result

hasto be a dimension. (As we'll see below, the result here is`6pt`

followed by`.3pt\relax`

.) (I've added`\the`

here so you can typeset the result rather than having to use it in an assignment. I'll do that throughout.)In all cases, the formal syntax is that the expressions absorb tokens and carry out appropriate mathematics up to either a

`\relax`

or the first non-valid token in the input. This is easiest to see with`\numexpr`

, which must produce an integer. So for examplewill print

`4pt`

, which is made up of the result of the expression (`4`

) followed by input which cannot be part of the expression and thus terminates it. This is useful in comparisons, where the comparator will necessarily terminate the expressionIn the case of

`\dimexpr`

and`\glueexpr`

, the formal syntax requires that the input consists of a dimension (or glue value) followed by an optional multiplication factor, and not the other way around. The factor may itself be a numerical expression. Thus all ofare valid and give the expected results, but

is not valid and leads to an error.

Expressions may use the operators

`+`

,`-`

,`*`

and`/`

along with parenthesis`(`

/`)`

. Division takes place with rounding, and this applies to any number expressions inside dimension/glue expressions. Thus for example we getIn glue expressions the plus/minus parts do not need parenthesis to be affected by a factor as they are necessarily one entity. So for example

yields

`10pt plus 2pt`

.Within expressions, TeX will coerce other numerical types into the correct form in the same way as occurs when doing register assignment. So

will result in

`65536`

,i.e.the value of`1pt`

converted to scaled points and then coerced into an integer. With`\glueexpr`

here the stretch/shrink would be dropped. Going the other way, any`\numexpr`

inside a`\dimexpr`

or`\glueexpr`

will need appropriate units providing