# Conflict between xparse and pstricks: pstricks doesn't believe xparse function is defined

I want to create a pspicture with a variety of parameters which are interdependent. I'm using expl3 for the interface. But I get an error when I try to use \getr

Error: /undefined in \getr
Operand stack:
--nostringval-- 56.9055  0.0


Initially, I had no ideas of where the error was arising from. I've now tried quite a few different ways to replicate the error. Most of them do not fail. The only time I get a fail is when I'm using xparse to define the interface I want.

Here's my MWE:

\documentclass{article}
\usepackage{xparse}
\usepackage{pst-eucl}
\usepackage[margin=1in]{geometry}
\psset{unit=1cm}
\pagestyle{empty}
%%
\ExplSyntaxOn
\cs_generate_variant:Nn \int_eval:n {c}
\NewDocumentCommand{\setr}{ m m }
{
\int_if_exist:cF { g__ace_angle_ #1 _int }
{ \int_new:c { g__ace_angle_ #1 _int }}
\int_gset:cn  { g__ace_angle_ #1 _int }
{\int_eval:n {#2}}
}
\NewDocumentCommand{\getr}{ m }
{
\int_eval:c  { g__ace_angle_ #1 _int }
}
%%
\setr{r1}{-30}
\setr{u1}{\getr{r1}+90}
%%
\newcounter{dummy}\setcounter{dummy}{-30}
\newcommand{\asimplecommand}{-30}
\newcommand{\expliiimacro}{\int_eval:n {\asimplecommand + 60}}
\newcommand{\argdependentmacro}[1]{\ifcase#1\relax-30\or0\or30\or60\fi}
\NewDocumentCommand{\xparsemacroA}{ }{120}
\NewDocumentCommand{\xparsemacroB}{ m }{#1}
\cs_new:Npn \latexiiimacro #1 { #1 }
\ExplSyntaxOff
\setlength{\parindent}{0ex}
\setlength{\parskip}{5ex}
\begin{document}

Works:\hspace*{1in}\texttt{getr(r1)=}$\getr{r1}$\newline
Works:\hspace*{1in}\texttt{getr(u1)=}$\getr{u1}$
\vspace{1cm}

\textbf{It's not a problem with passing a counter-like thingy:}\newline
Works:
\begin{pspicture}[shift=-1](-1,-1)(1,1)
\pstGeonode(0,0){o}(1,0){r}
\pstRotation[RotAngle=\thedummy]{o}{r}[r1]
\pstRotation[RotAngle=-60]{o}{r}[u1]
\end{pspicture}

\textbf{It's not a problem with a command:}\newline
Works:
\begin{pspicture}[shift=-1](-1,-1)(1,1)
\pstGeonode(0,0){o}(1,0){r}
\pstRotation[RotAngle=\asimplecommand]{o}{r}[r1]
\pstRotation[RotAngle=-60]{o}{r}[u1]
\end{pspicture}

\textbf{It's not with a command name whose internals are defined with \texttt{expl3}:}\newline
Works:
\begin{pspicture}[shift=-1](-1,-1)(1,1)
\pstGeonode(0,0){o}(1,0){r}
\pstRotation[RotAngle=\expliiimacro]{o}{r}[r1]
\pstRotation[RotAngle=-60]{o}{r}[u1]
\end{pspicture}

\textbf{It's not a problem with first having to evaluate an argument:}\newline
Works:
\begin{pspicture}[shift=-1](-1,-1)(1,1)
\pstGeonode(0,0){o}(1,0){r}
\pstRotation[RotAngle=\argdependentmacro{2}]{o}{r}[r1]
\pstRotation[RotAngle=-60]{o}{r}[u1]
\end{pspicture}

\textbf{It's not a problem with command name defined in \texttt{latex3}:}\newline
Works:
\begin{pspicture}[shift=-1](-1,-1)(1,1)
\pstGeonode(0,0){o}(1,0){r}
\pstRotation[RotAngle=\latexiiimacro{-120}]{o}{r}[r1]
\pstRotation[RotAngle=-60]{o}{r}[u1]
\end{pspicture}

Fails:
\begin{pspicture}[shift=-1](-1,-1)(1,1)
\pstGeonode(0,0){o}(1,0){r}
\pstRotation[RotAngle=\xparsemacroA]{o}{r}[r1]
\pstRotation[RotAngle=-60]{o}{r}[u1]
\end{pspicture}

Fails:
\begin{pspicture}[shift=-1](-1,-1)(1,1)
\pstGeonode(0,0){o}(1,0){r}
\pstRotation[RotAngle=\xparsemacroB{120}]{o}{r}[r1]
\pstRotation[RotAngle=-60]{o}{r}[u1]
\end{pspicture}

Fails:
\begin{pspicture}(-1,-1)(1,1)
\pstGeonode(0,0){o}(1,0){r}(0,1){u}
\pstRotation[RotAngle=\getr{r1}]{o}{r}[r1]
\pstRotation[RotAngle=-60]{o}{r}[u1]
\end{pspicture}

\end{document}


Producing:

Of all the methods I'm using, only xparse seems to result in the error:

 Error: /undefined in \xparsemacro


That's actually the last place I thought I'd have a problem. Any ideas?

-
Look for \int_case:nnn to be used instead of \ifcase: it's much more flexible and it's expandable as well. –  egreg Jan 27 '13 at 11:58
Instead of \int_if_exist:cF {...} { \int_new:c {...} } I think you can use \int_gzero_new:c {...} which also sets the integer to zero if it is already defined. –  Bruno Le Floch Jan 27 '13 at 18:03

The problem is expandability. When you have

\pstRotation[RotAngle=\SomeMacro{argument}]{o}{r}[r1]


PStricks needs to be able to write the angle into the .dvi file, which is then used further down the line by PostScript. That works fine if \SomeMacro is expandable, as it gets turned into a number. However, if it is a protected (non-expandable) command then this will not work: instead the name of the command is written to the .dvi file, and this is then meaningless to PStricks.

LaTeX3 document commands are protected, as this makes most sense in almost all cases. There is, however, a method for creating expandable document commands

\DeclareExpandableDocumentCommand{\getr}{ m }
{
\int_use:c  { g__ace_angle_ #1 _int }
}


If you use this for all of the 'get' functions, you find that the example then does compile.

-
Wouldn't \int_eval:n { \use:c {...} } be better? The fact that the c variant works is a bit of an artifact, in my opinion. –  egreg Jan 27 '13 at 11:43
@egreg Fixed: it should be \int_use:c as a variant on \int_use:N :-) –  Joseph Wright Jan 27 '13 at 11:47