# How can I use one argument as the default value for another?

I'd like to define a command that takes 1, 2 or 3 arguments, and where the 2nd gets the same value as the 1st if it is not defined. I tried

\newcommand\codefrom[3][#1][Matlab]{ ... }


but I get an error saying

! Illegal parameter number in definition of \codefrom.
1
l.57 \newcommand{\codefrom}[3][#1][
Matlab]

Is there any way to accomplish what I want to do?

• Sheesh, three answers in thirty seconds. Nice question, Tomas. Nov 11 '10 at 9:55
• In 2020, you may want to consider pulling the now best answer (?) up to help people landing here from search. Thanks! Jun 17 '20 at 9:04
• I'm reluctant to making such a change without verifying that it actually works - and since I no longer work with TeX (this question is almost 10 years old!) I have no reason (or incentive...) to spend time on this. Isn't that what votes are for? Jun 17 '20 at 13:41


\documentclass[12pt]{report}
\newcommand\storefirst{}
\newcommand\storesecond{}
\newcommand\codefromii[1][Matlab]{\storefirst, \storesecond, #1}
\begin{document}
\codefrom{first}\par
\codefrom{first}[second]\par
\codefrom{first}[second][third]
\end{document}

• Brilliant! This works exactly as I want it to, and is simple enough to understand =) Thanks! Nov 11 '10 at 10:27
• I'm having a problem with this solution. If you type \codefrom{first} Hello you'll get something like "first, first, MatlabHello" (note the missing space). The same with the other examples. Is there a easy solution to this? Otherwise, it is indeed a very nice answer. Nov 26 '16 at 21:34
• @PedroSánchezTerraf Use the following snippet (~ is a non-breaking space): \codefrom{first}~Hello Feb 25 '17 at 11:05

Here is a solution based on xparse:

\documentclass{minimal}

\usepackage{xparse}

\NewDocumentCommand\codefrom{moO{Matlab}}{%
\IfValueTF{#2}{%
\codefromaux{#1}{#2}{#3}%
}{%
\codefromaux{#1}{#1}{#3}%
}%
}
\NewDocumentCommand\codefromaux{mmm}{%
1 = #1, 2 = #2, 3 = #3%
}

\begin{document}

\codefrom{a}\par
\codefrom{a}[b]\par
\codefrom{a}[b][c]

\end{document}

• Very interesting. Could you elaborate a bit on the moO? (I think I can guess what it means, but still some confirmation would be great.) Nov 11 '10 at 13:50
• m = mandatory argument, o = optional argument (square brackets) with no default value, O = optional argument (square brackets) with default value as given. There was recently a question about trying to be able to use the value of one argument directly as the default for a second in xparse: currently, I've not come up with a good way to do it, I'm afraid. Nov 11 '10 at 13:57
• With the latest xparse (not yet on CTAN) one can replace the signature by m O{#1} O{Matlab} to directly have the second argument default to the first (no need for \IfValueTF then (basically Patrick Häcker's answer is now actually supported). Feb 12 '17 at 6:32

The question is old, but as all answers are unnecessary complicated, I want to provide a simpler solution using xparse's possibilities directly.

\documentclass{minimal}
\usepackage{xparse}
\begin{document}
\NewDocumentCommand{\codefrom}{mO{#1}O{Matlab}}{#1, #2, #3}
\end{document}


The result is . The first argument is mandatory, the second and third ones are Optional. The second argument's default value is the first argument, the third argument's default value is Matlab.

• It might be useful for others to know that it appears that only earlier arguments may be referenced this way. For example, I can't get this to work: {O{#2}m}. That tries to insert a literal "#2". Feb 15 '16 at 8:06
• @EvgeniSergeev with the latest xparse (not yet on CTAN) what you describe is supported (in fact, until now we had not explicitly supported the syntax described in the answer). Feb 12 '17 at 6:33

Yes, but you have to "roll your own", so to speak. (You should note that even the sort of optional arguments you see in various core LaTeX macros, like the ones which take two optionals, are not supported by the \newcommand syntax).

The basic mechanism is to use \@ifnextchar to figure out whether there is an optional argument, filling it in if not, and then calling an internal macro which doesn't take an optional argument. In your case the following seems reasonable (note: written on the fly):

\makeatletter
\newcommand{\codefrom}[1]{
\@ifnextchar[
{\codefrom@firstinner{#1}}
{\codefrom@firstinner{#1}[#1]}
}

\def\codefrom@firstinner#1[#2]{
\@ifnextchar[
{\codefrom@secondinner{#1}{#2}}
{\codefrom@secondinner{#1}{#2}[Matlab]}
}

\def\codefrom@secondinner#1#2[#3]{
...
}
\makeatother


As you can see, at each step it checks for a [ and, if it is not present, fills in the argument with the desired default. The last step has all the arguments, and continues the process.

\documentclass{article}
\makeatletter
\newcommand{\codefrom}[1][]{\def\c@defr@m{#1}\c@defrom}
\newcommand{\c@defrom}[2][\c@defr@m]{\message{[\c@defr@m,#1,#2]}}
\makeatother
\begin{document}
\codefrom{a}
\codefrom[a]{b}
\codefrom[a][b]{c}
\end{document}


Edit: An alternative, if it is important for you to access the parameters as #1–#3:

\newcommand{\codefrom}[1][]{\def\c@defr@m{#1}\c@defrom}
\newcommand{\c@defrom}[1][\c@defr@m]
{\expandafter\@codefrom\expandafter{\c@defr@m}{#1}}
\newcommand{\@codefrom}[3]{\message{[#1,#2,#3]}}

• This is great, and almost what I need =) The output now shows [,,a] [a,a,b] [a,b,c], but I'd like it to be [a,a,a] [a,a,b] [a,b,c] (or with some permutation of it). Also, I don't see where the \c@defr@om command comes from, but your MWE compiles on my machine... Nov 11 '10 at 10:19
• What \c@defr@om command? I neither use nor define one. I admit these names are hard to read and keep apart, though. I guess I have been badly influenced by lots of other (La)TeX code that uses the s@me s@rt of n@ming convention. Anyway, having #3 be the default value of #1 and #2 was not in your original specification. I don't have the time right now to come up with a good way to do that, but it is probably most easily achieved in a final processing step – if you're happy with a solution that treats [] the same way as if the optional parameter had been skipped. Nov 11 '10 at 12:09
• +1 for the idea to use repeated \newcommand s. Nov 11 '10 at 16:39