Callbacks in TeX [Jun. 20th, 2008|12:37 pm] pozorvlak

In my thesis, there are a lot of places where I write expressions like f 1 x ... x f n or (Σ y1, ... , Σ yn) or something similar. The code to generate this is repetitive. It would be nice to abstract out the general pattern of "list of things indexed from 1 to n, combined using some binary operation". But there's a problem: the indexing can occur anywhere in what might be quite a complicated expression. Rather than handing our "one to n" macro an ordinary TeX expression, we need to hand it an expression with placeholders: that is, we need to hand it a macro. Then our one-to-n macro can invoke the macro we handed it with the arguments "1" and "n" to generate the code we want.



This is quite a common thing to want to do in computer programming. It goes under various names, but probably the most common is "callback". More precisely, the callback is the piece of code accepted by the one-to-n macro, which it then invokes. Callbacks are very generally useful - they're the standard way of writing code for graphical user interfaces (if you've ever written an event handler in VB or an ActionListener in Java, you were writing callbacks), but they're also used for XML processing (via SAX) and all sorts of other things. Ruby's iterators and Smalltalk's if-statements take callbacks. If you've ever used the map function in Perl or Lisp or Python or Haskell, you were writing a callback. But can we write callback-based code in TeX?



Well, yes, as it turns out. One way would be to define our callback as a named macro every time we wanted to invoke \oneton : \def\oneton#1#2{#1{1} #2 \dots #2 #1{n}} \def\xi#1{x_#1} $$ \oneton\xi\otimes $$ but that would quickly get insupportably tedious. We want a way of passing some kind of anonymous lightweight block. One way might be to pass the definition of the callback as an argument, and \oneton can take care of building the temporary macro. Here's the code to do it in plain TeX along with an example of its use: \def\oneton#1#2{{\def\tmp##1{#1} \tmp{1} #2 \dots #2 \tmp{n}}} $$ \oneton{f_#1}{\otimes} = \oneton{\sum_{i=1}^#1 x^i_#1}{\times} = \widehat{\bigoplus}(\oneton{y_#1^#1}{,}) $$ \bye The ## was something I dimly remembered when I wrote this code late last night: looking at my copy of the TeXBook this afternoon, I see that the ## is replaced by a single # during macro-expansion, so the part defining \tmp becomes a perfectly ordinary \def\tmp#1{ whatever you put as the definition } . Note the curly brackets around the expansion of \oneton : that's to ensure that the definition of \tmp isn't visible elsewhere, potentially wreaking havoc.



What if you'd rather use LaTeX's

ewcommand ? I'd thought that

ewcommand could only go in the document prelude, but looking now, I see that I was wrong. So you could, in fact, replace the \def in the body of \oneton with a

ewcommand , like so:

ewcommand\oneton[2]{

ewcommand\tmp[1]{#1} \tmp{1} #2 \dots #2 \tmp{n}} You don't need the ## trick any more, but it's probably still worth knowing.