\write16 sends to terminal, \message also does this. Why there are two commands for this and in which cases each one must be used?
2 Answers
Here's in D. Knuth's words
An
‘\immediate\write16’differs from\messagein that\writeprints the text on a line by itself; the results of several\messagecommands might appear on the same line, separated by spaces.
Sample.tex
First page \write16{** one **} \message{** two **} \vfill\eject Second page \immediate\write16{** one W **}\immediate\write16{** two W **} \message{** one M **}\message{** two M **} \bye sample.log shows
(sample.tex ** two ** [1{[....]/texmfs/data/pdftex/config/pdftex.map} ** one ** ] ** one W ** ** two W ** ** one M ** ** two M ** [2] ) Well, for the sake of completeness, another difference is that LuaTeX supports more than 16 streams (it supports 128), therefore unlike \message, \write16 might actually write to some code that allocates that stream.
Some alternatives include
- Lua's
print() \write128, which is also valid in other engines\messagewith ^^J/whatever \newlinechar is at the end- LaTeX's
\typeoutcommand which internally writes to the\@unusedstream.
Remark, morewrites package does not touch stream 16 (it only uses 0-15 and 19...) so 16 is still safe.
Another difference, this one only for academical purpose, is that
\messageexpands tokens as it goes, similar to\csname … \endcsname,\pdfescapestring,\scantokensor\edef.\write16needs to first collect the arguments unexpanded (like\defor\toks0={…}), then fully expand it (with an\endwritetoken put after the}) when it needs to be written.\immediate\write16inherits this behavior as well. (it could do differently, but I assume this is for implementation simplicity)
Consequently, in these cases the behavior is different:
% given this. \outer\def\someoutertoken{} % then... \message{123 \noexpand\someoutertoken} % works %\immediate\write16{123 \noexpand\someoutertoken} % fails \message{\iffalse}{\fi} % works %\immediate\write16{\iffalse}{\fi} % fails, produces a "incomplete iffalse" error message just like "\iffalse\someoutertoken\fi"
\messagelike\immediate\writebut there is an other difference that's each write start a new line and\messagedon't