Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I seem to lack understanding the combination of an \edef and the definition of a macro inside another definition. This is probably best shown with an example.

The following MWE (I know it is not really useful so minimal) does not work:

\documentclass{article}
\def\mymacro#1{%
    \def\do##1{##1}%
    #1%
}

\begin{document}
    \edef\savedValue{\mymacro{argument}}%
    savedValue: \savedValue
\end{document}

The error is in the \edef line and states Illegal parameter number in definition of \savedValue.

I thought that the \edef would expand \mymacro{argument}, which first expands \def\do##1{##1} to nothing leading to the output argument, which is then saved into \savedValue. Without the line \def\do##1{##1} this seems to work as explained, but with that line I get the mentioned error.

What is the problem here?

Using xparse's command does work

\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand{\mymacro}{m}{%
    \def\do##1{##1}%
    #1%
}

\begin{document}
    \edef\savedValue{\mymacro{argument}}%
    savedValue: \savedValue
\end{document}

and gives the expected output: result

What is the actual difference to using \def?

share|improve this question

2 Answers 2

up vote 11 down vote accepted

the \def operation is not expandable. In an \edef \def is simply a non-expandable token that stays unchanged. Similarly \mymacro ends up being defined by \protected\def so does not expand in an \edef.

\show\mymacro

shows

> \mymacro=\protected macro:
#1->\def \do ##1{##1}#1.


\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand{\mymacro}{m}{%
    \def\do##1{##1}%
    #1%
}

\begin{document}
    \edef\savedValue{\mymacro{argument}}%
    savedValue: \savedValue
\end{document}

So there are no expandable tokens in the definition of \savedValue so the \edef is equivalent to \def in this case. \show\savedValue shows

   > \savedValue=macro:
->\mymacro {argument}.

Then when \savedValue is expanded it is equivalent to

\def\do#1{#1}argument

If you use \def rather than \protected\def then when you get to the \edef mymacro expands (but \def doesn't so it is the same as

\edef\savedValue{\mymacro{argument}}%

is

\edef\savedValue{\def\do##1{##1}argument}%

then it tries to expand \def but that is not expandable so it is left, then it tries to expand \do so you get the expansion of whatever random definition \do has at this point which happens to be

 \do=\noexpand.

and things go wrong....

share|improve this answer
    
Thanks for the explanations. Is there a standard trick to "remove" the inner \def. Maybe I am thinking to complicated but there seems to be much benefit it that were possible. –  Patrick Häcker Sep 15 '12 at 19:09
    
No once you have an unprotected definition that includes def it is the classic latex "fragile command' and "\edef" is the classic "moving argument". The solution to that is to use \protect to prevent the macro expanding. etex \protected\def as used by the expl3 command and the classic latex \DeclareRobustCommand mechanism both set things up so the macro automatically does not expand in the moving argument to save using \protect explictly. Searching fro "fragile command in a moving argument" on this site or via google will reveal lots of hits with further information:-) –  David Carlisle Sep 15 '12 at 19:37

Another possibility to avoid the problems explained by David Carlisle is to completely avoid the \edef. The trick is to put the saving inside of the "called function". This is a bit similar to C, where a pointer to the allocated memory is given as the first argument to a function and is normally an input-output-parameter. This pattern can probably save a lot of trouble with LaTeX.

\documentclass{article}
\usepackage{etoolbox}
\def\mymacro#1#2{%
    \def\do##1{##1}%
    \csdef{#1}{#2}%
}

\begin{document}
    \mymacro{savedValue}{argument}%
    savedValue: \savedValue
\end{document}
share|improve this answer
    
What's \def\do##1{##1} supposed to do? –  egreg Sep 15 '12 at 22:34
    
Serving as the placeholder for an MWE. In reality it would be the definition of a more complex \do macro, which is used in a \forcsvlist call. –  Patrick Häcker Sep 21 '12 at 20:41

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.