In math mode, does the space character between tokens have a meaning?

Like many around here, I am a long-time LaTeX user delighted to see a nice and consistent alternative to it!

I was under the impression that, in math mode, the space character has no meaning, except of course to separate tokens. I nevertheless encountered a case where it seems to impact spacing. To define Galois Fields, I’d write

define $"GF" ( p^n )$ as the field with $p^n$ elements

But Typst renders the expression with a fairly large extra space between the F and the opening bracket that I would like to avoid. The solution is to write $"GF"( p^n )$ instead, i.e., no space character between the second quote and the opening bracket, and the extra space disappears in the rendering.

On the other hand, if I write

$cos(theta)$ vs $cos ( theta )$

there does not seem to be any difference in the rendering.

So, are there some rules related to the space character in math mode that I am missing here? And, alternatively, is there a better way to write the GF in the expression above?

Many thanks already!

This is related to the symbol’s math class. You can try and observe it’s behavior with code below.

Code and preview
#let classes = ("normal", "punctuation", "opening", "closing", "fence", "large", "relation", "unary", "binary", "vary")

#table(
  columns: 2,
  align: center + horizon,
  "class", "behavior",
  ..classes
    .map(c => {
      let symbol = math.class(c, "test")
      (
        c,
        $
          "with space:" &a symbol b \
          "without space:" &a#symbol;b
        $,
      )
    })
    .flatten()
)

The math class of "GF" is normal so spaces around it counts.

1 Like

Hello! My advice here is to use change the math class text operator.

#let GF = math.op("GF")
define $GF ( p^n )$ as the field with $p^n$ elements
define $GF( p^n )$ as the field with $p^n$ elements

image

2 Likes

Very clear. Thank you both!

This is not entirely correct. While it’s true that "GF" by default has the "normal" class, it’s not what is responsible for the spacing. Any single-letter variable (like p or theta) also has the "normal" class. It is only because "GF" is in a string (with quotes), that it’s sensitive to spaces around it. The same is true for other elements which create a new frame, e.g. box or block.

For more detail, see the is_spaced function in the compiler’s source code.

A space is then only kept if at least one of the elements around it is spaced. One (slightly hacky) workaround to remove the “spacedness” of an element, while keeping it of class "normal", is by doing something like

#let symbol = math.class("normal", "GF" + h(0pt))
$ a symbol b $

image

See also this comment on GitHub.

(For this case, you should follow what @quachpas suggested though, as that is exactly what the op function is for.)

2 Likes