3

I must use longtblr from tabularray package and would like to calculate simple products on each row.

Trouble is, the product displayed in the final result is the same for every row : the product from the ending row. As illustrated below, the first row should end with 4.4 and not 8.

wrong output

\documentclass{article}
\usepackage{tabularray}
\UseTblrLibrary{functional}
\IgnoreSpacesOn
\FpNew \Total
\PrgNewFunction \Product {mmm} {
  \FpSet \SubTotal {#2 * #3}
  \TlSet \Row {#1 & #2 & #3 & {\FpUse \SubTotal}\\}
  \FpAdd \Total {\FpUse \SubTotal}
  \Return {\TlUse \Row}
}
\IgnoreSpacesOff
\begin{document}
\begin{longtblr}[evaluate=\Product]{cccc}
  \Product{Text}{1.1}{4}
  \Product{Text}{4}{2}
  Total &&& \FpUse \Total
\end{longtblr}
\end{document}

I'm using latest tabularray and functional packages from github for these functionalities.

I'm also computing the total sum from the last column and it is working fine.

Thanks in advance for any helpful answer ! And many thanks to @L.J.R. for creating this wonderful TeX package (the most feature-packed tabular environment to my knowledge) !

6
  • Looks like you can try printing out the value of Row before each return to see what will be executed.
    – user202729
    Commented May 21, 2022 at 18:00
  • Ah, the problem here is FpUse will not be "executed"... (see, I told the author that implicitly doing things without letting users understand how expansion works in TeX is not good idea...)
    – user202729
    Commented May 21, 2022 at 18:01
  • Try something like this, not tested \PrgNewFunction \SetRow {mmmm} {\TlSet \Row {#1 & #2 & #3 & #4\\}} + \SetRow {#1} {#2} {#3} {\FpUse \SubTotal}
    – user202729
    Commented May 21, 2022 at 18:04
  • @user202729 The main focus of functional package is to avoid using argument variants or \exp_args. Users still need to know some about expansion, and there are several expansion functions provided in functional package.
    – L.J.R.
    Commented May 22, 2022 at 11:23
  • Hm, I consider that a minor point it's it's not that inconvenient compared to the tmp-variable thing -- nevertheless what I'm saying here is that the package documentation is not clear on how it works internally in terms of TeX (which causes the confusion in at least this one example), and how it can be used in conjunction with other TeX interface (how to pass data from expl3-like interface to functional-like interface and vice versa, make wrapper of expl3-like libraries, etc.) --not to demand features (yes, software development is hard), just some suggestions.
    – user202729
    Commented May 22, 2022 at 11:46

1 Answer 1

3

To avoid potential naming conflicts with commands in LaTeX kernel and other packages, functional package has changed its naming scheme for functions from \UpperCamelCase to \lowerCamelCase since version 2022G (2022-05-22).

Also there is some renaming for single-word functions (see the changelog). For example, \Return has been renamed as \prgReturn.

For backward compatibility, those old UpperCamelCase function names can still be used for some time as long as they are not used by kernel or other packages, but they will be removed in the future.


An inner function is evaluated only when it occurs at the beginning of an argument. So the following line

\tlSet \Row {#1 & #2 & #3 & {\fpUse \SubTotal}\\}

need to be changed to

\tlSet \Row {#1 & #2 & #3 & }
\tlPutRight \Row {\fpUse \SubTotal}
\tlPutRight \Row {\\}

Now you get the expected result:

\documentclass{article}
\usepackage{tabularray}
\UseTblrLibrary{functional}
\IgnoreSpacesOn
\fpNew \Total
\prgNewFunction \Product {mmm} {
  \fpSet \SubTotal {#2 * #3}
  \tlSet \Row {#1 & #2 & #3 & }
  \tlPutRight \Row {\fpUse \SubTotal}
  \tlPutRight \Row {\\}
  \fpAdd \Total {\fpUse \SubTotal}
  \prgReturn {\tlUse \Row}
}
\IgnoreSpacesOff
\begin{document}
\begin{longtblr}[evaluate=\Product]{cccc}
  \Product{Text}{1.1}{4}
  \Product{Text}{4}{2}
  Total &&& \fpUse \Total
\end{longtblr}
\end{document}

enter image description here

6
  • (more remark) Also there's no need for TF variant of everything... just make the boolean-output function and pass it to BoolVarIfTF (maybe the other is slightly faster, but scanning every argument every time, make group, etc. likely is terribly slow anyway)
    – user202729
    Commented May 22, 2022 at 11:55
  • && there's no way I can set a TL to some token? \TlSet \lx {\ExpNot{\IntEval{1+2}}} doesn't work in the current version
    – user202729
    Commented May 22, 2022 at 11:55
  • (off topic here but) While testing different things I notice that \TlSet \lx {\UseOne{a}\UseOne{b}} will set it to b instead of ab (if it sets to ab then it could be used here, just wrap UseOne around things as well)
    – user202729
    Commented May 22, 2022 at 11:58
  • @user202729 Could you open a new question on this site? Or on github.com/lvjr/functional/discussions? It is always hard to discuss in comments.
    – L.J.R.
    Commented May 22, 2022 at 12:14
  • Thank you for the explanation and working example @L.J.R. Works like a charm for my usecase ! I guess the important part is about the need to use top-level argument to ensure evaluation. As you said "An inner function is evaluated only when it occurs at the beginning of an argument."
    – Wabylete
    Commented May 22, 2022 at 12:17

You must log in to answer this question.

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