It's a bad idea to do
\countdef\mycount=81
in all flavors of TeX. No discussion allowed.
Plain TeX allocates 25 count registers; it can be checked from any tex.log
(or plain.log
) on your machine. So, if a macro package says
\newcount\foo
TeX will execute internally \countdef\foo=26
, but the actual number should never be used. So, assume you load eplain
and some other macro package; they'll allocate new counters and, maybe, they'll use 56 of them. When you do \countdef\mycount=81
, any subsequent assignment to \mycount
will clobber the value the macro package is assuming the counter holds. Or a macro call will clobber the value you are counting on.
Do \newcount\mycount
(which works also in LaTeX, although it should be used carefully and only in package code) and no such problem will arise.
For your information, the last counter allocated by LaTeX is number 78. Other eleven are allocated by amsmath
. Do you see the problem? Counter 81 (if amsmath
is the first package called) would be \classnum@
, which is a very important internal register for amsmath
. Chaos ensues.
Let's tackle the ‘\newcount
versus \newcounter
’ question. The former is a Plain TeX construct also imported by LaTeX, while the latter is LaTeX specific. With \newcounter{foo}[baz]
one creates a LaTeX counter foo
that's added to the reset list of the counter baz
; an example is
\newcounter{section}[chapter]
that's done by the book
class. Adding the ‘parent’ counter is optional. After a \newcounter{foo}
declaration (with or without an optional argument), LaTeX defines
\c@foo
via \newcount\c@foo
\thefoo
via \newcommand\thefoo{\arabic{foo}}
and also \p@foo
(but describing this would be too technical).
We can use the commands \arabic{foo}
, \alph{foo}
, \Alph{foo}
, \roman{foo}
, \Roman{foo}
and \fnsymbol{foo}
for getting a representation of the counter's current value. Most importantly, we can use
\stepcounter{foo}
\addtocounter{foo}{<number>}
\setcounter{foo}{<number>}
\refstepcounter{foo}
to change the current value. I typed the last command in evidence because it not only steps the counter, but also (locally) defines \current@label
so that the next \label
command will reference this value (more precisely, the current representation of the value).
In order to behave well with the \label
-\ref
mechanism, all the above operations on the counter (using the allocated register named \c@foo
) are global.
In the majority of documents, there's no need to do arithmetic with registers involving multiplications and divisions, so no \multiplycounter
and \dividecounter
macros are defined at the user's level.
In case a package needs to do arithmetic, TeX counters directly defined with \newcount
are available for doing local or global computations with the primitives \advance
, \multiply
and \divide
. Several packages use TeX counters (I use this name as opposed to ‘LaTeX counter’ for those described above).
Because of the inherent global nature of LaTeX counters, it's bad practice operating on them with \multiply
or \divide
: operations on a register should be always local or always global. So \global\multiply\c@foo by 2
should be used in case one really needs to, which is quite rare, in my experience.
Best Answer
Technically using plain tex is not an option, plain is the format produced by inputting the file
plain.tex
into initex and that file is not used in LaTeX at all.It is however true that many of the commands that are defined in plain TeX have commands of the same name defined in LaTeX, and in some of those cases, the definitions are the same.
The commands in the LaTeX format and the standard classes are written in a mixture of "low level" macros and TeX primitives that are more or less analogous to plain tex. At the time they were written (1985-1993) doing anything else would not have been an option, early versions of what is now called xparse were already available at that time but there was not enough memory left to process any real documents, and even test documents took "a while..."
Now it depends. It is of course always more efficient in machine time to use a lower level interface but may be less efficient in human time in development and maintenance. This applies to any computing language not just TeX. For most people most of the time it is better to write code in a high level system, but for some people for some core code it is still effective to write code in processor-specific machine code assembler as a human expert can still do better than a compiler.
If you use low level commands then it might be more efficient but you might break something. There was a question here recently when someone had gone
\def\box{....}
and then wondered why things didn't work. Similarly if your document is also using higher level packages such as expl3 or pgf then if you update the structures those packages need via the documented package interfaces then the structures are far more likely to be internally consistent than if you just poke in some new values with\let
or\def
.On the other hand if, as often happens, your definition is a variation or extension on an existing definition then it makes sense to code it in the same style, for ease of code re-use but also for documentation reasons to make it more easy to see the differences. So it is not possible to give blanket advice that for latex2e all packages should be written in expl3 or whatever.
One other consideration that pushes towards low level code is that you may want the package to work with plain tex (and possibly context or eplain or lollipop or ...) without having to load a definitional layer such as
expl3-generic
orminiltx.tex
. Theltluatex
code for low level luatex support is for example written to work unchanged with plain TeX even though it is distributed as part of the LaTeX base.So if starting a completely new code and you want to provide a natural interface and documentable structure to the code I would use expl3. If you are adapting or modifying existing code or have other real world constraints then it's complicated and the end result is usually a compromise.
The LaTeX kernel itself is very stable and (apart from some changes to address new engines such as luatex) has not really changed since LaTeX2e stabilised in the the 1990's. Since the 2015 release some bug fixes have been added but they are all guarded by conditional code in the source file which allows the
latexrelease
package to wind back the definitions to an earlier release if necessary.