I assume most just use the typical commands for writing documents. I think only a small percentage of the user base programs and defines rather sophisticated things at all in TeX/LaTeX.
I think the reasoning for not providing \ProvideCommandCopy
in the LaTeX 2ε-kernel is: \ProvideCommandCopy
would be a possible pitfall. Besides this \ProvideCommandCopy
would be seldom needed. Thus in most scenarios having it in the kernel would imply having something in the kernel that is not used and thus in most scenarios is just ballast. Scenarios where \ProvideCommandCopy
might be needed are at an advanced level where the user should be capable of defining it her-/himself. ;-)
I wrote: "I think the reasoning ... is ...". So it is a guess. Neither am I a member of the LaTeX development team, nor do I have much insight, so I can't really speak for that team and justify team decisions.
I'm speculating on this reasoning because I heard it before with similar questions I asked in the past.
But to me it doesn't matter, because for what I need frequently and therefore define frequently, I have my own macro package and extraction routines that—in case of code sharing—extract only those of my own definitions that are really needed. Thus, creating a new template file that contains only those of my own definitions that are needed in the specific scenario is done with one mouse click. ;-)
Instead of arguing with people who for some reason don't want to see that I need what I need, if I felt I needed a \ProvideCommandCopy
command, I would simply define it myself.
This is done in the example below.
\DeclareCommandCopy
defines the command to be defined in any case, which does not exclude that it is redefined in the process. If redefining takes place, this is done silently, i.e., no error-message or the like is raised.
\RenewCommandCopy
defines the command to be defined in any case, which does not exclude that it is redefined in the process. If it is not already defined, an error message is raised beforehand.
\NewCommandCopy
defines the command to be defined if it is not defined. If it is already defined, an error message is raised and the command is not redefined.
\ProvideCommandCopy
defines the command to be defined if it is not defined. If it is already defined, no error message is raised and the command is not redefined.
The difference between \RenewCommandCopy
/\DeclareCommandCopy
and \NewCommandCopy
/\ProvideCommandCopy
is that the further redefine the command to define if it is already defined, while the latter don't redefine it if it is already defined.
The difference between \NewCommandCopy
/\RenewCommandCopy
and \ProvideCommandCopy
/\DeclareCommandCopy
is that the further raise an error-message if the command to be defined is (not) already defined, while the latter don't raise an error-message.
All(!!!) these \...CommandCopy
-commands do not check whether the command to be copied is defined.
With all these \...CommandCopy
-commands the (re)definition is limited to the local scope where the respective \...CommandCopy
-command is executed.
With all these \...CommandCopy
-commands checking whether the command to be defined is already defined is limited to the local scope where the respective \...CommandCopy
-command is executed.
\makeatletter
\providecommand*\ProvideCommandCopy{%
\declare@commandcopy{\@firstofone}{\@firstoftwo{}}%
}%
\makeatother
\newcommand\CommandToCopy{Copy}
\newcommand\CommandBToCopy{CopyB}
\newcommand\CommandCToCopy{CopyC}
\newcommand\CommandDToCopy{CopyD}
\begingroup
\NewCommandCopy\Copy\CommandToCopy
\message{You should get "\long macro:->Copy" and you get "\meaning\Copy"}
\RenewCommandCopy\Copy\CommandBToCopy
\message{You should get "\long macro:->CopyB" and you get "\meaning\Copy"}
\DeclareCommandCopy\Copy\CommandCToCopy
\message{You should get "\long macro:->CopyC" and you get "\meaning\Copy"}
% \Copy in the current scope is already defined equal to \ComandCToCopy, thus
% \ProvideCommandCopy does not redefine \Copy:
\ProvideCommandCopy\Copy\CommandDToCopy
\message{You should get "\long macro:->CopyC" and you get "\meaning\Copy"}
\endgroup
% Now \Copy is undefined
% \Copy is not defined in the current scope, thus \ProvideCommandCopy within
% the current scope makes \Copy equal to \CommandDToCopy:
\ProvideCommandCopy\Copy\CommandDToCopy
\message{You should get "\long macro:->CopyD" and you get "\meaning\Copy"}
\stop
Console output:
latex-dev test.tex
This is pdfTeX, Version 3.14159265-2.6-1.40.21 (TeX Live 2020) (preloaded format=latex-dev)
restricted \write18 enabled.
entering extended mode
(./test.tex
LaTeX2e <2021-05-01> pre-release-1 (develop 2021-2-27 branch)
L3 programming layer <2021-02-18>
You should get "\long macro:->Copy" and you get "\long macro:->Copy"
You should get "\long macro:->CopyB" and you get "\long macro:->CopyB"
You should get "\long macro:->CopyC" and you get "\long macro:->CopyC"
You should get "\long macro:->CopyC" and you get "\long macro:->CopyC"
You should get "\long macro:->CopyD" and you get "\long macro:->CopyD" )
No pages of output.
Transcript written on test.log.
Actually I don't see a proper reasoning for not having \ProvideCommandCopy
.
(Note that "having \ProvideCommandCopy
" is not the same as "including \ProvideCommandCopy
into the kernel". One can, e.g., have a command/macro/function by providing its definition in the preamble or via some home-brewed macro-package.)
Use-cases could include scenarios where \ProvideCommandCopy
is used for making another command's definition the default in case the command to be defined is not already defined.
In my humble opinion \ProvideCommandCopy
is not more harmful than the other \...CommandCopy
commands as long as its usage goes along with sufficient care.
If you want to copy a command for redefining it later, while preserving the old definition, you—be it defined or not—in any case do not use \ProvideCommandCopy
for the purpose of storing the old definition:
If \ProvideCommandCopy
is not defined you simply can't use it for this purpose.
If \ProvideCommandCopy
is defined you don't use it for this purpose because \ProvideCommandCopy
is the only one of these commands which allows the scenario of silently not storing the old definition. (With \NewCommandCopy
the not-storing is not silent but you get an error-message if storing goes along with overriding something that already exists. Both with \RenewCommandCopy
and with \DeclareCommandCopy
storing takes place in any case while only the further implies raising an error-message if storing goes along with not overriding but defining anew the macro that is to hold the stored definition.)
I don't think the argument of \ProvideCopyCommand
not making much sense due to usually the command to be copied being already defined, is very convincing: The command to be copied is not the command to be defined. The LaTeX-kernel's \providecommand
, and thus probably also a (hypothetical) command \ProvideCopyCommand
, does not check whether the command to be copied is already defined, but does check whether the command to be defined is already defined.
Loosely based on Forrest Gump: And that's all I have to say about that. ;-)
\blackandwhite
use case,\(new|provide)command\blackandwhite{\BooleanTrue}
works. I think\NewCommandCopy
and friends are mostly for redefining, not aliasing things.! Use of \??? doesn't match its definition. <argument> \??? ! LaTeX cmd Error: Invalid argument {\blackandwhite } to \IfBooleanTF{\blackandwhite}{a}{b}
when trying to use\(new|provide)command
\newcommand
and\providecommand
. The point is to wrap\BooleanTrue
in a macro, not copy it.\newcommand{\blackandwhite}{\BooleanTrue}
. I got the error mentioned in the previous comment when trying to use\IfBooleanTF{\blackandwhite}{a}{b}
.\IfBooleanTF
is not as flexible as I think.\expandafter\IfBooleanTF\blackandwhite{a}{b}
or use other ways like\csname xxx\endcsname
and\ifdefined\xxx <true>\else<false>\fi
.