I am writing a package which currently works okay.

I want to use function

\ifx\relax#2 \the\numexpr#1\relax
  \the\numexpr(#1+\ifnum\expandafter`\string#2<"80 1\else \ifnum\expandafter`\string#2>"BF 1 \else 0 \fi\fi

This works okay inside of a document like this


When I want to use the zz function inside of package's function it starts to throw weird errors. I was trying to use \expandafter but without any succes.

I am trying to call the xx function inside a function like this

    % Set keys + defaults if options not provided
    \zz{\mm@char}% \mm@char is a correctly set key ----- THIS THROWS ERRORS
  • 2
    Macro \zz is defined, but \xx is used. The error is probably "Undefined control sequence". Also, the definition of \mm@char is not shown. Depending on its definition, an expansion might help: \expandafter\zz\expandafter{\mm@char}. Mar 17, 2018 at 17:59
  • 1
    Please add a minimal working example (MWE) that illustrates your problem.
    – TH.
    Mar 17, 2018 at 18:00

1 Answer 1


(This answer is really a long rant about “functions”, but may help you anyway…)

Calling package function inside a package function […] I want to use function […] When I want to use the zz function inside of package's function […] I am trying to call the xx function inside a function

There are no functions in TeX. It only has macros, which are simply text (token) substitution.

This distinction matters because from most typical programming languages, you may expect functions to behave in certain ways:

  1. It is possible to tell, from looking at the place where a function is referenced, how many arguments it takes and where its “region of influence” (in the input text) ends. For example, in most languages if you saw f(a, b); g(c), you would know that the function f takes two arguments a and b, and that g is another function that is “called” after f is. In TeX, if you see \f{a}{b}\g{c}, then anything is possible:

    • maybe \f takes zero or one parameters (leaving {a}{b} or {b} remaining on the input stream),
    • maybe it takes exactly two,
    • maybe it even takes three or four (so that the token \g is one of the parameters passed to \f),
    • maybe it takes even more,
    • maybe things will fail with Use of \f does not match its definition,
    • maybe\f only takes one parameter {a}, but it expands to something that takes multiple parameters, and that thing will consume the \g.
    • maybe \f expands to different things in different circumstances, and in some cases consumes more tokens than in others.

    Worse, all these patterns are in fact common in TeX code, such as in the definitions of macros in LaTeX and in packages. (It is only the external interface that LaTeX provides to the document author that is mostly consistent.) It is impossible to tell by looking at the source code like \f{a}{b}\g{c}.

  2. In a place where a value is expected, you can substitute a function call that returns a value. For example, if the function call g(2) returns the value 21, and if f takes one argument, then writing f(g(2)) is (somewhat, modulo side-effects) equivalent to writing f(21). In TeX, writing \f{\g{2}} will result in \f getting the sequence of four tokens (\g, {, 2, }) as its #1. (And all this is a simplification, as the situation can be different if catcodes are changed.)

(With all this in mind, you may want to consider whether you really want to program in TeX and whether it's something you may enjoy long-term… it can certainly be a fun puzzle but it can also be frustrating.)

In this case, the \zz solution you got (and which is in the question) works like the following, in something like \zz{abc}: First, \zz gets the three tokens abc. Then via clever expansions \zzz is repeatedly left on the input stream, to consume, as its (#1, #2), the pairs (0, a), (1, b), (2, c), (3, \relax), after which it expands to 3.

Now in your case, with \zz{\mm@char}, first \zz will get the token \mm@char as the parameter #1, not the value of \mm@char. (And if @ doesn't have the catcode of “letter”, it would get the sequence of five tokens (\mm, @, c, h, a, r) which is even worse.) This won't work because \zzz expects to get characters, on which it does tests like \ifnum \expandafter `\string #2<"80 and with #2 being \mm@char, this will not work.

In other words, you've run into the second problem mentioned above: unlike in most programming languages, even if \mm@char is defined as something that expands to abc, you cannot write \zz{\mm@char} instead of \zz{abc}.

The way to fix this will depend on the definition of \mm@char (which you've not given):

  • If \mm@char is something that expands to a sequence of characters in one expansion step, then you could use \expandafter\zz\expandafter{\mm@char} which results in TeX actually seeing \zz{<expansion of \mm@char>}.
  • If \mm@char expands to its final sequence in two steps (that is, it expands to a macro which expands to the desired sequence of characters), you could do: \expandafter\expandafter\expandafter\zz\expandafter\expandafter\expandafter{\mm@char} which results in the input stream getting replaced first with \expandafter\zz\expandafter{<expansion of \mm@char>} and then with \zz{<expansion of expansion of \mm@char>}
  • If \mm@char expands to its final sequence in more steps, you'll need more \expandafters.
  • And if \mm@char expands to multiple tokens (that are not what you want), or involves doing some state-changing computation (i.e. it involves commands that reach and are processed by TeX's “stomach”), then you'll have to find alternative solutions.

There's no other programming language I know of where instead of f(g(2)) you have to write different things based on how many steps g takes. There's a way to rationalise all this within the terminology of functions (e.g. by saying the “type” of g is different in those different cases), but it's better to instead use the right mental model: token substitution, not function calls.

  • Thanks you very much! It looks like I just don't understand functions at all. It's very hard for me even as a programmer! Made my code work thanks to you sir!!! Mar 18, 2018 at 10:27
  • @JanVorisek Glad your code works now, but what I was trying to explain is that TeX doesn't have functions. :-) Mar 19, 2018 at 6:20
  • Thanks I got it. Just didn't know it was called "macros". Mar 20, 2018 at 18:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .