diff options
author | Karl Berry <karl@freefriends.org> | 2022-03-11 23:36:20 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2022-03-11 23:36:20 +0000 |
commit | 1dca4caf34e176c514533a41334db1b3a3395ada (patch) | |
tree | 3e5e27267bd24291218ec3760774e124e8c402ad /Master/texmf-dist/doc/latex/functional | |
parent | b705f82ecca81fe8f6762eba54e7d24fe7d42819 (diff) |
functional
git-svn-id: svn://tug.org/texlive/trunk@62647 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/doc/latex/functional')
-rw-r--r-- | Master/texmf-dist/doc/latex/functional/README.txt | 5 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/functional/functional.pdf | bin | 0 -> 189483 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/latex/functional/functional.tex | 994 |
3 files changed, 999 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/latex/functional/README.txt b/Master/texmf-dist/doc/latex/functional/README.txt new file mode 100644 index 00000000000..fcb1672c0c3 --- /dev/null +++ b/Master/texmf-dist/doc/latex/functional/README.txt @@ -0,0 +1,5 @@ +Functional: LaTeX2 functional interfaces to LaTeX3 programming layer +Copyright : 2022 (c) Jianrui Lyu <tolvjr@163.com> +Repository: https://github.com/lvjr/functional +Repository: https://bitbucket.org/lvjr/functional +License : The LaTeX Project Public License 1.3c diff --git a/Master/texmf-dist/doc/latex/functional/functional.pdf b/Master/texmf-dist/doc/latex/functional/functional.pdf Binary files differnew file mode 100644 index 00000000000..f9f553a0daa --- /dev/null +++ b/Master/texmf-dist/doc/latex/functional/functional.pdf diff --git a/Master/texmf-dist/doc/latex/functional/functional.tex b/Master/texmf-dist/doc/latex/functional/functional.tex new file mode 100644 index 00000000000..18dfa306621 --- /dev/null +++ b/Master/texmf-dist/doc/latex/functional/functional.tex @@ -0,0 +1,994 @@ +% -*- 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} + |