GeneralScope of a Command Declaration

LaTeX specific issues not fitting into one of the other forums of this category.
Post Reply
extal
Posts: 8
Joined: Tue Sep 06, 2011 3:01 pm

Scope of a Command Declaration

Post by extal »

Is the declaration of a command necessarily global to a document or can it be made local to a command (macro) which uses (calls?) it?

Here is a typical scenario schematically

Code: Select all

\newcommand{\firstmacro}[…]%
{%
   …
  \newcommand{\temp}{…}%
  …
  \renewcommand{\temp}{…}%
 …
}%
	\newcommand{\secondmacro}[…]%
{%
  … 
  \newcommand{\temp}{…}%
  …
  \firstmacro{…}%
  …
  \renewcommand{\temp}{…}%
  …
 }%
In both macros \temp is a temporary store for data which gets changed by \renewcommand during run of that macro. A call upon \secondmacro will fail with error message that command \temp is already defined. Using the same command \temp global to both macros might ‘upset the apple cart’ also. Is it possible, if so how, to arrange for command \temp to be local to \firstmacro so as to avoid this conflict of name. In effect one wants to use the command within a macro and then discard it upon completion of the macro. If this is not possible, in a largish document or package with many macros using temporary (pro tem.) commands one soon runs short of useful, convenient and meaningful names.

Recommended reading 2024:

LaTeXguide.org • LaTeX-Cookbook.net • TikZ.org
LaTeX Beginner's Guide LaTeX Cookbook LaTeX TikZ graphics TikZによるLaTeXグラフィックス
User avatar
nlct
Posts: 276
Joined: Thu Nov 06, 2008 11:15 am

Scope of a Command Declaration

Post by nlct »

Command definitions using \newcommand are always local to the current scope. For example:

Code: Select all

\documentclass{article}

\begin{document}

\begin{bfseries}
\newcommand{\temp}{Temp}% local to bfseries environment
\temp
\end{bfseries}

\temp % causes undefined control sequence error

{\newcommand{\temp}{Temp}% local to braces
\temp
}

\temp % causes undefined control sequence error

\bgroup
\newcommand{\temp}{Temp}% defined up to \egroup
\temp
\egroup

\temp % causes undefined control sequence error

\end{document}
Regards
Nicola Talbot
extal
Posts: 8
Joined: Tue Sep 06, 2011 3:01 pm

Scope of a Command Declaration

Post by extal »

Nicola thank you for taking an interest in my question. I note and understand what you write. It is, however, not altogether relevant to my question. At least I think not.

Here is a MWE of the sort of thing I want to be able to avoid happening.

Code: Select all

\documentclass{minimal}%
%
\begin{document}
\newcommand{\firstmacro}%
{%
 \newcommand{\temp}{Hello}%
 \temp\par%
}%
%
\newcommand{\secondmacro}
{%
 \newcommand{\temp}{World}%
 \firstmacro%
 \temp\par%
}%
\secondmacro%
%
\end{document}%
Running this through Latex gives the following (edited) log.

Code: Select all

! LaTeX Error: Command \temp already defined.
               Or name \end... illegal, see p.192 of the manual.

See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
 ...                                              
                                                  
l.16 \secondmacro
                 %
? 

Output written on example.dvi (1 page, 264 bytes).
Strangely if one simply does a carriage return the processing finishes with output
World
World


Thus \secondmacro proceeds by interpreting the \temp in \firstmacro as ‘local’ to \secondmacro and not to \firstmacro. I must say that the reference to p. 192 of the Manual does not clarify matters for me.

[The outcome is interesting if you put a call of \firstmacro in front of that of \secondmacro, by the way. It would seem that the first call determines to which macro \temp is local.]

The two definitions of \temp conflict. What I should wish to be able to do is to use the definition of \temp locally in \firstmicro and, so to speak, kill it off once it has done its job. I want to be able to make the two definitions of \temp local to their respective macros. Does that make better sense? I hope so. The problem seems to lie in the way that Latex interprets the source and that is what I need clarifying I suspect.

Thanks again extal
User avatar
frabjous
Posts: 2064
Joined: Fri Mar 06, 2009 12:20 am

Scope of a Command Declaration

Post by frabjous »

To make a new command local, it needs to be done inside braces, and the braces that are part of the \newcommand syntax itself don't count. So to make the definition of \temp used in \firstmacro get thrown away when it's done, you'd need another set of braces:

Code: Select all

\newcommand{\firstmacro}%
{%
{%
\newcommand{\temp}{Hello}%
\temp\par%
}%
}%
But you're still going to get an error when \firstmacro is called from inside \secondmacro, because the definition of \temp within second macro will be done first, and covers the group where \firstmacro is called, so it won't be new.

I don't understand why you don't just define all the command words at the beginning and then use \renewcommand always when defining commands which redefine commands.

Code: Select all

\documentclass{minimal}%

\newcommand{\temp}{UNDEFINED}

\begin{document}
\newcommand{\firstmacro}%
{%
{%
\renewcommand{\temp}{Hello}%
\temp\par%
}%
}%
%
\newcommand{\secondmacro}
{%
{%
\renewcommand{\temp}{World}%
\firstmacro%
\temp\par%
}%
}%
\secondmacro%
%
\temp
\end{document}%
yields
hwu.png
hwu.png (2.3 KiB) Viewed 17449 times
extal
Posts: 8
Joined: Tue Sep 06, 2011 3:01 pm

Scope of a Command Declaration

Post by extal »

Thank you Frabjous for your response.

You write "To make a new command local …". The point is I don’t want to make the command \firstmacro local but use of the command name \temp to be local to command \firstmacro. In your code, \firstmacro does not run on calling \secondmacro. I want it to run but without conflict of name \temp between the two macros. I want the call of \secondmacro (as it stands with sub-macro \firstmacro and not how it could be easily modified) to output:
Hello
World
.

In the applications I have in mind the command \temp plays the role (in programming language terms) of a declared variable. In all the programming languages I have used, variables declared in a routine (macro) are local to the routine. Thus variables of the same name declared in a routine and a subroutine are permitted without conflict of meaning or role. In consequence there is an economy of variable names. This does not seem to work with LateX commands in macros or, if it does, I don’t know how to make it work. That is the point of my question. Is the moral simply: LateX is not a programming language and cannot in all respects be made to work like one?

Of course one can use a different name for each temporary command arising but then one might get snowed under with names which are essentially of no significance.
josephwright
Site Moderator
Posts: 814
Joined: Tue Jul 01, 2008 2:19 pm

Re: Scope of a Command Declaration

Post by josephwright »

Variable scope in macro languages is not like scope in functional languages. When TeX expands \firstmacro, the fact that \temp was 'inside' \firstmacro is not relevant, as it has been expanded. (TeX replaces the name \firstmacro with the definition of \firstmacro, and then continues processing. The origin of the new tokens is irrelevant.) So if you want variables local to a particular macro, you have to give them different names.
Joseph Wright
extal
Posts: 8
Joined: Tue Sep 06, 2011 3:01 pm

Re: Scope of a Command Declaration

Post by extal »

In the first paragraph of my reply to frabjous everything after the first sentence is based upon a misinterpretation of his post and should therefore be ignored. I apologise to him and others for this careless error. On the other hand frabjois' post did not answer my question fully and in consquence the rest of my post is relevant.

I had prepared a post in correction and clarifying, I hoped, the exact nature of my question. Meantime, however, josephwright’s post has, I think, rather answered my question and rendered unnecessary that proposed posting from me.
Post Reply