119

I tend to use \newcommand to define macros for symbols I use often, e.g. \newcommand{\hankel}{H^{(1)}_0}. One inconvenience of this approach is the fact that command names cannot include numbers. What I ideally want is to map something like \H0 to H^{(1)}_0. I imagine this could be done with some macro expansion/snippet package, or one might use \newcommand to define a command that takes a parameter, etc. Before I start experimenting, though -- is there a canonical way of dealing with this problem?

7
  • 2
    I think it is important to know what other commands \H... you're going to need. Is it as in Jan's answer? Then that one's perfect for you. If not, can you add some explanation to your question? Commented Jan 26, 2011 at 12:22
  • Jan's answer works well for many of my use cases; it looks to me like other solutions are cumbersome or have side effects. I often use variables/identifiers with numbers when I compute things, and it is annoying that I cannot reuse these names in LaTeX -- that was my main motivation for asking the question. For the time being I think I'll stick with either not using numbers, or using command parameters as per Jan's suggestion. Commented Jan 27, 2011 at 5:33
  • It would be really interesting for me to see other command with numbers that you'd like to use. Commented Jan 27, 2011 at 10:32
  • 2
    @Hendrik: how about H2O? :) (I am not a chemist, so I actually don't care much about that one.) In truth, almost all my use cases involve subscripts and superscripts -- perhaps used as powers or to indicate matrix elements. So \newcommand parameters will work well. Commented Jan 27, 2011 at 18:26
  • 1
    Related Question: newcommand name cannot include numbers for example \Mycomand123 which actually references a package that allows one to do this. Commented Aug 10, 2012 at 19:38

10 Answers 10

91

Defining commands with parameters would be the way I would deal with this.

\newcommand{\H}[1]{H^{(1)}_{#1}}

defines a command with one parameter. You can then do \H0, \H1, ..., \H9. For more than one digit, you will have to use it as \H{10}.

3
  • 1
    Although this does address the particular example, a problem is that you may want the parameter to be omitted when it has a particular value, e.g. you want to write H2O but if 2 is 1 instead you want to write HO not H1O. Is there a way to achieve that with this approach? Sorry if this should be a different question.
    – kon psych
    Commented May 22, 2017 at 22:27
  • yes, you can check for special case with \if ... commands in the macro definition
    – Max
    Commented Nov 8, 2023 at 23:30
  • It seems you never cite Pàl Erd\H{o}s in your papers. If you had Erdös number 2 as I have (B-)), you'd probably elaborate a little on that point. (Hint: use e.g. \ifmmode {your definition} \else \HH and first "backup" \let\HH=\H
    – Max
    Commented Nov 8, 2023 at 23:41
70

This faq answer discusses this issue, criticises 4 possible ways of using such a macro and ultimately comes to the conclusion don't do that.

New LaTeX users are often suprised that macro definitions containing non-letters, such as

\newcommand{\cul8r}{Goodbye!}

fail to compile. The reason is that the TeX macro language, unlike most programming languages, allows nothing but letters in macro names.

There are a number of techniques for defining a macro with a name like \cul8r. Unfortunately, none of the techniques is particularly good:

  1. Use \csname\endcsname to define and invoke the macro:

    \expandafter\newcommand\csname cul8r\endcsname{Goodbye!}
    I said, ``\csname cul8r\endcsname''.
    
    • Pro: No unexpected side effects
    • Con: So verbose as to be unusable
  2. Define a "special-command generator", and use the resulting commands:

    \newcommand{\DefineRemark}[2]{%
      \expandafter\newcommand\csname rmk-#1\endcsname{#2}%
    }
    \newcommand{\Remark}[1]{\csname rmk-#1\endcsname}
    ...
    \DefineRemark{cul8r}{Goodbye!}
    ...
    \Remark{cul8r}
    
    • Pro: Straightforward to use, not too untidy
    • Con: It's hardly doing what we set out to do (experts will see that you are defining a macro, but others likely won't)
  3. Convince TeX that 8 is a letter:

    \catcode`8 = 11 
    \newcommand{\cul8r}{Goodbye!}
    I said, ``\cul8r''.
    
    • Pro: \cul8r can be used directly
    • Con: Likely to break other uses of 8 (such as numbers or dimensions; so \setlength{\paperwidth}{8in} tells us:
    ! Missing number, treated as zero.
    <to be read again> 
                       8
    

    As a general rule, changing category codes is something to use in extremis, after detailed examination of options. It is conceivable that such drastic action could be useful for you, but most ordinary users are well advised not even to try such a technique.

  4. Define a macro \cul which must always be followed by 8r:

    \def\cul8r{Goodbye!}
    I said, ``\cul8r''.
    
    • Pro: \cul8r can be used directly
    • Con #1: Breaks if \cul is followed by anything other than 8r, with a confusing diagnostic — \cul99 produces:
    ! Use of \cul doesn't match its definition.
    <*> \cul9
             9
    

    (which would confuse someone who hadn't even realised there was a definition of \cul in the document).

    • Con #2: Silently redefines existing \cul, if any; as a result, the technique cannot be used to define both a \cul8r and, say, a \cul123 macro in the same document.

Technique 3 is in fact commonly used — in a limited form — within most LaTeX packages and within LaTeX itself. The convention is to use @ within the names of internal macros to hide them from the user and thereby prevent naming conflicts. To this end, LaTeX automatically treats @ as a letter while processing classes and packages and as a non-letter while processing the user's document. The key to this technique is the separation: internally a non-letter is used for macro names, and the user doesn't see anything of it, while the status remains "frozen" in all the definitions created within the class or package. See \@ and @ in macro names for more information.

Note that analogous use of technique 3 in this example would give us

\begingroup
  \catcode`8 = 11 
  \gdef\cul8r{Goodbye!}
  \gdef\later{\cul8r}
\endgroup
I said, ``\later''.

which works, but rather defeats the object of the exercise. (\later has the "frozen" catcode for "8", even though the value has reverted to normal by the time it's used; note, also, the use of the primitive command \gdef, since \newcommand can't make a macro that's available outside the group.)

Recommendation: Either choose another mechanism (such as \DefineRemark above), or choose another name for your macro, one that contains only ordinary letters. A common approach is to use roman numerals in place of arabic ones:

\newcommand{\culVIIIr}{Goodbye!}

which rather spoils the intent of the joke implicit in the example \cul8r!

1
  • if you only want to use \cul8r and no other \cul then you can also just gobble the next two items: \def\cul#1#2{Goodbye!} . It will always work, and \cul11 will give the same result. Furthermore you could use \if's in the definition to yield different results depending on the two tokens #1 and #2 that follow the \cul command.
    – Max
    Commented Nov 8, 2023 at 23:34
20

In some cases, using Roman rather than Arabic numerals may help: \HI, \HII, \HIII, \HIV. This is also mentioned in Lev Bishop's link and helped in my case.

2
  • 13
    Though \HIV might be a little ambigious. Commented May 15, 2020 at 9:38
  • Roman numerals?! There's a reason we don't generally do arithmetic with Roman numerals.
    – Jason S
    Commented Jun 6, 2023 at 1:13
8

A bad hack (Jan's answer above is much better) :-):

\newcommand{\HH}{\afterassignment\HH@aux\count0=}
\newcommand{\HH@aux}{H^{(1)}_{\the\count0}}

between the usual \makeatletter and \makeatother. If you want to define the commands for various numbers separately, you can do

\makeatletter
\newcommand{\GG}{\afterassignment\GG@aux\count0=}
\newcommand{\GG@aux}{\csname GG\the\count0\endcsname}
\makeatother

and define the various \GG0, \GG1... as

\expandafter\newcommand\csname GG0\endcsname{%
  Definition of GG0.}
\expandafter\newcommand\csname GG1\endcsname{%
  Definition of GG1.}

\GG0 \GG1 \GG2 ...

Note that when we call \GG followed by 2, we don't get any error/warning: it is just ignored. This method could seem good, but it has many drawbacks, failing in unexpected cases. For instance, if \foo is say, 123, then

\GG1\foo...

will be seen as \GG1123, not the expected behaviour.

7

You can use \usepackage{numdef}:

http://web.archive.org/web/20130727172127/http://www.elec.ryukoku.ac.jp/~fujii/pub/ftp/incoming/styles/kth.se/numdef.sty

You can define \num\def\x1{x one} and use it as \x1.

Hope this helps! VIKI

4
  • 1
    I get ! LaTeX Error: File ``numdef.sty'' not found.
    – Viesturs
    Commented Dec 17, 2017 at 14:55
  • @Viesturs you've got to create a numdef.sty file that contains the code in the link provided. Commented May 16, 2019 at 7:49
  • Other link & more information: tex.stackexchange.com/questions/66666/…
    – user202729
    Commented Dec 18, 2021 at 11:05
  • This package does pretty-much the same thing as Bruno's answer above (i.e. grab the next number into a counter and call auxiliary function), but maybe more convenient as a premade package.
    – user202729
    Commented Apr 11, 2022 at 1:22
3

If the command is guaranteed to be followed by exactly one digit, suffix package can be used:

\documentclass{article}
\usepackage{suffix}
\begin{document}

\WithSuffix\def\aa1#1{first (#1)}
\WithSuffix\def\aa2#1{second (#1)}
\aa1{123}
\aa2{456}

\end{document}

maybe someone will write a triedef for the "general" case some time...

1

As under normal category code régime you cannot obtain control-word-tokens like \H0 directly by having TeX read and tokenize .tex-input and as correct invocation of \csname..\endcsname in combination with \expandafter sometimes seems cumbersome, I offer a macro \CsNameToCsToken to create, e.g., the control-word-token \H0 from the character-token-sequence H0.

Syntax:

\CsNameToCsToken⟨stuff not in braces⟩{⟨NameOfCs⟩}

⟨stuff not in braces⟩\NameOfCs

(⟨stuff not in braces⟩ may be empty.)

(Due to \romannumeral-expansion the result is obtained by triggering two expansion-steps, e.g., by having two "hits" with \expandafter.)

With such a macro you are not bound to specific definition commands:

\CsNameToCsToken{foo}\foo  .

\CsNameToCsToken\newcommand{foo}\newcommand\foo  .

\CsNameToCsToken\DeclareRobustCommand{foo}\DeclareRobustCommand\foo  .

\CsNameToCsToken\global\long\outer\def{foo}\global\long\outer\def\foo  .

\CsNameToCsToken\expandafter{foo}\bar\expandafter\foo\bar  .

\CsNameToCsToken\let{foo}=\bar\let\foo=\bar  .

\CsNameToCsToken\CsNameToCsToken\let{foo}={bar}\CsNameToCsToken\let\foo={bar}\let\foo=\bar  .

\CsNameToCsToken\string{foo}\string\foo  .

\CsNameToCsToken\meaning{foo}\meaning\foo  .

\CsNameToCsToken\NewDocumentCommand{foo}...\NewDocumentCommand\foo...  .

\makeatletter
%%===============================================================================
%% End \romannumeral-driven expansion safely:
%%===============================================================================
\@ifdefinable\UD@stopromannumeral{\chardef\UD@stopromannumeral=`\^^00}%
%%===============================================================================
%% Obtain control sequence token from name of control sequence token:
%%===============================================================================
%% \CsNameToCsToken<stuff not in braces>{NameOfCs}
%% ->  <stuff not in braces>\NameOfCs
%% (<stuff not in braces> may be empty.)
\@ifdefinable\CsNameToCsToken{%
  \long\def\CsNameToCsToken#1#{\romannumeral\InnerCsNameToCsToken{#1}}%
}%
\newcommand\InnerCsNameToCsToken[2]{%
  \expandafter\UD@exchange\expandafter{\csname#2\endcsname}{\UD@stopromannumeral#1}%
}%
\newcommand\UD@exchange[2]{#2#1}%
\makeatother

\documentclass{article}

\begin{document}

\begin{verbatim}
Define \H0:
\CsNameToCsToken\newcommand*{H0}{H^{(1)}_0}
\end{verbatim}

\CsNameToCsToken\newcommand*{H0}{H^{(1)}_0}


\begin{verbatim}
Using \H0: 
\[\CsNameToCsToken{H0}\]
\end{verbatim}

\[\CsNameToCsToken{H0}\]

\end{document}

enter image description here


If the most recent development release of LaTeX 2ε, 2022-06-01 Patch level -3, is in use, where \ExpandArgs as a wrapper for calling \exp_args:N..., and \UseName are available, you can do:

% \ExplSyntaxOn
% \cs_new_eq:NN \UseName \use:c
% \cs_new:Npn \ExpandArgs #1 {
%   \cs_if_exist_use:cF { exp_args:N #1 }
%   { \msg_expandable_error:nnn { kernel } { unknown-arg-expansion } {#1} }
% }
% \msg_new:nnn { kernel } { unknown-arg-expansion } { Unknown~arg~expansion~"#1" }
% \ExplSyntaxOff

\documentclass{article}

\begin{document}

\begin{verbatim}
Define \H0:
\ExpandArgs{Nc}\newcommand*{H0}{H^{(1)}_0}
\end{verbatim}

\ExpandArgs{Nc}\newcommand*{H0}{H^{(1)}_0}


\begin{verbatim}
Using \H0: 
\[\UseName{H0}\]
\end{verbatim}

\[\UseName{H0}\]

\end{document}

enter image description here


In your question you use the command \H.

As that is already defined in LaTeX 2ε in the following part of this answer the command \h is used instead.

If you don't need the commands that are trailed by digits to be fully expandable, you can enhance one of the above examples with a mechanism

\DefineCatTwelveDigitsCall{⟨CsName⟩} 

which defines \CsName to gather explicit catcode-12-digits from the token-stream and then to do \csname CsName⟨gathered digits⟩\endcsname if \CsName⟨gathered digits⟩ is defined.

Be aware that at the time of tokenizing things the digits to be gathered are not part of the name of a control sequence token but are tokenized as explicit character tokens on their own; thus spaces following them are not discarded—with \hello space-characters following the characters that form the single control-word-token \hello are discarded as TeX's reading apparatus switches to state S(skipping blanks) after tokenizing a control-word-token. With \h10 tokenizing yields the tokens: \h, 1, 0 followed by a space token: After tokenizing the explicit character token 0 TeX's reading-apparatus is in state M(middle of line) and thus the subsequent space character in the TeX-input is not discarded/skipped but yields insertion of an explicit space-token into the token stream.

\documentclass{article}

\makeatletter
%
% \CheckWhetherExplicitCatTwelveDigit{<Tokens in case subsequent token is explicit catcode-12-digit>}%
%                                    {<Tokens in case subsequent token is not explicit catcode-12-digit>}%
%                                    <subsequent token>
%
%
% Unexpandable check whether subsequent token is explicit catcode-12-digit 
% Via \futurelet and \if the character-code of the next token is checked.
% If the subsequent token's corresponds to the character-code of a digit-token,
% it can safely be grabbed as macro-argument for forking via delimited arguments
% if it is really an explicit catcode-12-digit-character-token.
%
\newcommand\CheckWhetherExplicitCatTwelveDigit[2]{%
  \begingroup
  \edef\@tempb{\unexpanded{#1}}%
  \edef\@tempc{\unexpanded{#2}}%
  \futurelet\@tempa\CheckWhetherDigitMeaning
}%
\newcommand\CheckWhetherDigitMeaning{%
  \if1\noexpand\@tempa\expandafter\@secondoftwo\else\expandafter\@firstofone\fi
  {\if2\noexpand\@tempa\expandafter\@secondoftwo\else\expandafter\@firstofone\fi
    {\if3\noexpand\@tempa\expandafter\@secondoftwo\else\expandafter\@firstofone\fi
      {\if4\noexpand\@tempa\expandafter\@secondoftwo\else\expandafter\@firstofone\fi
        {\if5\noexpand\@tempa\expandafter\@secondoftwo\else\expandafter\@firstofone\fi
          {\if6\noexpand\@tempa\expandafter\@secondoftwo\else\expandafter\@firstofone\fi
            {\if7\noexpand\@tempa\expandafter\@secondoftwo\else\expandafter\@firstofone\fi
              {\if8\noexpand\@tempa\expandafter\@secondoftwo\else\expandafter\@firstofone\fi
                {\if9\noexpand\@tempa\expandafter\@secondoftwo\else\expandafter\@firstofone\fi
                  {\if0\noexpand\@tempa\expandafter\@secondoftwo\else\expandafter\@firstoftwo\fi
                     {\expandafter\endgroup\@tempc}%
                  }%
                }%
              }%
            }%
          }%
        }%
      }%
    }%
  }%
  {\CheckWhetherExplicitDigit}%
}%
\@ifdefinable\ForkExplicitDigit{\long\def\ForkExplicitDigit#11234567890#2#3\relax{#2}}%
\newcommand\CheckWhetherExplicitDigit[1]{%
  \ForkExplicitDigit
  #1234567890{\expandafter\endgroup\@tempb}%
  1#134567890{\expandafter\endgroup\@tempb}%
  12#14567890{\expandafter\endgroup\@tempb}%
  123#1567890{\expandafter\endgroup\@tempb}%
  1234#167890{\expandafter\endgroup\@tempb}%
  12345#17890{\expandafter\endgroup\@tempb}%
  123456#1890{\expandafter\endgroup\@tempb}%
  1234567#190{\expandafter\endgroup\@tempb}%
  12345678#10{\expandafter\endgroup\@tempb}%
  123456789#1{\expandafter\endgroup\@tempb}%
  1234567890{\expandafter\endgroup\@tempc}\relax#1%
}%
%
% \GrabCatTwelveDigitsLoop{<Tokens where to append collected digits nested in curly braces>}%
%                         {<digits collected so far>}%
%                         <digits>
% 
% is an unexpandable loop for gathering explicit catcode-12-digit-characters from the
% token-stream until encountering a non-digit; initially <digits collected so far> is
% to be left empty.
\newcommand\GrabCatTwelveDigitsLoop[2]{%
  \CheckWhetherExplicitCatTwelveDigit{\GrabNextCatTwelveDigit{#1}{#2}}{#1{#2}}%
}%
\newcommand\GrabNextCatTwelveDigit[3]{%
  \GrabCatTwelveDigitsLoop{#1}{#2#3}%
}%
%
% \DefineCatTwelveDigitsCall{CsName} defines \CsName to gather explicit catcode-12-digits
% and to do \csname CsName<gathered digits>\endcsname or raise an
% error-message if \CsName<gathered digits> is undefined/\relax.
%
\newcommand\DefineCatTwelveDigitsCall[1]{%
  \CsNameToCsToken\NewDocumentCommand{#1}{}{%
    \GrabCatTwelveDigitsLoop{\CsDigitName{#1}}{}%
  }%
}%
\newcommand\CsDigitName[2]{%
  \@ifundefined{#1#2}{%
    \@latex@error{Command \@backslashchar#1#2 is undefined}\@eha
  }{\csname#1#2\endcsname}%
}%

%%===============================================================================
%% End \romannumeral-driven expansion safely:
%%===============================================================================
\@ifdefinable\UD@stopromannumeral{\chardef\UD@stopromannumeral=`\^^00}%
%%===============================================================================
%% Obtain control sequence token from name of control sequence token:
%%===============================================================================
%% \CsNameToCsToken<stuff not in braces>{NameOfCs}
%% ->  <stuff not in braces>\NameOfCs
%% (<stuff not in braces> may be empty.)
\@ifdefinable\CsNameToCsToken{%
  \long\def\CsNameToCsToken#1#{\romannumeral\InnerCsNameToCsToken{#1}}%
}%
\newcommand\InnerCsNameToCsToken[2]{%
  \expandafter\UD@exchange\expandafter{\csname#2\endcsname}{\UD@stopromannumeral#1}%
}%
\newcommand\UD@exchange[2]{#2#1}%
\makeatother


\begin{document}

\begin{verbatim}
Define \h as a mechanism for gathering subsequent digits and then doing
\csname h<gathered digits>\endcsname:
\DefineCatTwelveDigitsCall{h}
\end{verbatim}
\DefineCatTwelveDigitsCall{h}


\begin{verbatim}
Define \h10:
\CsNameToCsToken\newcommand*{h10}{H^{(1)}_0}
\end{verbatim}

\CsNameToCsToken\newcommand*{h10}{H^{(1)}_0}


\begin{verbatim}
Using \h10: 
\[\CsNameToCsToken{h10}\]
\end{verbatim}

\[\CsNameToCsToken{h10}\]


\begin{verbatim}
Using \h10: 
\[\h10\]
\end{verbatim}

\[\h10\]


\begin{verbatim}
Define \h20:
\CsNameToCsToken\newcommand*{h20}{H^{(2)}_0}
\end{verbatim}

\CsNameToCsToken\newcommand*{h20}{H^{(2)}_0}


\begin{verbatim}
Using \h20: 
\[\CsNameToCsToken{h20}\]
\end{verbatim}

\[\CsNameToCsToken{h20}\]


\begin{verbatim}
Using \h20: 
\[\h20\]
\end{verbatim}

\[\h20\]

\end{document}

enter image description here

1
1

What we can do in OpTeX:

\def\defprefix#1{%
   \def#1{\csname\csstring#1\immediateassignment\futurelet\next\numread}}
\def\numread{\isxnum\next\iftrue \ea\numreadA\else \ea\endcsname\fi}
\def\numreadA#1{#1\immediateassignment\futurelet\next\numread}
\def\isxnum#1\iftrue{\ifnum 0%
   \ifx#101\fi\ifx#111\fi\ifx#121\fi\ifx#131\fi\ifx#141\fi
   \ifx#151\fi\ifx#161\fi\ifx#171\fi\ifx#181\fi\ifx#191\fi>0
}

\defprefix\x
\sdef{x000}{three zeros}  % defines \x000 {three zeros}
\sdef{x01}{X01}           % defines \x01  {X01}
\sdef{x42}#1{result:(#1)} % defines \x42#1{result(#1)}

\x000,     % expands to three zeors 
\x01,      % expands to X01
\x42 {uff} % expands to result(uff)
\x3        % expands to \relax (like unknown \csname...\encsname)

\bye
0

As a variable name cannot contain numbers or other symbols, the LaTex assignment is clearly incorrect: \setlength{\myT1Col1}{0.2\columnwidth}.

Here is how I propose to handle the problem (when I get around to it):

I will use numbers and underscore in variable names but with a switch \myVar. So the above statement would be written:

\setlength{\myVar{myT1_Col1}}{0.2\columnwidth}.

Next, I will preprocess the LaTex file (using my own code in ‘C’) replacing the numbers and underscores with some suitable alphabetical characters so that the above line becomes

\setlength{\myTOneUSColOne}{0.2\columnwidth}.

The problem still is that if I need to share the LaTex file, I shall have to send the preprocessed version, which does not help make things clear for others.

Wouldn’t it be great it a LaTeX Guru wrote a package to do the preprocessing?

4
  • 1
    This looks to me more like a new question than like an answer to the question.
    – campa
    Commented May 23, 2018 at 14:46
  • 1
    I felt it was related to the problem faced by the OP. I have proposed a possible solution.
    – Raviharry
    Commented May 23, 2018 at 14:50
  • Welcome to TeX.SX! A tip: You can use backticks ` to mark your inline code as I did in my edit.
    – dexteritas
    Commented May 23, 2018 at 15:06
  • With \CsNameToCsToken from my answer you can do \CsNameToCsToken\newlength{myT1Col1} ... \CsNameToCsToken\setlength{myT1Col1}{0.2\columnwidth}. With a LaTeX distribution which is up to date, you can do \ExpandArgs{c}\newlength{myT1Col1} ... \ExpandArgs{c}\setlength{myT1Col1}{0.2\columnwidth}. Commented Jan 2 at 15:06
0

I faced the same problem as I was implementing a simplistic method of getting the long sample name by just entering the sample number from my lab book. For example I wanted \p{25} to return the string PFN/3k--C, which is the sample name that I am mentioning in my thesis.

In the end, I did the following:

\documentclass{article}

% \defineSample{}{} defines other commands that can include numbers
\makeatletter
\newcommand{\defineSample}[2]{%
  \@namedef{sample@#1}{#2}%
}
% \p{} returns the long sample
\newcommand{\p}[1]{%
  \@nameuse{sample@#1}%
}
\makeatother

% Define pairs of sample numbers and long sample names
\defineSample{8}{PFN/4k--A}
\defineSample{17}{PFN/5k/DTd--A}
\defineSample{78}{ITO/2.5k--F}

\begin{document}

Sample 8: \p{8}

Sample 78: \p{78}

\end{document}

In my case, I only needed the \p{} command. But it can be adapted to different letters easily. You just have to change the first argument in \definesamples{}{}:

\defineSample{H8}{PFN/4k--A}
\defineSample{K17}{PFN/5k/DTd--A}
\defineSample{L78}{ITO/2.5k--F}

\begin{document}

Sample 8: \p{H8}

Sample 78: \p{L78}

\end{document}

Writing \p{H8} is not quite as short as writing \H8 but it gets the job done. The solution is also very simple without the need of additional packages and the long variable names can be changed globally very easily.

You must log in to answer this question.

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