# How to use pgf-math inside an argument?

I response to xport's recent questions, I tried to do the following

\usepackage{pgf}
[...]
\rule{\pgfmathdivide{4}{3}\pgfmathresult mm}{5mm}


Unfortunately, this fails with the following error message:

! Missing number, treated as zero.
\begingroup
l.11 ...pgfmathdivide{4}{3}\pgfmathresult mm}{5mm}


My first guess was that for some reason the output of \pgfmathresult cannot be used as the input for \rule. However, the slight rearrangement

\pgfmathdivide{4}{3}\rule{\pgfmathresult mm}{5mm}


works as expected. Why? What do I have to change to be able to put \pgfmathdivide inside the argument of \rule (or rather inside a macro that can be used in the argument of \rule and similar commands)?

-

\pgfmathdivide is simply not expandable. By that, I mean it cannot run entirely in TeX's expansion processor.

A simple example of this is trying to assign to a register inside the replacement text of an \edef.

\edef\foo{\dimen0=3pt}
\show\foo


gives

> \foo=macro:
->\dimen 0=3pt.


Note that nothing actually expanded. The same principle is at work here. \pgfmathdivide expands to at least one assignment (to \pgfmathresult) and since assignments are not expandable, \pgfmathdivide cannot be used in an expansion context (at least not the way you want).

It might be possible to reimplement division in a way that is expandable, for example using ε-TeX's expression primitives, but it would probably be a nontrivial amount of work.

-
You can do division up to a point: see my answer to xport's question: tex.stackexchange.com/questions/7801. However, there is always the need to do an approximation via dimensions. To do a fully-expandable but accurate division you'd be looking at incredibly complex code, if it's doable at all. (As I've been writing the floating point unit for LaTeX3 I do have some idea about how complex this might be!) –  Joseph Wright Dec 27 '10 at 16:40
For completeness, an expandable division using e-TeX can be defined as \newcommand\Divide[2]{\strip@pt\dimexpr#1pt/#2\relax} (with the appropriate \makeatletter/\makeatother if needed). –  Joseph Wright Dec 27 '10 at 16:46
Another point to make here with my 'LaTeX3 hat' on. In the LaTeX3 work we are aiming to be very clear that everything is either fully expandable or is protected (using e-TeX) so it will not expand at all in these contexts. At the same time, we're trying to document whether functions are expandable or not, so that users are not left with having to guess! –  Joseph Wright Dec 27 '10 at 16:49
@Joseph: I didn't realize one could use \the with a \dimexpr. For example, \the 5pt is invalid. This is good to know. The more I hear about the features that LaTeX3 is aiming to provide, the more excited I am. (I still haven't found the time to take the plunge and spend a lot of time looking at expl3. It just seems verbose and obscure at the same time. It's just my ignorance, I'm sure.) –  TH. Dec 27 '10 at 17:47
Compared to TeX primitives I guess that expl3 does look quite verbose. However, in many ways I guess this reflects changes in programming ideas over the years. TeX's syntax is compact but at a cost of having to understand a lot of what is going on, while with expl3 the plan is to provide something which is more accessible and systematic. Of course there is a pay off, and not everyone feels it is worth it. The other members of the LaTeX3 Team and I do, and I hope we can convince enough other people to make things work. Perhaps a discussion to continue on directly :-) –  Joseph Wright Dec 27 '10 at 20:03

As TH notes in his answer, the macros from pgfmath are not expandable. In fact, I rewrote the l3fp package from scratch a year ago (well, it took me many months) to provide an expandable version of what many other packages provide. Writing expandable code means in particular that it is not possible to store results in variables, and of course that makes it very tricky to parse expressions, or compute trigonometric functions. Long story short, we can now perform computations expandably, hence the following works.

\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\cs_set_eq:NN \eval \fp_eval:n
\ExplSyntaxOff
\begin{document}
\rule{\eval{4/3}mm}{5mm}
\end{document}


First make the programming command \fp_eval:n available at document level, as \eval, then use it in the argument of \rule. The \fp_eval:n command takes one argument, evaluates it as a floating point expression, and produces a decimal number, so after expansion the argument of \rule is 1.333333333333333mm (16 significant figures). The l3fp package also provides other functions, for instance \fp_to_scientific:n, which would give things like 3.4e5, or \fp_to_tl:n, which produces a scientific representation for very large or very small numbers, but otherwise a decimal representation. Another goal of l3fp is to follow the (decimal) IEEE 854 (now absorbed into 754) standard. A major omission is the absence of support for subnormal numbers.

-