% -*- coding: utf-8 -*- \documentclass[oneside]{book} \usepackage[a4paper,margin=2.5cm]{geometry} \newcommand*{\myversion}{2022A} \newcommand*{\mydate}{Version \myversion\ (\the\year-\mylpad\month-\mylpad\day)} \newcommand*{\mylpad}[1]{\ifnum#1<10 0\the#1\else\the#1\fi} \setlength{\parindent}{0pt} \setlength{\parskip}{4pt plus 1pt minus 1pt} \usepackage{codehigh} \colorlet{highback}{blue9} %\CodeHigh{lite} \CodeHigh{language=latex/latex2,style/main=highback,style/code=highback} \NewCodeHighEnv{code}{style/main=gray9,style/code=gray9} \NewCodeHighEnv{demo}{style/main=gray9,style/code=gray9,demo} \NewDocumentCommand\MySubScript{m}{$_{#1}$} \ExplSyntaxOn \NewDocumentCommand\PrintVarList{m}{ \clist_set:Nn \l_tmpa_clist {#1} \clist_map_inline:Nn \l_tmpa_clist { \token_to_str:N ##1 ~ } } \NewDocumentCommand\RelaceChacters{m}{ \tl_set:Nn \lTmpaTl {#1} \regex_replace_once:nnN { \_ } { \c{MySubScript} } \lTmpaTl } \ExplSyntaxOff \NewDocumentEnvironment{variable}{m}{ \vspace{5pt} \begin{minipage}{\linewidth} \hrule\vspace{4pt}\obeylines% \begingroup \ttfamily\bfseries\color{azure3} \PrintVarList{#1} \endgroup \par\vspace{4pt}\hrule \end{minipage}\par\nopagebreak\vspace{4pt} }{% \vspace{5pt}% } \NewDocumentEnvironment{function}{m}{ \vspace{5pt}% }{\vspace{5pt}} \NewDocumentEnvironment{syntax}{}{% \begin{minipage}{\linewidth} \hrule\vspace{4pt}\obeylines% }{% \par\vspace{4pt}\hrule \end{minipage}\par\nopagebreak\vspace{4pt} } \NewDocumentEnvironment{texnote}{}{}{} \NewDocumentCommand\cs{m}{% \texttt{\bfseries\color{purple3}\expandafter\string\csname#1\endcsname}% } \NewDocumentCommand\meta{m}{% \RelaceChacters{#1}% \textsl{$\langle$\ignorespaces\lTmpaTl\unskip$\rangle$}% } \NewDocumentCommand\Arg{m}{% \RelaceChacters{#1}% \texttt{\{}\textsl{$\langle$\ignorespaces\lTmpaTl\unskip$\rangle$}\texttt{\}}% } \let\tn=\cs \RenewDocumentCommand\emph{m}{% \underline{\textsl{#1}}% } \usepackage{hyperref} \hypersetup{ colorlinks=true, urlcolor=blue3, linkcolor=blue3, } \usepackage{functional} %\Functional{scoping=false,tracing=true} \begin{document} \title{\sffamily LaTeX2 \textcolor{green3}{Functional} Interfaces to LaTeX3 Programming Layer} \author{Jianrui Lyu (tolvjr@163.com)\\\url{https://github.com/lvjr/functional}} \date{\mydate\vspace{1cm}\\\myabstract\vspace{10cm}} \newcommand\myabstract{\parbox{\linewidth}{\hrule\vspace{0.8em}\large LaTeX3 programming layer (\textsf{expl3}) is very powerful for advanced users, but it is a little complicated for normal users. This \textcolor{green3}{\sffamily functional} package aims to provide intuitive LaTeX2 functional interfaces for it. \par\vspace{0.5em} Although there are functions in LaTeX3, the evaluation of them is from outside to inside. With this package, the evaluation of functions is from inside to outside, which is the same as other programming languages such as \texttt{JavaScript} or \texttt{Lua}. In this way, it is rather easy to debug code too. \par\vspace{0.5em} Note that many paragraphs in this manual are copied from the documentation of \textsf{expl3}. \par\vspace{0.8em}\hrule}} {\let\newpage\relax\vspace{-4cm}\maketitle} \tableofcontents \chapter{Overview of Features} \section{Evaluation from Inside to Outside} We will compare our first example with a similar \verb!Lua! example: \begin{code} -- lua code -- function MathSquare (arg) local lTmpaInt = arg * arg return lTmpaInt end print(MathSquare(5)) print(MathSquare(MathSquare(5))) \end{code} \begin{codehigh} %% function code \ExplSyntaxOn \PrgNewFunction \MathSquare { m } { \IntSet \lTmpaInt { \IntEval { #1 * #1 } } \Result { \Value \lTmpaInt } } \ExplSyntaxOff \MathSquare{5} \MathSquare{\MathSquare{5}} \end{codehigh} %\ExplSyntaxOn %\PrgNewFunction \MathSquare { m }{ % \IntSet \lTmpaInt { \IntEval { #1 * #1 } } % \Result { \Value \lTmpaInt } %} %\ExplSyntaxOff %\MathSquare{5} %\MathSquare{\MathSquare{5}} %\ExplSyntaxOn %\PrgNewFunction \MathCubic { m } % { % \IntSet \lTmpaInt { \IntEval { #1 * #1 * #1 } } % \Result { \Value \lTmpaInt } % } %\ExplSyntaxOff %\MathCubic{2} %\MathCubic{\MathCubic{2}} Both examples calculate first the square of $5$ and produce $25$, then calculate the square of $25$ and produce $625$. In contrast to \verb!expl3!, this \verb!functional! package does evaluation of functions from inside to outside, which means composition of functions works like othe programming languages such as \verb!Lua! or \verb!JavsScript!. You can define new functions with \cs{PrgNewFunction} command. To make composition of functions work as expected, every function \emph{must not} insert directly any token to the input stream. Instead, a function \emph{must} pass the result (if any) to \verb!functional! package with \cs{Result} command. And \verb!functional! package is responsible for inserting result tokens to the input stream at the appropriate time. To remove space tokens inside function code in defining functions, you'd better put function definitions inside \verb!\ExplSyntaxOn! and \verb!\ExplSyntaxOff! block. Within this block, \verb!~! is used to input a space. At the end of this section, we will compare our factorial example with a similar \verb!Lua! example: \begin{code} -- lua code -- function Factorial (n) if n == 0 then return 1 else return n * Factorial(n-1) end end print(Factorial(4)) \end{code} \begin{codehigh} \ExplSyntaxOn \PrgNewFunction \Factorial { m } { \IntCompareTF {#1} = {0} { \Result {1} }{ \Result { \IntMathMult {#1} { \Factorial { \IntMathSub{#1}{1} } } } } } \ExplSyntaxOff \Factorial{4} \end{codehigh} %\ExplSyntaxOn %\PrgNewFunction \Factorial { m } { % \IntCompareTF {#1} = {0} { % \Result {1} % }{ % \Result { \IntMathMult {#1} { \Factorial { \IntMathSub{#1}{1} } } } % } %} %\ExplSyntaxOff %\Factorial{0} %\Factorial{4} \section{Group Scoping of Functions} In \verb!Lua! language, a function or a condition expression makes a block, and the values of local variables will be reset after a block. For example \begin{code} -- lua code -- local a = 1 print(a) ---- 1 function SomeFun() local a = 2 print(a) ---- 2 if 1 > 0 then local a = 3 print(a) ---- 3 end print(a) ---- 2 end SomeFun() print(a) ---- 1 \end{code} In \verb!functional! package, a condition expression is in fact a function, and you can make every function become a group by setting \verb!\Functional{scoping=true}!. For example \begin{codehigh} \Functional{scoping=true} \ExplSyntaxOn \IntSet \lTmpaInt {1} \IntLog \lTmpaInt % ---- 1 \PrgNewFunction \SomeFun { } { \IntSet \lTmpaInt {2} \IntLog \lTmpaInt % ---- 2 \IntCompareTF {1} > {0} { \IntSet \lTmpaInt {3} \IntLog \lTmpaInt % ---- 3 }{ } \IntLog \lTmpaInt % ---- 2 } \SomeFun \IntLog \lTmpaInt % ---- 1 \ExplSyntaxOff \end{codehigh} Same as \verb!expl3!, the names of local variables \emph{must} start with \verb!l!, while names of global variables \emph{must} start with \verb!g!. The difference is that \verb!functional! package provides only one function for setting both local and global varianbles of the same type, by checking leading letters of their names. So for integer variables, you can write \verb!\IntSet\lTmpaInt{1}! and \verb!\IntSet\gTmpbInt{2}!. The previous example will produce different result if we change variable from \verb!\lTmpaInt! to \verb!\gTmpaInt!. \begin{codehigh} \Functional{scoping=true} \IntSet \gTmpaInt {1} \IntLog \gTmpaInt % ---- 1 \PrgNewFunction \SomeFun { } { \IntSet \gTmpaInt {2} \IntLog \gTmpaInt % ---- 2 \IntCompareTF {1} > {0} { \IntSet \gTmpaInt {3} \IntLog \gTmpaInt % ---- 3 }{ } \IntLog \gTmpaInt % ---- 3 } \SomeFun \IntLog \gTmpaInt % ---- 3 \end{codehigh} As you can see, the values of global variables will never be reset after a group. \section{Tracing Evaluation of Functions} Since every function in \verb!functional! package will pass its return value to the package, it is quite easy to debug your code. You can turn on the tracing by setting \verb!\Functional{tracing=true}!. For example, the tracing log of the first example in this chapter will be the following: % FIXME: spaces at the first line will be removed %\begin{codehigh}[] % [I] \MathSquare{5} % [I] \IntEval{5*5} % [I] \Expand{\int_eval:n {5*5}} % [O] 25 % [I] \Result{25} % [O] 25 % [O] 25 % [I] \IntSet\lTmpaInt {25} % [O] % [I] \Value\lTmpaInt % [O] 25 % [I] \Result{25} % [O] 25 % [O] 25 %\end{codehigh} \begin{codehigh}[] [I] \MathSquare{5} [I] \IntEval{5*5} [I] \Expand{\int_eval:n {5*5}} [O] 25 [I] \Result{25} [O] 25 [O] 25 [I] \IntSet\lTmpaInt {25} [O] [I] \Value\lTmpaInt [O] 25 [I] \Result{25} [O] 25 [O] 25 [I] \MathSquare{25} [I] \IntEval{25*25} [I] \Expand{\int_eval:n {25*25}} [O] 625 [I] \Result{625} [O] 625 [O] 625 [I] \IntSet\lTmpaInt {625} [O] [I] \Value\lTmpaInt [O] 625 [I] \Result{625} [O] 625 [O] 625 \end{codehigh} \section{Definitions of Functions} Within \verb!expl3!, there are eight commands for defining new functions, which is good for power users. \begin{code}[language=latex/latex3] \cs_new:Npn \cs_new_nopar:Npn \cs_new_protected:Npn \cs_new_protected_nopar:Npn \cs_new:Nn \cs_new_nopar:Nn \cs_new_protected:Nn \cs_new_protected_nopar:Nn \end{code} Within \verb!functional! package, there is only one command (\cs{PrgNewFunction}) for defining new functions, which is good for normal users. The created functions are always protected and accept \verb!\par! in their arguments. Since \verb!functional! package gets the results of functions by evaluation (including expansion and execution by \TeX), it is natural to protect all functions. \section{Variants of Arguments} Within \verb!expl3!, there are several expansion variants for arguments, and many expansion functions for expanding them, which are necessary for power users. \begin{code}[language=latex/latex3] \module_foo:c \module_bar:e \module_bar:x \module_bar:f \module_bar:o \module_bar:V \module_bar:v \end{code} \begin{code}[language=latex/latex3] \exp_args:Nc \exp_args:Ne \exp_args:Nx \exp_args:Nf \exp_args:No \exp_args:NV \exp_args:Nv \end{code} Within \verb!functional! package, there are only three variants (\verb!c!, \verb!e!, \verb!V!) are provided, and these variants are defined as functions (\cs{Name}, \cs{Expand}, \cs{Value}, respetively), which are easier to use for normal users. \begin{demohigh} \newcommand\test{uvw} \Name{test} \end{demohigh} \begin{demohigh} \newcommand\test{uvw} \Expand{111\test222} \end{demohigh} \begin{demohigh} \IntSet\lTmpaInt{123} \Value\lTmpaInt \end{demohigh} The most interesting feature is that you can compose these functions. For example, you can easily get the \verb!v! variant of \verb!expl3! by simply composing \cs{Name} and \cs{Value} functions: \begin{demohigh} \IntSet\lTmpaInt{123} \Value{\Name{lTmpaInt}} \end{demohigh} \chapter{Basic Definitions (\texttt{l3basics})} \section{Deļ¬ning Functions and Conditionals} \begin{function}{\PrgNewFunction} \begin{syntax} \cs{PrgNewFunction} \meta{function} \Arg{argument specification} \Arg{code} \end{syntax} Creates protected \meta{function} for evaluating the \meta{code}. Within the \meta{code}, the parameters (\verb|#1|, \verb|#2|, \emph{etc.}) will be replaced by those absorbed by the function. The returned value \emph{must} be passed with \cs{Result} function. The definition is global and an error results if the \meta{function} is already defined.\par The \Arg{argument specification} in a list of letters, where each letter is one of the following argument specifiers (nearly all of them are \texttt{M} or \texttt{m} for functions provided by this package):\par {\centering\begin{tabular}{ll} %\hline \texttt{M} & single-token argument, which will be manipulated first \\ \texttt{m} & multi-token argument, which will be manipulated first \\ \texttt{N} & single-token argument, which will not be manipulated first \\ \texttt{n} & multi-token argument, which will not be manipulated first \\ %\hline \end{tabular}\par} The argument manipulation for argument type \texttt{M} or \texttt{m} is: if the argument starts with a function defined with \cs{PrgNewFunction}, the argument will be evaluated and replaced with the returned value. \end{function} \begin{function}{\PrgNewConditional} \begin{syntax} \cs{PrgNewConditional} \meta{function} \Arg{argument specification} \Arg{code} \end{syntax} Creates protected conditional \meta{function} for evaluating the \meta{code}. The returned value of the \meta{function} \emph{must} be either \verb!\cTrueBool! or \verb!\cFalseBool! and be passed with \cs{Result} function.. The definition is global and an error results if the \meta{function} is already defined. \par Assume the \meta{function} is \verb!\FooIfBar!, then another function \verb!\FooIfBarTF! will be created at the same time. \verb!\FooIfBarTF! function has two extra arguments which are \Arg{true code} and \Arg{false code}.\par \end{function} \begin{function}{\Result} \begin{syntax} \cs{Result} \Arg{tokens} \end{syntax} Appends \meta{tokens} to \verb!\gResultTl!, which holds the returned value of current function. This function is normally used in the \meta{code} of \cs{PrgNewFunction} and \cs{PrgNewConditional}. \end{function} \section{Expanding and Using Tokens} \begin{function}{\Name} \begin{syntax} \cs{Name} \Arg{control sequence name} \end{syntax} Expands the \meta{control sequence name} until only characters remain, then converts this into a control sequence and returns it. The \meta{control sequence name} must consist of character tokens %, %typically a mixture of category code $10$ (space), $11$ (letter) and $12$ (other). when exhaustively expanded.% %\begin{texnote} %Protected macros that appear in a \texttt{c}-type argument are %expanded despite being protected; \cs{exp_not:n} also has no %effect. An internal error occurs if non-characters or active %characters remain after full expansion, as the conversion to a %control sequence is not possible. %\end{texnote} \end{function} \begin{function}{\Value} \begin{syntax} \cs{Value} \meta{variable} \end{syntax} Recovers the content of a \meta{variable} and returns the value. An error is raised if the variable does not exist or if it is invalid. Note that it is the same as \cs{TlUse} for \meta{tl var}, or \cs{IntUse} for \meta{int var}. \end{function} \begin{function}{\Expand} \begin{syntax} \cs{Expand} \Arg{tokens} \end{syntax} Expands the \meta{tokens} exhaustively and returns the result. \end{function} \begin{function}{\ExpNot} \begin{syntax} \cs{ExpNot} \Arg{tokens} \end{syntax} Prevents expansion of the \meta{tokens} inside the argument of \cs{Expand} function. The argument of \cs{ExpNot} \emph{must} be surrounded by braces. %\begin{texnote} %This is the \eTeX{} \tn{unexpanded} primitive. In an %|x|-expanding definition (\cs{cs_new:Npx}), \cs{exp_not:n}~|{#1}| %is equivalent to |##1| rather than to~|#1|, namely it inserts the %two characters |#| and~|1|. In an |e|-type argument %\cs{exp_not:n}~|{#}| is equivalent to |#|, namely it inserts the %character~|#|. %\end{texnote} \end{function} \begin{function}{\ExpValue} \begin{syntax} \cs{ExpValue} \meta{variable} \end{syntax} Recovers the content of the \meta{variable}, then prevents expansion of this material inside the argument of \cs{Expand} function. \end{function} \begin{function}{\UseOne,\GobbleOne} \begin{syntax} \cs{UseOne} \Arg{argument} \cs{GobbleOne} \Arg{argument} \end{syntax} The function \cs{UseOne} absorbs one argument and returns it. %\begin{texnote} %The \cs{UseOne} function is equivalent to \LaTeXe{}'s \tn{@firstofone}. %\end{texnote} \cs{GobbleOne} absorbs one argument and returns nothing. %\begin{texnote} %These are equivalent to \LaTeXe{}'s \tn{@gobble}, \tn{@gobbbletwo}, %\emph{etc.} %\end{texnote} For example \begin{demohigh} \UseOne{abc}\GobbleOne{ijk}\UseOne{xyz} \end{demohigh} \end{function} \begin{function}{\UseGobble,\GobbleUse} \begin{syntax} \cs{UseGobble} \Arg{arg_1} \Arg{arg_2} \cs{GobbleUse} \Arg{arg_1} \Arg{arg_2} \end{syntax} These functions absorb two arguments. The function \cs{UseGobble} discards the second argument, and returns the content of the first argument. \cs{GobbleUse} discards the first argument, and returns the content of the second argument. %\begin{texnote} %These are equivalent to \LaTeXe{}'s \tn{@firstoftwo} and %\tn{@secondoftwo}. %\end{texnote} For example \begin{demohigh} \UseGobble{abc}{uvw}\GobbleUse{abc}{uvw} \end{demohigh} \end{function} \chapter{Control Structures (\texttt{l3prg})} \section{Scratch Variables of Booleans} \begin{variable}{\lTmpaBool,\lTmpbBool,\lTmpcBool,\lTmpiBool,\lTmpjBool,\lTmpkBool} Scratch booleans for local assignment. These are never used by the \verb!functional! package, and so are safe for use with any function. However, they may be overwritten by other code and so should only be used for short-term storage. \end{variable} \begin{variable}{\gTmpaBool,\gTmpbBool,\gTmpcBool,\gTmpiBool,\gTmpjBool,\gTmpkBool} Scratch booleans for global assignment. These are never used by the \verb!functional! package, and so are safe for use with any function. However, they may be overwritten by other code and so should only be used for short-term storage. \end{variable} %\BoolIfTF\cTrueBool{\Result{true}}{\Result{false}} %\BoolIfTF\cFalseBool{\Result{true}}{\Result{false}} \section{Public Functions for Booleans} \begin{function}{\BoolNew} \begin{syntax} \cs{BoolNew} \meta{boolean} \end{syntax} Creates a new \meta{boolean} or raises an error if the name is already taken. The declaration is global. The \meta{boolean} is initially \texttt{false}. \end{function} \begin{function}{\BoolSetTrue} \begin{syntax} \cs{BoolSetTrue} \meta{boolean} \end{syntax} Sets \meta{boolean} logically \texttt{true}. \end{function} \begin{function}{\BoolSetFalse} \begin{syntax} \cs{BoolSetFalse} \meta{boolean} \end{syntax} Sets \meta{boolean} logically \texttt{false}. \end{function} \begin{function}{\BoolIf,\BoolIfTF} \begin{syntax} \cs{BoolIf} \meta{boolean} \cs{BoolIfTF} \meta{boolean} \Arg{true code} \Arg{false code} \end{syntax} Tests the current truth of \meta{boolean}, and continues evaluation based on this result. For example \begin{demohigh} \BoolSetTrue\lTmpaBool \BoolIfTF\lTmpaBool{\Result{True!}}{\Result{False!}} \BoolSetFalse\lTmpaBool \BoolIfTF\lTmpaBool{\Result{True!}}{\Result{False!}} \end{demohigh} \end{function} \chapter{Token Lists (\texttt{l3tl})} \section{Scratch Variables of Token Lists} \begin{variable}{\lTmpaTl,\lTmpbTl,\lTmpcTl,\lTmpiTl,\lTmpjTl,\lTmpkTl} Scratch token lists for local assignment. These are never used by the \verb!functional! package, and so are safe for use with any function. However, they may be overwritten by other code and so should only be used for short-term storage. \end{variable} \begin{variable}{\gTmpaTl,\gTmpbTl,\gTmpcTl,\gTmpiTl,\gTmpjTl,\gTmpkTl} Scratch token lists for global assignment. These are never used by the \verb!functional! package, and so are safe for use with any function. However, they may be overwritten by other code and so should only be used for short-term storage. \end{variable} \section{Public Functions for Token Lists} \begin{function}{\TlNew} \begin{syntax} \cs{TlNew} \meta{tl~var} \end{syntax} Creates a new \meta{tl~var} or raises an error if the name is already taken. The declaration is global. The \meta{tl~var} is initially empty. \end{function} \begin{function}{\TlUse} \begin{syntax} \cs{TlUse} \meta{tl~var} \end{syntax} Recovers the content of a \meta{tl~var} and returns the value. An error is raised if the variable does not exist or if it is invalid. Note that it is possible to use a \meta{tl~var} directly without an accessor function. \end{function} \begin{function}{\TlSet} \begin{syntax} \cs{TlSet} \meta{tl~var} \Arg{tokens} \end{syntax} Sets \meta{tl~var} to contain \meta{tokens}, removing any previous content from the variable. For example \begin{demohigh} \TlSet\lTmpiTl{\IntMathMult{4}{5}} \TlUse\lTmpiTl \end{demohigh} \end{function} \begin{function}{\TlClear} \begin{syntax} \cs{TlClear} \meta{tl~var} \end{syntax} Clears all entries from the \meta{tl~var}. For example \begin{demohigh} \TlSet\lTmpjTl{One} \TlClear\lTmpjTl \TlSet\lTmpjTl{Two} \TlUse\lTmpjTl \end{demohigh} \end{function} \begin{function}{\TlPutLeft} \begin{syntax} \cs{TlPutLeft} \meta{tl~var} \Arg{tokens} \end{syntax} Appends \meta{tokens} to the left side of the current content of \meta{tl~var}. For example \begin{demohigh} \TlSet\lTmpkTl{Functional} \TlPutLeft\lTmpkTl{Hello} \TlUse\lTmpkTl \end{demohigh} \end{function} \begin{function}{\TlPutRight} \begin{syntax} \cs{TlPutRight} \meta{tl~var} \Arg{tokens} \end{syntax} Appends \meta{tokens} to the right side of the current content of \meta{tl~var}. For example \begin{demohigh} \TlSet\lTmpkTl{Functional} \TlPutRight\lTmpkTl{World} \TlUse\lTmpkTl \end{demohigh} \end{function} \begin{function}{\TlIfEmpty,\TlIfEmptyTF} \begin{syntax} \cs{TlIfEmpty} \meta{tl~var} \cs{TlIfEmptyTF} \meta{tl~var} \Arg{true code} \Arg{false code} \end{syntax} Tests if the \meta{token list variable} is entirely empty (\emph{i.e.}~contains no tokens at all). For example \begin{demohigh} \TlSet\lTmpaTl{abc} \TlIfEmptyTF\lTmpaTl{\Result{Empty}}{\Result{NonEmpty}} \TlClear\lTmpaTl \TlIfEmptyTF\lTmpaTl{\Result{Empty}}{\Result{NonEmpty}} \end{demohigh} \end{function} \begin{function}{\TlIfEq,\TlIfEqTF} \begin{syntax} \cs{TlIfEq} \meta{tl~var_1} \meta{tl~var_2} \cs{TlIfEqTF} \meta{tl~var_1} \meta{tl~var_2} \Arg{true code} \Arg{false code} \end{syntax} Compares the content of two \meta{token list variables} and is logically \texttt{true} if the two contain the same list of tokens (\emph{i.e.}~identical in both the list of characters they contain and the category codes of those characters). For example \begin{demohigh} \TlSet\lTmpaTl{abc} \TlSet\lTmpbTl{abc} \TlSet\lTmpcTl{xyz} \TlIfEqTF\lTmpaTl\lTmpbTl{\Result{Yes}}{\Result{No}} \TlIfEqTF\lTmpaTl\lTmpcTl{\Result{Yes}}{\Result{No}} \end{demohigh} %See also \cs{StrIfEqTF} for a comparison that ignores category codes. \end{function} \chapter{Integers (\texttt{l3int})} \section{Scratch Variables of Integers} \begin{variable}{\lTmpaInt,\lTmpbInt,\lTmpcInt,\lTmpiInt,\lTmpjInt,\lTmpkInt} Scratch integer for local assignment. These are never used by the \verb!functional! package, and so are safe for use with any function. However, they may be overwritten by other code and so should only be used for short-term storage. \end{variable} \begin{variable}{\gTmpaInt,\gTmpbInt,\gTmpcInt,\gTmpiInt,\gTmpjInt,\gTmpkInt} Scratch integer for global assignment. These are never used by the \verb!functional! package, and so are safe for use with any function. However, they may be overwritten by other code and so should only be used for short-term storage. \end{variable} \section{Public Functions for Integers} \begin{function}{\IntEval} \begin{syntax} \cs{IntEval} \Arg{integer expression} \end{syntax} Evaluates the \meta{integer expression} and returns the result: for positive results an explicit sequence of decimal digits not starting with~\texttt{0}, for negative results \texttt{-}~followed by such a sequence, and \texttt{0}~for zero. For example \begin{demohigh} \IntEval{(1+4)*(2-3)/5} \end{demohigh} \end{function} \begin{function}{\IntMathAdd} \begin{syntax} \cs{IntMathAdd} \Arg{integer expression_1} \Arg{integer expression_2} \end{syntax} Adds \Arg{integer expression_1} and \Arg{integer expression_2}, and returns the result. For example \begin{demohigh} \IntMathAdd{7}{3} \end{demohigh} \end{function} \begin{function}{\IntMathSub} \begin{syntax} \cs{IntMathSub} \Arg{integer expression_1} \Arg{integer expression_2} \end{syntax} Subtracts \Arg{integer expression_1} from \Arg{integer expression_2}, and returns the result. For example \begin{demohigh} \IntMathSub{7}{3} \end{demohigh} \end{function} \begin{function}{\IntMathMult} \begin{syntax} \cs{IntMathMult} \Arg{integer expression_1} \Arg{integer expression_2} \end{syntax} Multiplies \Arg{integer expression_1} by \Arg{integer expression_2}, and returns the result. For example \begin{demohigh} \IntMathMult{7}{3} \end{demohigh} \end{function} \begin{function}{\IntMathDiv} \begin{syntax} \cs{IntMathDiv} \Arg{integer expression_1} \Arg{integer expression_2} \end{syntax} Divides \Arg{integer expression_1} by \Arg{integer expression_2}, and returns the result. For example \begin{demohigh} \IntMathDiv{7}{3} \end{demohigh} \end{function} \begin{function}{\IntNew} \begin{syntax} \cs{IntNew} \meta{integer} \end{syntax} Creates a new \meta{integer} or raises an error if the name is already taken. The declaration is global. The \meta{integer} is initially equal to $0$. \end{function} \begin{function}{\IntUse} \begin{syntax} \cs{IntUse} \meta{integer} \end{syntax} Recovers the content of an \meta{integer} and returns the value. An error is raised if the variable does not exist or if it is invalid. Can be omitted in places where an \meta{integer} is required (such as in the first and third arguments of \cs{IntCompareTF}).% %\begin{texnote} %\cs{IntUse} is the \TeX{} primitive \tn{the}: this is one of %several \verb!functional! names for this primitive. %\end{texnote} \end{function} \begin{function}{\IntSet} \begin{syntax} \cs{IntSet} \meta{integer} \Arg{integer expression} \end{syntax} Sets \meta{integer} to the value of \meta{integer expression}, which must evaluate to an integer (as described for \cs{IntEval}). For example \begin{demohigh} \IntSet\lTmpaInt{3+5} \IntUse\lTmpaInt \end{demohigh} \end{function} \begin{function}{\IntZero} \begin{syntax} \cs{IntZero} \meta{integer} \end{syntax} Sets \meta{integer} to $0$. For example \begin{demohigh} \IntSet\lTmpaInt{5} \IntZero\lTmpaInt \IntUse\lTmpaInt \end{demohigh} \end{function} \begin{function}{\IntIncr} \begin{syntax} \cs{IntIncr} \meta{integer} \end{syntax} Increases the value stored in \meta{integer} by $1$. For example \begin{demohigh} \IntSet\lTmpaInt{5} \IntIncr\lTmpaInt \IntUse\lTmpaInt \end{demohigh} \end{function} \begin{function}{\IntDecr} \begin{syntax} \cs{IntDecr} \meta{integer} \end{syntax} Decreases the value stored in \meta{integer} by $1$. For example \begin{demohigh} \IntSet\lTmpaInt{5} \IntDecr\lTmpaInt \IntUse\lTmpaInt \end{demohigh} \end{function} \begin{function}{\IntAdd} \begin{syntax} \cs{IntAdd} \meta{integer} \Arg{integer expression} \end{syntax} Adds the result of the \meta{integer expression} to the current content of the \meta{integer}. For example \begin{demohigh} \IntSet\lTmpaInt{5} \IntAdd\lTmpaInt{2} \IntUse\lTmpaInt \end{demohigh} \end{function} \begin{function}{\IntSub} \begin{syntax} \cs{IntSub} \meta{integer} \Arg{integer expression} \end{syntax} Subtracts the result of the \meta{integer expression} from the current content of the \meta{integer}. For example \begin{demohigh} \IntSet\lTmpaInt{5} \IntSub\lTmpaInt{3} \IntUse\lTmpaInt \end{demohigh} \end{function} \begin{function}{\IntStepVariable} \begin{syntax} \cs{IntStepVariable} \Arg{initial value} \Arg{step} \Arg{final value} \meta{tl~var} \Arg{code} \end{syntax} This function first evaluates the \meta{initial value}, \meta{step} and \meta{final value}, all of which should be integer expressions. Then for each \meta{value} from the \meta{initial value} to the \meta{final value} in turn (using \meta{step} between each \meta{value}), the \meta{code} is evaluated, with the \meta{tl~var} defined as the current \meta{value}. Thus the \meta{code} should make use of the \meta{tl~var}. For example \begin{demohigh} \TlClear\lTmpaTl \IntStepVariable{1}{3}{30}\lTmpiTl{ \TlPutRight\lTmpaTl{\Value\lTmpiTl} \TlPutRight\lTmpaTl{ } } \Result{\Value\lTmpaTl} \end{demohigh} \end{function} \begin{function}{\IntCompare,\IntCompareTF} \begin{syntax} \cs{IntCompare} \Arg{intexpr_1} \meta{relation} \Arg{intexpr_2} \cs{IntCompareTF} \Arg{intexpr_1} \meta{relation} \Arg{intexpr_2} \Arg{true code} \Arg{false code} \end{syntax} This function first evaluates each of the \meta{integer expressions} as described for \cs{IntEval}. The two results are then compared using the \meta{relation}:\par {\centering\begin{tabular}{ll} Equal & \texttt{=} \\ Greater than & \texttt{>} \\ Less than & \texttt{<} \\ \end{tabular}\par} For example \begin{demohigh} \IntCompareTF{2}>{1}{\Result{Greater}}{\Result{Less}} \IntCompareTF{2}>{3}{\Result{Greater}}{\Result{Less}} \end{demohigh} \end{function} \chapter{The Source Code} %\CodeHigh{lite} \setlength\parskip{0pt} \dochighinput[language=latex/latex3]{functional.sty} \end{document}