7

I have read the question and answers about:

What I want to do is similar, but one step further. I would like to define a new command with a variable name, but the new command should have parameters (exactly one in my case).

I tried to use the hash symbol # twice, like this:

\newcommand{\deffun}[1]{\expandafter\newcommand[1]\csname #1\endcsname[1]{#1(##1)}}

But this does not seem to work and I am too confused or ignorant to produce a mwe with nesting of macro definitions with parameters. For an answer, pointing me to the relevant place of the documentation would be enough. It looks like nesting of macro definitions is not a commonly used nor explained feature.

PD: I was almost right, it is like this:

\newcommand{\deffun}[1]{\expandafter\newcommand\csname #1\endcsname[1]{#1(##1)}}
  • What is this \newcommand[1] supposed to do? – jon Sep 10 '15 at 2:17
  • See also: tex.stackexchange.com/a/188478/8528 (shameless self-promotion; but examples are similar). – jon Sep 10 '15 at 2:23
  • Use \def\deffun#1{\expadafter\def\csname#1\endcsname##1{#1(##1)}}. The combination of TeX primitives \csname, \endcsname with the LaTeX macro \newcommand looks funny. And pointer to the documentation? The TeXbook. – wipet Sep 10 '15 at 3:37
  • @jon *facepalm* I'm sorry, I was getting errors and I thought that everything was wrong because (honestly) I had no idea of what I was doing. Turns out that was the only problem to make it work... – Trylks Sep 10 '15 at 5:14
5

There are a number of ways to achieve this:

enter image description here

\documentclass{article}

\def\deffunA#1{\expandafter\def\csname #1\endcsname##1{#1(##1)}}

\newcommand{\deffunB}[1]{\expandafter\newcommand\csname #1\endcsname[1]{#1(##1)}}

\usepackage{etoolbox}
\newcommand{\deffunC}[1]{\csdef{#1}##1{#1(##1)}}

\begin{document}

\deffunA{abc}
$\abc{123}$

\deffunB{ghi}
$\ghi{123}$

\deffunC{jkl}
$\jkl{123}$

\end{document}

\deffunA uses a pure TeX way of defining a macro, while \deffunB is a LaTeX-related way of doing it. \deffunC uses etoolbox which provides a neat interface for defining macros. See section 3.1.1 Macro Definitions of the documentation. In fact, \csdef uses the LaTeX-defined \@namedef... yet another way of achieving what you're after.

  • Comprehensive, exhaustive and precise. Very good answer. – Trylks Sep 10 '15 at 5:17
2

The error is in the wrong \newcommand[1].

Here's a way using expl3:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\deffun}{m}
 {
  \exp_args:Nc \newcommand{#1}[1]{#1(##1)}
 }
\ExplSyntaxOff

\begin{document}

\deffun{foo}

\texttt{\meaning\foo}

\end{document}

The output is

\long macro:#1->foo(#1)

The trick is that \exp_args:Nc jumps over the next token (N), takes the next braced group as an argument and makes a control sequence name out of it (c), and restarts from the jumped over token.

A possible “more proper” way, taking into account that the macro to be defined has just one parameter, would be

\NewDocumentCommand{\deffun}{m}
 {
  \cs_new:cpn {#1} ##1 { #1 ( ##1 ) }
 }

that essentially uses the same idea; note that \cs_new:... refuses to define an already existing command, but the definition is global (contrary to \newcommand).

Several variations are possible.

  • \cs_new:cpn {#1} { #1 ( ##1 ) } should be \cs_new:cpn {#1} ##1 { #1 ( ##1 ) } – clemens Sep 10 '15 at 10:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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