10

It's common for packages to accept one- or two-argument macros as transformations of some element, and it's at least common for me for these to be one-offs that don't deserve a permanent name—or at least one in the user's namespace. How can I effect this?

\documentclass{article}
\usepackage{xcolor,empheq}

\begin{document}
\begin{empheq}[box=\colorbox{blue!20}{\hspace{1em}#1\hspace{1em}}]{align*}
  a & = b \\
  a^2 &= b^2
\end{empheq}
\end{document}

Consider the following attempt, heavily influenced by Define a New Macro via a Macro Using xparse Syntax:

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn

\cs_new:Npn \lambda_generate_new_csname: {
  \tl_set:Nn \l_tmpa_tl { random } % I'll figure this out later
  \prg_while:nn { ! \undefined_p \l_tmpa_tl } {
    \tl_set:Nn \l_tmpa_tl { another random }
  }
  \tl_use:N \l_tmpa_tl
}
\cs_new:Npn \lambda_generate_new_cs: {
  \use:c { \lambda_generate_new_csname: }
}

% number of arguments and then transformation
\NewDocumentCommand \LambdaFunction { m m } {
  \lambda_insert_lambda:nn { #1 } { #2 }
}

\cs_new_protected:Npn \lambda_insert_lambda:nn #1 #2 {
  \use:x {
    % expansion unsure
    \exp_not:n { \NewDocumentCommand } \lambda_generate_new_cs: {
      \prg_replicate:nn { #1 } { m }
    }
  } {
    #2
  }
}

\ExplSyntaxOff

\begin{document}

\LambdaFunction{1}{hello, #1!}
  {world}

% > hello, world!

\end{document}

EDIT

Acting on the comments, it would be very interesting to create an expandable LambdaFunction—one that would be more befitting of a functional programming style. I'd consider TeX as, after all, a functional language to a large extent—but does this extend to its very core? I think the answer to this question would say a lot about TeX's programming paradigm.

11
  • Yes, hold up—I posted too early by accident. It's turning out to be a self-answer, at any rate; I haven't ever seen anything like this here before (or anywhere else, for that matter). Jul 4, 2014 at 18:59
  • I'm not sure in what cases this is useful. Is this some sort of on the fly definition and use of a command? (I just say that for what I see in your answer.) By the way, that's something I miss in xparse the ability to use numbers (e.g., 3 instead of mmm :D).
    – Manuel
    Jul 4, 2014 at 19:14
  • 2
    Perhaps *{3}{m} like for tabular
    – egreg
    Jul 4, 2014 at 19:19
  • 1
    I have the feeling this is of limited use, because in TeX a "functional" programming style requires expandability. If you would modify your question to request an expandable \LambdaFunction, I would set a huge bounty :-) But my gut says it is impossible in TeX. Jul 5, 2014 at 6:24
  • 1
    @Manuel This would mean that \the\numexpr\LambdaFunction{2}{#1+#2}{5}{7}\relax would give 12. Jul 5, 2014 at 16:03

4 Answers 4

11

The diversion from a number to a list of m back (internally) to a list #1#2... seems unnecessarily long winded, I'd just do

\documentclass{article}

\newcommand\LambdaFunction[2][0]{%
\let\tmp\relax
\newcommand\tmp[#1]{#2}\tmp}

\begin{document}

\LambdaFunction[1]{hello, #1!}
  {world}

% > hello, world!

\LambdaFunction[2]{Good #1, Mr.~#2}
  {morning}{Sun}

\end{document}
2
  • You were faster.
    – Manuel
    Jul 4, 2014 at 19:29
  • @Manuel a few seconds:-) Jul 4, 2014 at 19:31
11

As an alternative for the xparse solution, this is a \newcommand version.

\documentclass{scrartcl}

\makeatletter
\providecommand\use@command{}
\newcommand\usecommand[2][1]{\renewcommand\use@command[#1]{#2}\use@command}
\makeatother

\begin{document}

\usecommand{hello, #1!}
  {world}

\usecommand[2]{Good #1, Mr.~#2}
  {morning}{Sun}

\end{document}

This is “easier” because xparse doesn't accept numbers (although I would prefer \NewDocumentCommand\definedcommand[3]{definition with #1, #2 and #3} to be accepted :P).

1
  • I always do seem to make things needlessly complicated ;). +1! Jul 4, 2014 at 19:31
6

The task is much simpler if you don't try to create random csnames on every run.

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn

\NewDocumentCommand \LambdaFunction { O{1} m } {
  \lambda_insert_lambda:nn { #1 } { #2 }
}

% #1: Number of arguments
% #2: Transformation
\cs_new_protected:Npn \lambda_insert_lambda:nn #1 #2 {
  \use:x {
    % Put off expanding the declaration until its argument list has
    % been expanded
    \exp_not:n { \DeclareDocumentCommand \__lambda_expression } {
      % Create the argument list
      \prg_replicate:nn { #1 } { m }
    }
  } {
    % Insert the definition
    #2
  }
  % Leave the new function in the input stream
  \__lambda_expression
}

\ExplSyntaxOff

\usepackage{empheq,xcolor}
\begin{document}

\LambdaFunction{hello, #1!}
  {world}

% > hello, world!

\LambdaFunction[2]{Good #1, Mr.~#2}
  {morning}{Sun}

% > Good morning, Mr.~Sun

\begin{empheq}[
  box={\LambdaFunction[1]{%
      \colorbox
      {blue!20}%
      {\hspace{1em}##1\hspace{1em}}%
    }%
  }
  ]{align*}
  a   &= b   \\
  a^2 &= b^2
\end{empheq}
\end{document}
1
  • It may be worth mentioning \cs_generate_from_arg_count:NNnn. Which does what you want within a “programmer level” (which may work also for “user level”, although I don't know if xparse does something more). It's documented in source3.pdf.
    – Manuel
    Jul 7, 2014 at 8:47
2

Lambda ala JavaScript anonymous functions, and python, pick your style and stay within the LaTeX/TeX paradigm it is better.

\documentclass{article}
\usepackage{lipsum}
\usepackage{fp}
% function (callback, args) {
%   return  
%}
\def\func (#1,#2){%
   \ifcsname#1\endcsname%
     \csname#1\endcsname{#2}%
    \else%
     #1,#2  
    \fi%
} 
\begin{document}
\func (textbf, Heading)  
\func (textit, \lipsum[2])
\func (hello, world)

%python
%g = lambda x: x**2

\def\g#1{\FPpow\result{#1}{2}\result}
\g{18}
\end{document}

You must log in to answer this question.

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