[latex3-commits] [l3svn] r6938 - Allow expandable commands with long args after short args

noreply at latex-project.org noreply at latex-project.org
Fri Feb 17 05:22:23 CET 2017


Author: bruno
Date: 2017-02-17 05:22:23 +0100 (Fri, 17 Feb 2017)
New Revision: 6938

Modified:
   trunk/l3packages/xparse/testfiles/xparse001.ptex.tlg
   trunk/l3packages/xparse/testfiles/xparse001.tlg
   trunk/l3packages/xparse/testfiles/xparse001.uptex.tlg
   trunk/l3packages/xparse/xparse.dtx
Log:
Allow expandable commands with long args after short args

While grabbing a short argument once one has some \par among earlier
arguments is impossible, the opposite is fine.


Modified: trunk/l3packages/xparse/testfiles/xparse001.ptex.tlg
===================================================================
--- trunk/l3packages/xparse/testfiles/xparse001.ptex.tlg	2017-02-16 20:05:09 UTC (rev 6937)
+++ trunk/l3packages/xparse/testfiles/xparse001.ptex.tlg	2017-02-17 04:22:23 UTC (rev 6938)
@@ -35,8 +35,8 @@
 | You have used \RenewDocumentCommand with a command that was never defined.
 | LaTeX will ignore this entire definition.
 |...............................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {}\foo  \foo code
-?{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {}\foo  \foo  \foo
+code ?{}.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:->First definition.
@@ -51,8 +51,8 @@
 . 
 . Defining command \foo with sig. 'm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {m}\foo  \foo code
-?{\__xparse_expandable_grab_m:w }.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {m}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1->(#1).
@@ -63,8 +63,8 @@
 . 
 . Redefining command \foo with sig. 'mm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mm}\foo  \foo code
-?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mm}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2->(#1)(#2).
@@ -75,8 +75,8 @@
 . 
 . Redefining command \foo with sig. 'mmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmm}\foo  \foo
-code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmm}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
@@ -88,8 +88,8 @@
 . 
 . Redefining command \foo with sig. 'mmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmm}\foo  \foo
-code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmm}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
@@ -101,8 +101,8 @@
 . 
 . Redefining command \foo with sig. 'mmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmm}\foo  \foo
-code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmm}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w }.
 <recently read> }
@@ -115,8 +115,8 @@
 . 
 . Redefining command \foo with sig. 'mmmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmmm}\foo  \foo
-code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmmm}\foo  \foo
+ \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
 <recently read> }
@@ -129,8 +129,8 @@
 . 
 . Redefining command \foo with sig. 'mmmmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmmmm}\foo  \foo
-code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmmmm}\foo 
+\foo  \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w }.
@@ -145,8 +145,8 @@
 . 
 . Redefining command \foo with sig. 'mmmmmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmmmmm}\foo 
-\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmmmmm}\foo 
+\foo  \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
@@ -161,8 +161,8 @@
 . 
 . Redefining command \foo with sig. 'mmmmmmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmmmmmm}\foo 
-\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmmmmmm}\foo 
+\foo  \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
@@ -216,8 +216,8 @@
 . 
 . Defining command \foo with sig. '+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {+m}\foo  \foo code
-{\__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {+m}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1->(#1).
@@ -228,8 +228,9 @@
 . 
 . Redefining command \foo with sig. 'm+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {m+m}\foo  \foo code
-{\__xparse_grab_m_1:w \__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {m+m}\foo  \foo  
+\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m_long:w
+}.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2->(#1)(#2).
@@ -240,8 +241,9 @@
 . 
 . Redefining command \foo with sig. 'mm+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mm+m}\foo  \foo code
-{\__xparse_grab_m_2:w \__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mm+m}\foo  \foo  
+\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3->(#1)(#2)(#3).
@@ -252,8 +254,9 @@
 . 
 . Redefining command \foo with sig. 'mmm+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmm+m}\foo  \foo code
-{\__xparse_grab_m_3:w \__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmm+m}\foo  \foo 
+ \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3#4->(#1)(#2)(#3)(#4).
@@ -264,8 +267,10 @@
 . 
 . Redefining command \foo with sig. 'mmmm+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmm+m}\foo  \foo code
-{\__xparse_grab_m_4:w \__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmm+m}\foo  \foo
+  \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3#4#5->(#1)(#2)(#3)(#4)(#5).
@@ -276,8 +281,10 @@
 . 
 . Redefining command \foo with sig. 'mmmmm+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmm+m}\foo  \foo code
-{\__xparse_grab_m_5:w \__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmm+m}\foo 
+\foo   \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3#4#5#6->(#1)(#2)(#3)(#4)(#5)(#6).
@@ -288,8 +295,11 @@
 . 
 . Redefining command \foo with sig. 'mmmmmm+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmmm+m}\foo  \foo code
-{\__xparse_grab_m_6:w \__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmmm+m}\foo 
+\foo   \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long
@@ -301,8 +311,11 @@
 . 
 . Redefining command \foo with sig. 'mmmmmmm+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmmmm+m}\foo  \foo code
-{\__xparse_grab_m_7:w \__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmmmm+m}\foo 
+\foo   \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long
@@ -314,8 +327,12 @@
 . 
 . Redefining command \foo with sig. 'mmmmmmmm+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmmmmm+m}\foo  \foo code
-{\__xparse_grab_m_8:w \__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmmmmm+m}\foo 
+\foo   \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long
@@ -462,8 +479,9 @@
 . 
 . Defining command \foo with sig. 'lm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {lm}\foo  \foo code
-?{\__xparse_expandable_grab_u:w \foo (arg 1) \__xparse_expandable_grab_m:w }.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {lm}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_u:w \foo (arg 1)
+\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2->(#1)(#2).
@@ -474,9 +492,9 @@
 . 
 . Redefining command \foo with sig. 'mlm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mlm}\foo  \foo
-code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_u:w \foo (arg
-2) \__xparse_expandable_grab_m:w }.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mlm}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_u:w \foo
+(arg 2) \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3->(#1)(#2)(#3).
@@ -487,9 +505,9 @@
 . 
 . Redefining command \foo with sig. 'u{end}u{stop!}' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn
-{u{end}u{stop!}}\foo  \foo code ?{\__xparse_expandable_grab_u:w \foo (arg 1)
-\__xparse_expandable_grab_u:w \foo (arg 2) }.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn
+{u{end}u{stop!}}\foo  \foo  \foo code ?{\__xparse_expandable_grab_u:w \foo
+(arg 1) \__xparse_expandable_grab_u:w \foo (arg 2) }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2->(#1)(#2).
@@ -500,8 +518,8 @@
 . 
 . Redefining command \foo with sig. 'lll' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {lll}\foo  \foo
-code ?{\__xparse_expandable_grab_u:w \foo (arg 1)
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {lll}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_u:w \foo (arg 1)
 \__xparse_expandable_grab_u:w \foo (arg 2) \__xparse_expandable_grab_u:w \foo
 (arg 3) }.
 <recently read> }
@@ -686,7 +704,7 @@
 . 
 . Defining command \foo with sig. 'm' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNNn {m}\foo  \foo code
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {m}\foo  \foo  \foo code
 ?{\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
@@ -698,8 +716,8 @@
 . 
 . Redefining command \foo with sig. '+m' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNNn {+m}\foo  \foo code
-?{\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {+m}\foo  \foo  \foo code
+?{\__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1->(#1).
@@ -710,7 +728,7 @@
 . 
 . Redefining command \foo with sig. 'mmm' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNNn {mmm}\foo  \foo code
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {mmm}\foo  \foo  \foo code
 ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w }.
 <recently read> }
@@ -723,8 +741,8 @@
 . 
 . Redefining command \foo with sig. 'om' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNNn {om}\foo  \foo code \foo
-defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {om}\foo  \foo  \foo code
+\foo defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
 []\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
@@ -736,9 +754,9 @@
 . 
 . Redefining command \foo with sig. '+o+m' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNNn {+o+m}\foo  \foo code \foo
-defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
-[]\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {+o+m}\foo  \foo  \foo code
+\foo defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
+[]\__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1#2->(#1)(#2).
@@ -749,7 +767,7 @@
 . 
 . Redefining command \foo with sig. 'sm' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNNn {sm}\foo  \foo code
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {sm}\foo  \foo  \foo code
 ?{\__xparse_expandable_grab_t:w \__xparse_grabber_*:w
 *\__xparse_expandable_grab_m:w }.
 <recently read> }
@@ -762,8 +780,8 @@
 . 
 . Redefining command \foo with sig. 'osm' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNNn {osm}\foo  \foo code \foo
-defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {osm}\foo  \foo  \foo code
+\foo defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
 []\__xparse_expandable_grab_t:w \__xparse_grabber_*:w
 *\__xparse_expandable_grab_m:w }.
 <recently read> }
@@ -823,8 +841,8 @@
 |'''''''''''''''''''''''''''''''''''''''''''''''
 | This is a coding error.
 | 
-| The arguments for an expandable command must either all be short or all be
-| long. You have tried to mix the two types.
+| The arguments for an expandable command must not involve short arguments
+| after long arguments. You have tried to mix the two types.
 |...............................................
 > \foo=undefined.
 <recently read> }
@@ -837,29 +855,21 @@
 . 
 . Defining command \foo with sig. 'o+m' on line ....
 .................................................
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-!
-! LaTeX error: "xparse/inconsistent-long"
-! 
-! Inconsistent long arguments for expandable command '\foo'.
-! 
-! See the LaTeX3 documentation for further information.
-! 
-! For immediate help type H <return>.
-!...............................................  
-l. ...}
-|'''''''''''''''''''''''''''''''''''''''''''''''
-| This is a coding error.
-| 
-| The arguments for an expandable command must either all be short or all be
-| long. You have tried to mix the two types.
-|...............................................
-> \foo=undefined.
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {o+m}\foo  \foo   \foo code
+\foo defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
+[]\__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
-> \foo code=undefined.
+> \foo code=\long macro:#1#2->(#1)(#2).
 <recently read> }
 l. ...}
+*************************************************
+* LaTeX warning: "xparse/unsupported-let"
+* 
+* The command '\foo' was undefined but not the associated commands '\foo code'
+* and/or '\foo defaults'. Maybe you tried using \let. This may lead to an
+* infinite loop.
+*************************************************
 .................................................
 . LaTeX info: "xparse/define-command"
 . 
@@ -886,7 +896,7 @@
 > \foo=undefined.
 <recently read> }
 l. ...}
-> \foo code=undefined.
+> \foo code=\long macro:#1#2->(#1)(#2).
 <recently read> }
 l. ...}
 ============================================================
@@ -1256,7 +1266,7 @@
 | defined.
 | LaTeX will ignore this entire definition.
 |...............................................
-> \foo=macro:->\__xparse_start_expandable:nNNNn {}\foo  \foo code ?{}.
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {}\foo  \foo  \foo code ?{}.
 <recently read> }
 l. ...}
 > \foo code=\long macro:->First definition.

Modified: trunk/l3packages/xparse/testfiles/xparse001.tlg
===================================================================
--- trunk/l3packages/xparse/testfiles/xparse001.tlg	2017-02-16 20:05:09 UTC (rev 6937)
+++ trunk/l3packages/xparse/testfiles/xparse001.tlg	2017-02-17 04:22:23 UTC (rev 6938)
@@ -35,8 +35,8 @@
 | You have used \RenewDocumentCommand with a command that was never defined.
 | LaTeX will ignore this entire definition.
 |...............................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {}\foo  \foo code
-?{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {}\foo  \foo  \foo
+code ?{}.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:->First definition.
@@ -51,8 +51,8 @@
 . 
 . Defining command \foo with sig. 'm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {m}\foo  \foo code
-?{\__xparse_expandable_grab_m:w }.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {m}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1->(#1).
@@ -63,8 +63,8 @@
 . 
 . Redefining command \foo with sig. 'mm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mm}\foo  \foo code
-?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mm}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2->(#1)(#2).
@@ -75,8 +75,8 @@
 . 
 . Redefining command \foo with sig. 'mmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmm}\foo  \foo
-code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmm}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
@@ -88,8 +88,8 @@
 . 
 . Redefining command \foo with sig. 'mmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmm}\foo  \foo
-code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmm}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
@@ -101,8 +101,8 @@
 . 
 . Redefining command \foo with sig. 'mmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmm}\foo  \foo
-code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmm}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w }.
 <recently read> }
@@ -115,8 +115,8 @@
 . 
 . Redefining command \foo with sig. 'mmmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmmm}\foo  \foo
-code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmmm}\foo  \foo
+ \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
 <recently read> }
@@ -129,8 +129,8 @@
 . 
 . Redefining command \foo with sig. 'mmmmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmmmm}\foo  \foo
-code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmmmm}\foo 
+\foo  \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w }.
@@ -145,8 +145,8 @@
 . 
 . Redefining command \foo with sig. 'mmmmmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmmmmm}\foo 
-\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmmmmm}\foo 
+\foo  \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
@@ -161,8 +161,8 @@
 . 
 . Redefining command \foo with sig. 'mmmmmmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmmmmmm}\foo 
-\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmmmmmm}\foo 
+\foo  \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
@@ -216,8 +216,8 @@
 . 
 . Defining command \foo with sig. '+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {+m}\foo  \foo code
-{\__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {+m}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1->(#1).
@@ -228,8 +228,9 @@
 . 
 . Redefining command \foo with sig. 'm+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {m+m}\foo  \foo code
-{\__xparse_grab_m_1:w \__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {m+m}\foo  \foo  
+\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m_long:w
+}.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2->(#1)(#2).
@@ -240,8 +241,9 @@
 . 
 . Redefining command \foo with sig. 'mm+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mm+m}\foo  \foo code
-{\__xparse_grab_m_2:w \__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mm+m}\foo  \foo  
+\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3->(#1)(#2)(#3).
@@ -252,8 +254,9 @@
 . 
 . Redefining command \foo with sig. 'mmm+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmm+m}\foo  \foo code
-{\__xparse_grab_m_3:w \__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmm+m}\foo  \foo 
+ \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3#4->(#1)(#2)(#3)(#4).
@@ -264,8 +267,10 @@
 . 
 . Redefining command \foo with sig. 'mmmm+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmm+m}\foo  \foo code
-{\__xparse_grab_m_4:w \__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmm+m}\foo  \foo
+  \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3#4#5->(#1)(#2)(#3)(#4)(#5).
@@ -276,8 +281,10 @@
 . 
 . Redefining command \foo with sig. 'mmmmm+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmm+m}\foo  \foo code
-{\__xparse_grab_m_5:w \__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmm+m}\foo 
+\foo   \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3#4#5#6->(#1)(#2)(#3)(#4)(#5)(#6).
@@ -288,8 +295,11 @@
 . 
 . Redefining command \foo with sig. 'mmmmmm+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmmm+m}\foo  \foo code
-{\__xparse_grab_m_6:w \__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmmm+m}\foo 
+\foo   \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long
@@ -301,8 +311,11 @@
 . 
 . Redefining command \foo with sig. 'mmmmmmm+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmmmm+m}\foo  \foo code
-{\__xparse_grab_m_7:w \__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmmmm+m}\foo 
+\foo   \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long
@@ -314,8 +327,12 @@
 . 
 . Redefining command \foo with sig. 'mmmmmmmm+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmmmmm+m}\foo  \foo code
-{\__xparse_grab_m_8:w \__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmmmmm+m}\foo 
+\foo   \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long
@@ -462,8 +479,9 @@
 . 
 . Defining command \foo with sig. 'lm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {lm}\foo  \foo code
-?{\__xparse_expandable_grab_u:w \foo (arg 1) \__xparse_expandable_grab_m:w }.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {lm}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_u:w \foo (arg 1)
+\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2->(#1)(#2).
@@ -474,9 +492,9 @@
 . 
 . Redefining command \foo with sig. 'mlm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mlm}\foo  \foo
-code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_u:w \foo (arg
-2) \__xparse_expandable_grab_m:w }.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mlm}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_u:w \foo
+(arg 2) \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3->(#1)(#2)(#3).
@@ -487,9 +505,9 @@
 . 
 . Redefining command \foo with sig. 'u{end}u{stop!}' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn
-{u{end}u{stop!}}\foo  \foo code ?{\__xparse_expandable_grab_u:w \foo (arg 1)
-\__xparse_expandable_grab_u:w \foo (arg 2) }.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn
+{u{end}u{stop!}}\foo  \foo  \foo code ?{\__xparse_expandable_grab_u:w \foo
+(arg 1) \__xparse_expandable_grab_u:w \foo (arg 2) }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2->(#1)(#2).
@@ -500,8 +518,8 @@
 . 
 . Redefining command \foo with sig. 'lll' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {lll}\foo  \foo
-code ?{\__xparse_expandable_grab_u:w \foo (arg 1)
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {lll}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_u:w \foo (arg 1)
 \__xparse_expandable_grab_u:w \foo (arg 2) \__xparse_expandable_grab_u:w \foo
 (arg 3) }.
 <recently read> }
@@ -686,7 +704,7 @@
 . 
 . Defining command \foo with sig. 'm' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNNn {m}\foo  \foo code
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {m}\foo  \foo  \foo code
 ?{\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
@@ -698,8 +716,8 @@
 . 
 . Redefining command \foo with sig. '+m' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNNn {+m}\foo  \foo code
-?{\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {+m}\foo  \foo  \foo code
+?{\__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1->(#1).
@@ -710,7 +728,7 @@
 . 
 . Redefining command \foo with sig. 'mmm' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNNn {mmm}\foo  \foo code
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {mmm}\foo  \foo  \foo code
 ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w }.
 <recently read> }
@@ -723,8 +741,8 @@
 . 
 . Redefining command \foo with sig. 'om' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNNn {om}\foo  \foo code \foo
-defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {om}\foo  \foo  \foo code
+\foo defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
 []\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
@@ -736,9 +754,9 @@
 . 
 . Redefining command \foo with sig. '+o+m' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNNn {+o+m}\foo  \foo code \foo
-defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
-[]\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {+o+m}\foo  \foo  \foo code
+\foo defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
+[]\__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1#2->(#1)(#2).
@@ -749,7 +767,7 @@
 . 
 . Redefining command \foo with sig. 'sm' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNNn {sm}\foo  \foo code
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {sm}\foo  \foo  \foo code
 ?{\__xparse_expandable_grab_t:w \__xparse_grabber_*:w
 *\__xparse_expandable_grab_m:w }.
 <recently read> }
@@ -762,8 +780,8 @@
 . 
 . Redefining command \foo with sig. 'osm' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNNn {osm}\foo  \foo code \foo
-defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {osm}\foo  \foo  \foo code
+\foo defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
 []\__xparse_expandable_grab_t:w \__xparse_grabber_*:w
 *\__xparse_expandable_grab_m:w }.
 <recently read> }
@@ -823,8 +841,8 @@
 |'''''''''''''''''''''''''''''''''''''''''''''''
 | This is a coding error.
 | 
-| The arguments for an expandable command must either all be short or all be
-| long. You have tried to mix the two types.
+| The arguments for an expandable command must not involve short arguments
+| after long arguments. You have tried to mix the two types.
 |...............................................
 > \foo=undefined.
 <recently read> }
@@ -837,29 +855,21 @@
 . 
 . Defining command \foo with sig. 'o+m' on line ....
 .................................................
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-!
-! LaTeX error: "xparse/inconsistent-long"
-! 
-! Inconsistent long arguments for expandable command '\foo'.
-! 
-! See the LaTeX3 documentation for further information.
-! 
-! For immediate help type H <return>.
-!...............................................  
-l. ...}
-|'''''''''''''''''''''''''''''''''''''''''''''''
-| This is a coding error.
-| 
-| The arguments for an expandable command must either all be short or all be
-| long. You have tried to mix the two types.
-|...............................................
-> \foo=undefined.
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {o+m}\foo  \foo   \foo code
+\foo defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
+[]\__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
-> \foo code=undefined.
+> \foo code=\long macro:#1#2->(#1)(#2).
 <recently read> }
 l. ...}
+*************************************************
+* LaTeX warning: "xparse/unsupported-let"
+* 
+* The command '\foo' was undefined but not the associated commands '\foo code'
+* and/or '\foo defaults'. Maybe you tried using \let. This may lead to an
+* infinite loop.
+*************************************************
 .................................................
 . LaTeX info: "xparse/define-command"
 . 
@@ -886,7 +896,7 @@
 > \foo=undefined.
 <recently read> }
 l. ...}
-> \foo code=undefined.
+> \foo code=\long macro:#1#2->(#1)(#2).
 <recently read> }
 l. ...}
 ============================================================
@@ -1252,7 +1262,7 @@
 | defined.
 | LaTeX will ignore this entire definition.
 |...............................................
-> \foo=macro:->\__xparse_start_expandable:nNNNn {}\foo  \foo code ?{}.
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {}\foo  \foo  \foo code ?{}.
 <recently read> }
 l. ...}
 > \foo code=\long macro:->First definition.

Modified: trunk/l3packages/xparse/testfiles/xparse001.uptex.tlg
===================================================================
--- trunk/l3packages/xparse/testfiles/xparse001.uptex.tlg	2017-02-16 20:05:09 UTC (rev 6937)
+++ trunk/l3packages/xparse/testfiles/xparse001.uptex.tlg	2017-02-17 04:22:23 UTC (rev 6938)
@@ -35,8 +35,8 @@
 | You have used \RenewDocumentCommand with a command that was never defined.
 | LaTeX will ignore this entire definition.
 |...............................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {}\foo  \foo code
-?{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {}\foo  \foo  \foo
+code ?{}.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:->First definition.
@@ -51,8 +51,8 @@
 . 
 . Defining command \foo with sig. 'm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {m}\foo  \foo code
-?{\__xparse_expandable_grab_m:w }.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {m}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1->(#1).
@@ -63,8 +63,8 @@
 . 
 . Redefining command \foo with sig. 'mm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mm}\foo  \foo code
-?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mm}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2->(#1)(#2).
@@ -75,8 +75,8 @@
 . 
 . Redefining command \foo with sig. 'mmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmm}\foo  \foo
-code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmm}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
@@ -88,8 +88,8 @@
 . 
 . Redefining command \foo with sig. 'mmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmm}\foo  \foo
-code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmm}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
@@ -101,8 +101,8 @@
 . 
 . Redefining command \foo with sig. 'mmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmm}\foo  \foo
-code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmm}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w }.
 <recently read> }
@@ -115,8 +115,8 @@
 . 
 . Redefining command \foo with sig. 'mmmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmmm}\foo  \foo
-code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmmm}\foo  \foo
+ \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
 <recently read> }
@@ -129,8 +129,8 @@
 . 
 . Redefining command \foo with sig. 'mmmmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmmmm}\foo  \foo
-code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmmmm}\foo 
+\foo  \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w }.
@@ -145,8 +145,8 @@
 . 
 . Redefining command \foo with sig. 'mmmmmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmmmmm}\foo 
-\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmmmmm}\foo 
+\foo  \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
@@ -161,8 +161,8 @@
 . 
 . Redefining command \foo with sig. 'mmmmmmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmmmmmm}\foo 
-\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmmmmmm}\foo 
+\foo  \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
@@ -216,8 +216,8 @@
 . 
 . Defining command \foo with sig. '+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {+m}\foo  \foo code
-{\__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {+m}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1->(#1).
@@ -228,8 +228,9 @@
 . 
 . Redefining command \foo with sig. 'm+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {m+m}\foo  \foo code
-{\__xparse_grab_m_1:w \__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {m+m}\foo  \foo  
+\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m_long:w
+}.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2->(#1)(#2).
@@ -240,8 +241,9 @@
 . 
 . Redefining command \foo with sig. 'mm+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mm+m}\foo  \foo code
-{\__xparse_grab_m_2:w \__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mm+m}\foo  \foo  
+\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3->(#1)(#2)(#3).
@@ -252,8 +254,9 @@
 . 
 . Redefining command \foo with sig. 'mmm+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmm+m}\foo  \foo code
-{\__xparse_grab_m_3:w \__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmm+m}\foo  \foo 
+ \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3#4->(#1)(#2)(#3)(#4).
@@ -264,8 +267,10 @@
 . 
 . Redefining command \foo with sig. 'mmmm+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmm+m}\foo  \foo code
-{\__xparse_grab_m_4:w \__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmm+m}\foo  \foo
+  \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3#4#5->(#1)(#2)(#3)(#4)(#5).
@@ -276,8 +281,10 @@
 . 
 . Redefining command \foo with sig. 'mmmmm+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmm+m}\foo  \foo code
-{\__xparse_grab_m_5:w \__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmm+m}\foo 
+\foo   \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3#4#5#6->(#1)(#2)(#3)(#4)(#5)(#6).
@@ -288,8 +295,11 @@
 . 
 . Redefining command \foo with sig. 'mmmmmm+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmmm+m}\foo  \foo code
-{\__xparse_grab_m_6:w \__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmmm+m}\foo 
+\foo   \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long
@@ -301,8 +311,11 @@
 . 
 . Redefining command \foo with sig. 'mmmmmmm+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmmmm+m}\foo  \foo code
-{\__xparse_grab_m_7:w \__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmmmm+m}\foo 
+\foo   \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long
@@ -314,8 +327,12 @@
 . 
 . Redefining command \foo with sig. 'mmmmmmmm+m' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmmmmm+m}\foo  \foo code
-{\__xparse_grab_m_8:w \__xparse_grab_m_long:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mmmmmmmm+m}\foo 
+\foo   \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long
@@ -462,8 +479,9 @@
 . 
 . Defining command \foo with sig. 'lm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {lm}\foo  \foo code
-?{\__xparse_expandable_grab_u:w \foo (arg 1) \__xparse_expandable_grab_m:w }.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {lm}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_u:w \foo (arg 1)
+\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2->(#1)(#2).
@@ -474,9 +492,9 @@
 . 
 . Redefining command \foo with sig. 'mlm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mlm}\foo  \foo
-code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_u:w \foo (arg
-2) \__xparse_expandable_grab_m:w }.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {mlm}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_u:w \foo
+(arg 2) \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3->(#1)(#2)(#3).
@@ -487,9 +505,9 @@
 . 
 . Redefining command \foo with sig. 'u{end}u{stop!}' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn
-{u{end}u{stop!}}\foo  \foo code ?{\__xparse_expandable_grab_u:w \foo (arg 1)
-\__xparse_expandable_grab_u:w \foo (arg 2) }.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn
+{u{end}u{stop!}}\foo  \foo  \foo code ?{\__xparse_expandable_grab_u:w \foo
+(arg 1) \__xparse_expandable_grab_u:w \foo (arg 2) }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2->(#1)(#2).
@@ -500,8 +518,8 @@
 . 
 . Redefining command \foo with sig. 'lll' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {lll}\foo  \foo
-code ?{\__xparse_expandable_grab_u:w \foo (arg 1)
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNNn {lll}\foo  \foo 
+\foo code ?{\__xparse_expandable_grab_u:w \foo (arg 1)
 \__xparse_expandable_grab_u:w \foo (arg 2) \__xparse_expandable_grab_u:w \foo
 (arg 3) }.
 <recently read> }
@@ -686,7 +704,7 @@
 . 
 . Defining command \foo with sig. 'm' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNNn {m}\foo  \foo code
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {m}\foo  \foo  \foo code
 ?{\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
@@ -698,8 +716,8 @@
 . 
 . Redefining command \foo with sig. '+m' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNNn {+m}\foo  \foo code
-?{\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {+m}\foo  \foo  \foo code
+?{\__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1->(#1).
@@ -710,7 +728,7 @@
 . 
 . Redefining command \foo with sig. 'mmm' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNNn {mmm}\foo  \foo code
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {mmm}\foo  \foo  \foo code
 ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w }.
 <recently read> }
@@ -723,8 +741,8 @@
 . 
 . Redefining command \foo with sig. 'om' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNNn {om}\foo  \foo code \foo
-defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {om}\foo  \foo  \foo code
+\foo defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
 []\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
@@ -736,9 +754,9 @@
 . 
 . Redefining command \foo with sig. '+o+m' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNNn {+o+m}\foo  \foo code \foo
-defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
-[]\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {+o+m}\foo  \foo  \foo code
+\foo defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
+[]\__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1#2->(#1)(#2).
@@ -749,7 +767,7 @@
 . 
 . Redefining command \foo with sig. 'sm' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNNn {sm}\foo  \foo code
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {sm}\foo  \foo  \foo code
 ?{\__xparse_expandable_grab_t:w \__xparse_grabber_*:w
 *\__xparse_expandable_grab_m:w }.
 <recently read> }
@@ -762,8 +780,8 @@
 . 
 . Redefining command \foo with sig. 'osm' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNNn {osm}\foo  \foo code \foo
-defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {osm}\foo  \foo  \foo code
+\foo defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
 []\__xparse_expandable_grab_t:w \__xparse_grabber_*:w
 *\__xparse_expandable_grab_m:w }.
 <recently read> }
@@ -823,8 +841,8 @@
 |'''''''''''''''''''''''''''''''''''''''''''''''
 | This is a coding error.
 | 
-| The arguments for an expandable command must either all be short or all be
-| long. You have tried to mix the two types.
+| The arguments for an expandable command must not involve short arguments
+| after long arguments. You have tried to mix the two types.
 |...............................................
 > \foo=undefined.
 <recently read> }
@@ -837,29 +855,21 @@
 . 
 . Defining command \foo with sig. 'o+m' on line ....
 .................................................
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-!
-! LaTeX error: "xparse/inconsistent-long"
-! 
-! Inconsistent long arguments for expandable command '\foo'.
-! 
-! See the LaTeX3 documentation for further information.
-! 
-! For immediate help type H <return>.
-!...............................................  
-l. ...}
-|'''''''''''''''''''''''''''''''''''''''''''''''
-| This is a coding error.
-| 
-| The arguments for an expandable command must either all be short or all be
-| long. You have tried to mix the two types.
-|...............................................
-> \foo=undefined.
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {o+m}\foo  \foo   \foo code
+\foo defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
+[]\__xparse_expandable_grab_m_long:w }.
 <recently read> }
 l. ...}
-> \foo code=undefined.
+> \foo code=\long macro:#1#2->(#1)(#2).
 <recently read> }
 l. ...}
+*************************************************
+* LaTeX warning: "xparse/unsupported-let"
+* 
+* The command '\foo' was undefined but not the associated commands '\foo code'
+* and/or '\foo defaults'. Maybe you tried using \let. This may lead to an
+* infinite loop.
+*************************************************
 .................................................
 . LaTeX info: "xparse/define-command"
 . 
@@ -886,7 +896,7 @@
 > \foo=undefined.
 <recently read> }
 l. ...}
-> \foo code=undefined.
+> \foo code=\long macro:#1#2->(#1)(#2).
 <recently read> }
 l. ...}
 ============================================================
@@ -1256,7 +1266,7 @@
 | defined.
 | LaTeX will ignore this entire definition.
 |...............................................
-> \foo=macro:->\__xparse_start_expandable:nNNNn {}\foo  \foo code ?{}.
+> \foo=macro:->\__xparse_start_expandable:nNNNNn {}\foo  \foo  \foo code ?{}.
 <recently read> }
 l. ...}
 > \foo code=\long macro:->First definition.

Modified: trunk/l3packages/xparse/xparse.dtx
===================================================================
--- trunk/l3packages/xparse/xparse.dtx	2017-02-16 20:05:09 UTC (rev 6937)
+++ trunk/l3packages/xparse/xparse.dtx	2017-02-17 04:22:23 UTC (rev 6938)
@@ -704,8 +704,7 @@
 %   \begin{itemize}
 %     \item The last argument (if any are present) must be one of the
 %       mandatory types \texttt{m} or \texttt{r}.
-%     \item All arguments are either short or long: it is not possible
-%       to mix short and long argument types.
+%     \item All short arguments appear before long arguments.
 %     \item The mandatory argument types \texttt{l} and \texttt{u} may
 %       not be used after optional arguments.
 %     \item The optional argument types \texttt{g}
@@ -810,24 +809,6 @@
 %    \end{macrocode}
 % \end{variable}
 %
-% \begin{variable}{\l_@@_all_long_bool}
-%   For expandable commands, all arguments have the same long status, but this
-%   needs to be checked. A flag is therefore needed to track whether arguments
-%   are long at all.
-%    \begin{macrocode}
-\bool_new:N \l_@@_all_long_bool
-%    \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\l_@@_all_long_set_bool}
-%   Whether \cs{l_@@_all_long_bool}'s value is fixed yet or not.  This
-%   is to deal with the case of leading \texttt{t}-type argument, whose
-%   \enquote{long} status should be ignored.
-%    \begin{macrocode}
-\bool_new:N \l_@@_all_long_set_bool
-%    \end{macrocode}
-% \end{variable}
-%
 % \begin{variable}{\l_@@_arg_spec_tl}
 %   Holds the argument specification after normalization of shorthands.
 %    \begin{macrocode}
@@ -935,6 +916,16 @@
 %    \end{macrocode}
 % \end{variable}
 %
+% \begin{variable}{\l_@@_grab_expandably_bool}
+%   When defining a non-expandable command, indicates whether the
+%   arguments can all safely be grabbed by expandable grabbers.  This is
+%   to support abuses of \pkg{xparse} that use protected functions
+%   inside csname constructions.
+%    \begin{macrocode}
+\bool_new:N \l_@@_grab_expandably_bool
+%    \end{macrocode}
+% \end{variable}
+%
 % \begin{variable}{\l_@@_last_delimiters_tl}
 %   Holds the delimiters (first tokens) of all optional arguments since
 %   the previous mandatory argument, to warn about cases where it would
@@ -947,9 +938,7 @@
 % \end{variable}
 %
 % \begin{variable}{\l_@@_long_bool}
-%   Used to indicate that an argument is long: this is used on a per-argument
-%   basis for non-expandable functions, or for the entire set of arguments
-%   when working expandably.
+%   Used to indicate that an argument is long, on a per-argument basis.
 %    \begin{macrocode}
 \bool_new:N \l_@@_long_bool
 %    \end{macrocode}
@@ -1005,13 +994,17 @@
 %    \end{macrocode}
 % \end{variable}
 %
-% \begin{variable}{\l_@@_simple_args_bool}
-%   When defining a non-expandable command, indicates whether the
-%   arguments can all safely be grabbed by expandable grabbers.  This is
-%   to support abuses of \pkg{xparse} that use protected functions
-%   inside csname constructions.  Better name welcome.
+% \begin{variable}{\l_@@_some_long_bool, \l_@@_some_short_bool}
+%   Both of these flags are set while normalizing the argument
+%   specification.  To grab arguments expandably, all short arguments
+%   must appear before long arguments, so as soon as the first long
+%   argument is seen (other than \texttt{t}-type, whose long status is
+%   ignored) the \texttt{some_long} flag is set.  The
+%   \texttt{some_short} flag is used for expandable commands, to know
+%   whether to define a short auxiliary too.
 %    \begin{macrocode}
-\bool_new:N \l_@@_simple_args_bool
+\bool_new:N \l_@@_some_long_bool
+\bool_new:N \l_@@_some_short_bool
 %    \end{macrocode}
 % \end{variable}
 %
@@ -1104,11 +1097,7 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_declare_cmd_code:Nnn
   {
-    \bool_if:nTF
-      {
-        \l_@@_expandable_bool ||
-        \l_@@_simple_args_bool && ! \l_@@_environment_bool
-      }
+    \bool_if:NTF \l_@@_grab_expandably_bool
       { \@@_declare_cmd_code_expandable:Nnn }
       { \@@_declare_cmd_code_aux:Nnn }
    }
@@ -1142,12 +1131,18 @@
   }
 %    \end{macrocode}
 %   Expandable functions and functions whose arguments can be grabbed
-%   expandably call \cs{@@_start_expandable:nNNNn}, which receives the
-%   argument specification, auxiliaries used for grabbing arguments, for
-%   the code, and for default arguments, and finally the signature.
+%   expandably call \cs{@@_start_expandable:nNNNNn}, which receives the
+%   argument specification, four auxiliaries (two for grabbing arguments, one for
+%   the code, and one for default arguments), and finally the signature.
 %   Non-expandable functions that take this branch should nevertheless
 %   be protected, as well as their \texttt{code} function.  They will
 %   only be expanded in contexts such as constructing a csname.
+%   The two grabbers (named after the function with one or two spaces)
+%   are needed when there are both short and long arguments; otherwise
+%   the same grabber is included twice in the definition.  If all
+%   arguments are long or all are short the (only) grabber is defined
+%   correspondingly to be long/short.  Otherwise two grabbers are
+%   defined, one long, one short.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_declare_cmd_code_expandable:Nnn #1#2#3
   {
@@ -1168,19 +1163,32 @@
     \bool_if:NTF \l_@@_expandable_bool
       { \cs_set_nopar:Npx } { \cs_set_protected_nopar:Npx } #1
       {
-        \exp_not:N \@@_start_expandable:nNNNn
+        \exp_not:N \@@_start_expandable:nNNNNn
           { \exp_not:n {#2} }
           \exp_not:c { \l_@@_function_tl \c_space_tl }
+          \exp_not:c
+            {
+              \l_@@_function_tl \c_space_tl
+              \bool_if:NT \l_@@_some_short_bool
+                { \bool_if:NT \l_@@_some_long_bool { \c_space_tl } }
+            }
           \exp_not:c { \l_@@_function_tl \c_space_tl code }
           \bool_if:NTF \l_@@_defaults_bool
             { \exp_not:c { \l_@@_function_tl \c_space_tl defaults } }
             { ? }
           { \exp_not:o \l_@@_signature_tl }
       }
-    \bool_if:NTF \l_@@_all_long_bool
-      { \cs_set:cpx }
+    \bool_if:NTF \l_@@_some_long_bool
+      {
+        \bool_if:NT \l_@@_some_short_bool
+          {
+            \cs_set_nopar:cpx { \l_@@_function_tl \c_space_tl \c_space_tl }
+              ##1##2 { ##1 {##2} }
+          }
+        \cs_set:cpx
+      }
       { \cs_set_nopar:cpx }
-      { \l_@@_function_tl \c_space_tl } ##1##2 { ##1 {##2} }
+          { \l_@@_function_tl \c_space_tl } ##1##2 { ##1 {##2} }
   }
 %    \end{macrocode}
 % \end{macro}
@@ -1421,30 +1429,30 @@
 % \end{macro}
 % \end{macro}
 %
-% \begin{macro}[EXP]{\@@_start_expandable:nNNNn}
-%   This is called for all expandable commands.  |#5| is the signature,
-%   responsible for grabbing arguments.  |#4| is used to determine
-%   default values.  |#3| is the code to run.
-%   |#2|~is a function (named after the command) that grabs a single
-%   argument in the input stream.  The argument specification |#1| is
-%   unused but used by diagnostic functions.
+% \begin{macro}[EXP]{\@@_start_expandable:nNNNNn}
+%   This is called for all expandable commands.  |#6| is the signature,
+%   responsible for grabbing arguments.  |#5| is used to determine
+%   default values (or is |?| if there are none).  |#4| is the code to run.
+%   |#2|~and~|#3| are functions (named after the command) that grab a single
+%   argument in the input stream (|#3|~is~short).  The argument specification |#1| is
+%   only used by diagnostic functions.
 %    \begin{macrocode}
-\cs_new:Npn \@@_start_expandable:nNNNn #1#2#3#4#5
-  { #5 \@@_end_expandable:NNw #4 #3 \q_@@ #2 }
+\cs_new:Npn \@@_start_expandable:nNNNNn #1#2#3#4#5#6
+  { #6 \@@_end_expandable:NNw #5 #4 \q_@@ #2#3 }
 %    \end{macrocode}
 % \end{macro}
 %
 % \begin{macro}[EXP]{\@@_end_expandable:NNw}
 % \begin{macro}[EXP,aux]{\@@_end_expandable_aux:w}
-% \begin{macro}[EXP,aux]{\@@_end_expandable_aux:nNNN}
+% \begin{macro}[EXP,aux]{\@@_end_expandable_aux:nNNNN}
 % \begin{macro}[EXP,aux]{\@@_end_expandable_defaults:nnnNNn}
 % \begin{macro}[EXP,aux]{\@@_end_expandable_defaults:nnw}
 % \begin{macro}[EXP,aux]{\@@_end_expandable_defaults:nw}
 % \begin{macro}[EXP,aux]{\@@_end_expandable_defaults_E:nnw}
 %   Followed by a function |#1| to determine default values (or |?| if
 %   there are no defaults), the code
-%   |#2|, arguments that have been grabbed, then \cs{q_@@} and a generic
-%   grabber.  The idea to find default values is similar to the
+%   |#2|, arguments that have been grabbed, then \cs{q_@@} and two generic
+%   grabbers.  The idea to find default values is similar to the
 %   non-expandable case but we cannot define an auxiliary function, so
 %   at every step in the loop we need to go through all arguments
 %   searching for which ones started out as |-NoValue-| and replacing
@@ -1455,9 +1463,9 @@
 %    \begin{macrocode}
 \cs_new:Npn \@@_end_expandable:NNw #1#2
   { \@@_end_expandable_aux:w #1#2 \prg_do_nothing: }
-\cs_new:Npn \@@_end_expandable_aux:w #1#2#3 \q_@@ #4
-  { \exp_args:No \@@_end_expandable_aux:nNNN {#3} #1 #2 #4 }
-\cs_new:Npn \@@_end_expandable_aux:nNNN #1#2#3#4
+\cs_new:Npn \@@_end_expandable_aux:w #1#2#3 \q_@@
+  { \exp_args:No \@@_end_expandable_aux:nNNNN {#3} #1 #2 }
+\cs_new:Npn \@@_end_expandable_aux:nNNNN #1#2#3#4#5
   {
     \token_if_eq_charcode:NNT ? #2 { \exp_after:wN \use_iv:nnnn }
     \@@_end_expandable_defaults:nnnNNn {#1} { } {#1} #2#3
@@ -1543,12 +1551,22 @@
 % mandatory argument with the same delimiter, as otherwise the optional
 % argument could never be omitted.
 %
-% The fifth is to keep track in \cs{l_@@_simple_args_bool} of whether
-% all arguments are \texttt{m}/\texttt{l}/\texttt{u} type, in which case
-% they can be grabbed expandably.
+% The fifth is to keep track in \cs{l_@@_some_long_bool} and
+% \cs{l_@@_some_short_bool} of whether the command has some long/short
+% arguments.
 %
-% The last is to count mandatory arguments.
+% The sixth is to keep track in \cs{l_@@_grab_expandably_bool} of
+% whether all arguments are \texttt{m}/\texttt{l}/\texttt{u} type and
+% short arguments appear before long ones, in which case they can be
+% grabbed expandably just as safely as they could be grabbed expandably.
+% Regardless of that, arguments of expandable commands will be grabbed
+% expandably and arguments of environments will not (because the list of
+% arguments built by non-expandable grabbing is used to pass them to the
+% end-environment code).
 %
+% The last is to count mandatory arguments, used later to detect which
+% optional arguments are trailing.
+%
 % \begin{macro}{\@@_normalize_arg_spec:n}
 % \begin{macro}{\@@_normalize_arg_spec_loop:n}
 %   Loop through the argument specification, calling an auxiliary
@@ -1565,7 +1583,10 @@
     \int_zero:N \l_@@_current_arg_int
     \tl_clear:N \l_@@_last_delimiters_tl
     \tl_clear:N \l_@@_arg_spec_tl
-    \bool_set_true:N \l_@@_simple_args_bool
+    \bool_set_true:N \l_@@_grab_expandably_bool
+    \bool_set_false:N \l_@@_long_bool
+    \bool_set_false:N \l_@@_some_long_bool
+    \bool_set_false:N \l_@@_some_short_bool
     \@@_normalize_arg_spec_loop:n #1
       \q_recursion_tail \q_recursion_tail \q_recursion_tail \q_recursion_stop
     \int_compare:nNnT \l_@@_current_arg_int > 9
@@ -1583,6 +1604,10 @@
             \@@_bad_def:wn
           }
       }
+    \bool_if:NT \l_@@_expandable_bool
+      { \bool_set_true:N \l_@@_grab_expandably_bool }
+    \bool_if:NT \l_@@_environment_bool
+      { \bool_set_false:N \l_@@_grab_expandably_bool }
   }
 \cs_new_protected:Npn \@@_normalize_arg_spec_loop:n #1
   {
@@ -1669,15 +1694,15 @@
       }
     \tl_put_right:Nn \l_@@_arg_spec_tl { > {#1} }
     \int_decr:N \l_@@_current_arg_int
-    \bool_set_false:N \l_@@_simple_args_bool
+    \bool_set_false:N \l_@@_grab_expandably_bool
     \@@_normalize_arg_spec_loop:n {#2}
   }
 \cs_new_protected:cpn { @@_normalize_type_+:w } #1
   {
     \quark_if_recursion_tail_stop_do:nn {#1} { \@@_bad_arg_spec:wn }
     \tl_put_right:Nn \l_@@_arg_spec_tl { + }
+    \bool_set_true:N \l_@@_long_bool
     \int_decr:N \l_@@_current_arg_int
-    \bool_set_false:N \l_@@_simple_args_bool
     \@@_normalize_arg_spec_loop:n {#1}
   }
 %    \end{macrocode}
@@ -1706,9 +1731,9 @@
     \@@_single_token_check:n {#1}
     \@@_single_token_check:n {#2}
     \quark_if_recursion_tail_stop_do:nn {#3} { \@@_bad_arg_spec:wn }
-    \tl_put_right:Nn \l_@@_arg_spec_tl { D #1 #2 {#3} }
+    \@@_add_arg_spec:n { D #1 #2 {#3} }
     \tl_put_right:Nn \l_@@_last_delimiters_tl {#1}
-    \bool_set_false:N \l_@@_simple_args_bool
+    \bool_set_false:N \l_@@_grab_expandably_bool
     \@@_normalize_arg_spec_loop:n
   }
 \cs_new_protected:Npn \@@_normalize_type_E:w #1#2
@@ -1719,9 +1744,9 @@
     \@@_normalize_E_unique_check:w #1 \q_nil \q_stop
     \int_compare:nNnT { \tl_count:n {#2} } > { \tl_count:n {#1} }
       { \@@_bad_arg_spec:wn }
-    \tl_put_right:Nn \l_@@_arg_spec_tl { E {#1} {#2} }
+    \@@_add_arg_spec:n { E {#1} {#2} }
     \tl_put_right:Nn \l_@@_last_delimiters_tl {#1}
-    \bool_set_false:N \l_@@_simple_args_bool
+    \bool_set_false:N \l_@@_grab_expandably_bool
     \@@_normalize_arg_spec_loop:n
   }
 \cs_new_protected:Npn \@@_normalize_E_unique_check:w #1#2 \q_stop
@@ -1736,9 +1761,8 @@
   {
     \quark_if_recursion_tail_stop_do:nn {#1} { \@@_bad_arg_spec:wn }
     \@@_normalize_check_gv:N G
-    \tl_put_right:Nn \l_@@_arg_spec_tl { G {#1} }
+    \@@_add_arg_spec:n { G {#1} }
     \tl_put_right:Nn \l_@@_last_delimiters_tl { { } }
-    \bool_set_false:N \l_@@_simple_args_bool
     \@@_normalize_arg_spec_loop:n
   }
 \cs_new_protected:Npn \@@_normalize_type_t:w #1
@@ -1747,7 +1771,8 @@
     \quark_if_recursion_tail_stop_do:Nn #1 { \@@_bad_arg_spec:wn }
     \tl_put_right:Nn \l_@@_arg_spec_tl { t #1 }
     \tl_put_right:Nn \l_@@_last_delimiters_tl {#1}
-    \bool_set_false:N \l_@@_simple_args_bool
+    \bool_set_false:N \l_@@_grab_expandably_bool
+    \bool_set_false:N \l_@@_long_bool
     \@@_normalize_arg_spec_loop:n
   }
 %    \end{macrocode}
@@ -1774,7 +1799,7 @@
 \cs_new_protected:Npn \@@_normalize_type_l:w
   {
     \@@_normalize_check_lu:N l
-    \tl_put_right:Nn \l_@@_arg_spec_tl { l }
+    \@@_add_arg_spec:n { l }
     \int_incr:N \l_@@_mandatory_args_int
     \tl_clear:N \l_@@_last_delimiters_tl
     \@@_normalize_arg_spec_loop:n
@@ -1782,7 +1807,7 @@
 \cs_new_protected:Npn \@@_normalize_type_m:w
   {
     \@@_delimiter_check:nnn { } { m } { \iow_char:N \{ }
-    \tl_put_right:Nn \l_@@_arg_spec_tl { m }
+    \@@_add_arg_spec:n { m }
     \int_incr:N \l_@@_mandatory_args_int
     \tl_clear:N \l_@@_last_delimiters_tl
     \@@_normalize_arg_spec_loop:n
@@ -1793,17 +1818,17 @@
     \@@_single_token_check:n {#2}
     \quark_if_recursion_tail_stop_do:nn {#3} { \@@_bad_arg_spec:wn }
     \@@_delimiter_check:nnn {#1} { R/r } { \tl_to_str:n {#1} }
-    \tl_put_right:Nn \l_@@_arg_spec_tl { R #1 #2 {#3} }
+    \@@_add_arg_spec:n { R #1 #2 {#3} }
     \int_incr:N \l_@@_mandatory_args_int
     \tl_clear:N \l_@@_last_delimiters_tl
-    \bool_set_false:N \l_@@_simple_args_bool
+    \bool_set_false:N \l_@@_grab_expandably_bool
     \@@_normalize_arg_spec_loop:n
   }
 \cs_new_protected:Npn \@@_normalize_type_u:w #1
   {
     \quark_if_recursion_tail_stop_do:nn {#1} { \@@_bad_arg_spec:wn }
     \@@_normalize_check_lu:N u
-    \tl_put_right:Nn \l_@@_arg_spec_tl { u {#1} }
+    \@@_add_arg_spec:n { u {#1} }
     \int_incr:N \l_@@_mandatory_args_int
     \tl_clear:N \l_@@_last_delimiters_tl
     \@@_normalize_arg_spec_loop:n
@@ -1811,10 +1836,9 @@
 \cs_new_protected:Npn \@@_normalize_type_v:w
   {
     \@@_normalize_check_gv:N v
-    \tl_put_right:Nn \l_@@_arg_spec_tl { v }
+    \@@_add_arg_spec:n { v }
     \int_incr:N \l_@@_mandatory_args_int
     \tl_clear:N \l_@@_last_delimiters_tl
-    \bool_set_false:N \l_@@_simple_args_bool
     \@@_normalize_arg_spec_loop:n
   }
 %    \end{macrocode}
@@ -1849,6 +1873,7 @@
           { \iow_char:N \\ \l_@@_function_tl } { \tl_to_str:n {#1} }
         \@@_bad_def:wn
       }
+    \bool_set_false:N \l_@@_grab_expandably_bool
   }
 \cs_new_protected:Npn \@@_normalize_check_lu:N #1
   {
@@ -1887,8 +1912,8 @@
 % \end{macro}
 %
 % \begin{macro}{\@@_bad_arg_spec:wn, \@@_bad_def:wn}
-%   If the argument specification is wrong, this provides an escape from the entire
-%   definition process.
+%   If the argument specification is wrong, this provides an escape from
+%   the entire definition process.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_bad_arg_spec:wn #1 \@@_break_point:n #2
   {
@@ -1899,6 +1924,38 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}{\@@_add_arg_spec:n}
+%   When adding an argument to the argument specification, set the
+%   \texttt{some_long} or \texttt{some_short} booleans as appropriate
+%   and clear the boolean keeping track of whether the argument is long.
+%   Before that, test for a short argument following some long
+%   arguments: this is forbidden for expandable commands and prevents
+%   grabbing arguments expandably.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_add_arg_spec:n #1
+  {
+    \bool_if:NF \l_@@_long_bool
+      {
+        \bool_if:NT \l_@@_some_long_bool
+          {
+            \bool_if:NT \l_@@_expandable_bool
+              {
+                \__msg_kernel_error:nnx { xparse } { inconsistent-long }
+                  { \iow_char:N \\ \l_@@_function_tl }
+                \@@_bad_def:wn
+              }
+            \bool_set_false:N \l_@@_grab_expandably_bool
+          }
+      }
+    \bool_if:NTF \l_@@_long_bool
+      { \bool_set_true:N \l_@@_some_long_bool }
+      { \bool_set_true:N \l_@@_some_short_bool }
+    \bool_set_false:N \l_@@_long_bool
+    \tl_put_right:Nn \l_@@_arg_spec_tl {#1}
+  }
+%    \end{macrocode}
+% \end{macro}
+%
 % \subsection{Preparing the signature: general mechanism}
 %
 % \begin{macro}{\@@_prepare_signature:n}
@@ -1911,8 +1968,6 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_prepare_signature:n #1
   {
-    \bool_set_false:N \l_@@_all_long_bool
-    \bool_set_false:N \l_@@_all_long_set_bool
     \int_zero:N \l_@@_current_arg_int
     \bool_set_false:N \l_@@_long_bool
     \int_zero:N \l_@@_m_args_int
@@ -1948,12 +2003,7 @@
     \use:c
       {
          @@_add
-         \bool_if:nT
-           {
-             \l_@@_expandable_bool ||
-             \l_@@_simple_args_bool && ! \l_@@_environment_bool
-           }
-           { _expandable }
+         \bool_if:NT \l_@@_grab_expandably_bool { _expandable }
          _type_  \token_to_str:N #1 :w
       }
   }
@@ -2257,7 +2307,11 @@
 % the general grabbers are dealt with later.
 %
 % \begin{macro}{\@@_add_expandable_type_+:w}
-%   ^^A todo
+%   We have already checked that short arguments are before long
+%   arguments, so \cs{l_@@_long_bool} only changes from \texttt{false}
+%   to \texttt{true} once (and there is no need to reset it after each
+%   argument).  Also knock back the argument count because |+| is not an
+%   argument.  Continue the loop.
 %    \begin{macrocode}
 \cs_new_protected:cpn { @@_add_expandable_type_+:w }
   {
@@ -2288,18 +2342,16 @@
     \tl_if_eq:nnTF {#2} {#3}
       { \@@_add_expandable_type_D_aux:NN #1 #2 }
       { \@@_add_expandable_type_D_aux:NNN #1 #2 #3 }
-    \bool_set_false:N \l_@@_long_bool
     \@@_prepare_signature:N
   }
 \cs_new_protected:Npn \@@_add_expandable_type_D_aux:NNN #1#2#3
   {
-    \@@_add_expandable_grabber:n {#1}
-    \bool_if:NTF \l_@@_all_long_bool
+    \bool_if:NTF \l_@@_long_bool
       { \cs_set:cpx }
       { \cs_set_nopar:cpx }
       { \l_@@_expandable_aux_name_tl } ##1 ##2 #2 ##3 \q_@@ ##4 #3
       { ##1 {##2} {##3} {##4} }
-    \tl_put_right:Nx \l_@@_signature_tl
+    \@@_add_expandable_grabber:nn {#1}
       {
         \exp_not:c  { \l_@@_expandable_aux_name_tl }
         \exp_not:n { #2 #3 }
@@ -2307,13 +2359,12 @@
   }
 \cs_new_protected:Npn \@@_add_expandable_type_D_aux:NN #1#2
   {
-    \@@_add_expandable_grabber:n { #1_alt }
-    \bool_if:NTF \l_@@_all_long_bool
+    \bool_if:NTF \l_@@_long_bool
       { \cs_set:cpx }
       { \cs_set_nopar:cpx }
       { \l_@@_expandable_aux_name_tl } ##1 #2 ##2 #2
       { ##1 {##2} }
-    \tl_put_right:Nx \l_@@_signature_tl
+    \@@_add_expandable_grabber:nn { #1_alt }
       {
         \exp_not:c  { \l_@@_expandable_aux_name_tl }
         \exp_not:n {#2}
@@ -2337,10 +2388,10 @@
 \cs_new_protected:Npn \@@_add_expandable_type_E:w #1#2
   {
     \@@_add_default_E:nn {#1} {#2}
-    \@@_add_expandable_grabber:n { E }
     \tl_clear:N \l_@@_tmpb_tl
     \tl_map_function:nN {#1} \@@_add_expandable_type_E_aux:n
-    \tl_put_right:Nx \l_@@_signature_tl
+    \@@_add_expandable_grabber:nn
+      { E \bool_if:NT \l_@@_long_bool { _long } }
       {
         { \exp_not:o \l_@@_tmpb_tl }
         {
@@ -2348,7 +2399,6 @@
             { { \c_@@_no_value_tl } }
         }
       }
-    \bool_set_false:N \l_@@_long_bool
     \@@_prepare_signature:N
   }
 \cs_new_protected:Npn \@@_add_expandable_type_E_aux:n #1
@@ -2378,7 +2428,8 @@
 \cs_new_protected:Npn \@@_add_expandable_type_m:w
   {
     \@@_add_default:
-    \@@_add_expandable_grabber:n { m }
+    \@@_add_expandable_grabber:nn
+      { m \bool_if:NT \l_@@_long_bool { _long } } { }
     \@@_prepare_signature:N
   }
 %    \end{macrocode}
@@ -2400,14 +2451,12 @@
 \cs_new_protected:Npn \@@_add_expandable_type_t:w #1
   {
     \@@_add_default:
-    \@@_add_expandable_grabber_t:
     \@@_get_grabber:NN #1 \l_@@_tmpa_tl
-    \tl_put_right:Nx \l_@@_signature_tl
+    \@@_add_expandable_grabber:nn { t }
       {
         \exp_not:o \l_@@_tmpa_tl
         \exp_not:N #1
       }
-    \bool_set_false:N \l_@@_long_bool
     \@@_prepare_signature:N
   }
 %    \end{macrocode}
@@ -2420,54 +2469,27 @@
 \cs_new_protected:Npn \@@_add_expandable_type_u:w #1
   {
     \@@_add_default:
-    \@@_add_expandable_grabber:n { u }
-    \bool_if:NTF \l_@@_all_long_bool
+    \bool_if:NTF \l_@@_long_bool
       { \cs_set:cpn }
       { \cs_set_nopar:cpn }
-      { \l_@@_expandable_aux_name_tl } ##1 \q_@@ ##2 ##3 #1
-      { ##1 {##3} \q_@@ ##2 }
-    \tl_put_right:Nx \l_@@_signature_tl
+      { \l_@@_expandable_aux_name_tl } ##1 \q_@@ ##2 ##3 ##4 #1
+      { ##1 {##4} \q_@@ ##2 ##3 }
+    \@@_add_expandable_grabber:nn { u }
       { \exp_not:c  { \l_@@_expandable_aux_name_tl } }
     \@@_prepare_signature:N
   }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\@@_add_expandable_grabber:n, \@@_add_expandable_grabber_t:}
-%   For \texttt{t}-type arguments, simply add a grabber to the signature
-%   and reset the boolean keeping track of~\texttt{+} markers (they
-%   should be ignored for the purpose of determining the long status of
-%   the command because they take no argument).  For all other
-%   arguments, if the command's long status is already known then check
-%   that this argument has the correct long status, and otherwise set
-%   the long status to this argument's long status.
+% \begin{macro}{\@@_add_expandable_grabber:nn}
+%   This is called for all arguments to place the right grabber in the
+%   signature.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_add_expandable_grabber:n #1
+\cs_new_protected:Npn \@@_add_expandable_grabber:nn #1#2
   {
-    \bool_if:NTF \l_@@_all_long_set_bool
-      {
-        \bool_if:nT
-          { \bool_xor_p:nn { \l_@@_all_long_bool } { \l_@@_long_bool } }
-          {
-            \__msg_kernel_error:nnx { xparse } { inconsistent-long }
-              { \iow_char:N \\ \l_@@_function_tl }
-            \@@_bad_def:wn
-          }
-      }
-      {
-        \bool_set:Nn \l_@@_all_long_bool { \l_@@_long_bool }
-        \bool_set_true:N \l_@@_all_long_set_bool
-      }
     \tl_put_right:Nx \l_@@_signature_tl
-      { \exp_not:c { @@_expandable_grab_ #1 :w } }
-    \bool_set_false:N \l_@@_long_bool
+      { \exp_not:c { @@_expandable_grab_ #1 :w } #2 }
   }
-\cs_new_protected:Npn \@@_add_expandable_grabber_t:
-  {
-    \tl_put_right:Nn \l_@@_signature_tl
-      { \@@_expandable_grab_t:w }
-    \bool_set_false:N \l_@@_long_bool
-  }
 %    \end{macrocode}
 % \end{macro}
 %
@@ -3309,33 +3331,37 @@
 % \subsection{Grabbing arguments expandably}
 %
 % \begin{macro}[EXP]{\@@_expandable_grab_D:w}
-% \begin{macro}[EXP, aux]{\@@_expandable_grab_D:NNNwNn}
-% \begin{macro}[EXP, aux]{\@@_expandable_grab_D:NNNwNnnn}
+% \begin{macro}[EXP, aux]{\@@_expandable_grab_D:NNNwNNn}
+% \begin{macro}[EXP, aux]{\@@_expandable_grab_D:NNNwNNnnn}
 % \begin{macro}[EXP, aux]{\@@_expandable_grab_D:Nw}
-% \begin{macro}[EXP, aux]{\@@_expandable_grab_D:nnNNNwN}
-%   The first step is to grab the first token or group. The generic grabber
-%   \cs{\meta{function}}\verb*| | is just after \cs{q_@@}, we go and find
-%   it.
+% \begin{macro}[EXP, aux]{\@@_expandable_grab_D:nnNNNwNN}
+%   The first step is to grab the first token or group. The generic grabbers
+%   \cs{\meta{function}}\verb*| | and \cs{\meta{function}}\verb*| | are just after \cs{q_@@}, we go and find
+%   them (and use the long one).
 %    \begin{macrocode}
-\cs_new:Npn \@@_expandable_grab_D:w #1 \q_@@ #2
-  { #2 { \@@_expandable_grab_D:NNNwNn #1 \q_@@ #2 } }
+\cs_new:Npn \@@_expandable_grab_D:w #1 \q_@@ #2#3
+  { #2 { \@@_expandable_grab_D:NNNwNNn #1 \q_@@ #2 #3 } }
 %    \end{macrocode}
-%   We then wish to test whether |#6|, which we just grabbed, is exactly |#2|.
-%   Expand the only grabber function we have, |#1|, once: the two strings below
-%   are equal if and only if |#6| matches |#2| exactly.\footnote{It is obvious
-%   that if \texttt{\#6} matches \texttt{\#2} then the strings are equal. We
+%   We then wish to test whether |#7|, which we just grabbed, is exactly |#2|.
+%   A preliminary test is whether their string representations coincide, then
+%   expand the only grabber function we have, |#1|, once: the two strings below
+%   are equal if and only if |#7| matches |#2| exactly.\footnote{It is obvious
+%   that if \texttt{\#7} matches \texttt{\#2} then the strings are equal. We
 %   must check the converse. The right-hand-side of \cs{str_if_eq:onTF} does
 %   not end with \texttt{\#3}, implying that the grabber function took
 %   everything as its arguments. The first brace group can only be empty if
-%   \texttt{\#6} starts with \texttt{\#2}, otherwise the brace group preceding
-%   \texttt{\#6} would not vanish. The third brace group is empty, thus the
+%   \texttt{\#7} starts with \texttt{\#2}, otherwise the brace group preceding
+%   \texttt{\#7} would not vanish. The third brace group is empty, thus the
 %   \cs{q_@@} that was used by our grabber \texttt{\#1} must be the one
-%   that we inserted (not some token in \texttt{\#6}), hence the second brace
-%   group contains the end of \texttt{\#6} followed by \texttt{\#2}. Since this
+%   that we inserted (not some token in \texttt{\#7}), hence the second brace
+%   group contains the end of \texttt{\#7} followed by \texttt{\#2}. Since this
 %   is \texttt{\#2} on the right-hand-side, and no brace can be lost there,
-%   \texttt{\#6} must contain nothing else than its leading \texttt{\#2}.} If
-%   |#6| does not match |#2|, then the optional argument is missing, we use the
-%   default |-NoValue-|, and put back the argument |#6| in the input stream.
+%   \texttt{\#7} must contain nothing else than its leading \texttt{\#2}.}
+%   The preliminary test is needed as |#7| could validly contain
+%   \tn{par} (because a later mandatory argument could be long) and our
+%   grabber may be short.  If
+%   |#7| does not match |#2|, then the optional argument is missing, we use the
+%   default |-NoValue-|, and put back the argument |#7| in the input stream.
 %
 %   If it does match, then interesting things need to be done. We will grab the
 %   argument piece by piece, with the following pattern:
@@ -3361,34 +3387,38 @@
 %    \begin{macrocode}
 \cs_set_protected:Npn \@@_tmp:w #1
   {
-    \cs_new:Npn \@@_expandable_grab_D:NNNwNn ##1##2##3##4 \q_@@ ##5##6
+    \cs_new:Npn \@@_expandable_grab_D:NNNwNNn ##1##2##3##4 \q_@@ ##5##6##7
       {
-        \str_if_eq:onTF
-          { ##1 { } { } ##6 ##2 \q_@@ ##3 }
-          { { } {##2} { } }
+        \str_if_eq:nnTF {##2} {##7}
           {
+            \str_if_eq:onTF
+              { ##1 { } { } ##7 ##2 \q_@@ ##3 }
+              { { } {##2} { } }
+          }
+          { \use_ii:nn }
+          {
             ##1
-              { \@@_expandable_grab_D:NNNwNnnn ##1##2##3##4 \q_@@ ##5 }
+              { \@@_expandable_grab_D:NNNwNNnnn ##1##2##3##4 \q_@@ ##5##6 }
               \q_nil { } ##2 \ERROR \q_@@ \ERROR
           }
-          { ##4 {#1} \q_@@ ##5 {##6} }
+          { ##4 {#1} \q_@@ ##5 ##6 {##7} }
       }
   }
 \exp_args:No \@@_tmp:w { \c_@@_no_value_tl }
 %    \end{macrocode}
-%   At this stage, |#6| is \cs{q_nil} \Arg{piece 1} \meta{more for piece 1},
+%   At this stage, |#7| is \cs{q_nil} \Arg{piece 1} \meta{more for piece 1},
 %   and we want to concatenate all that, removing \cs{q_nil}, and keeping the
-%   opening delimiter |#2|. Simply use \cs{use_ii:nn}. Also, |#7| is
-%   \meta{remainder of piece 2} \cs{ERROR}, and |#8| is \cs{ERROR} \meta{more
+%   opening delimiter |#2|. Simply use \cs{use_ii:nn}. Also, |#8| is
+%   \meta{remainder of piece 2} \cs{ERROR}, and |#9| is \cs{ERROR} \meta{more
 %   for piece 2}. We concatenate those, replacing the two \cs{ERROR} by the
 %   closing delimiter |#3|.
 %    \begin{macrocode}
-\cs_new:Npn \@@_expandable_grab_D:NNNwNnnn #1#2#3#4 \q_@@ #5#6#7#8
+\cs_new:Npn \@@_expandable_grab_D:NNNwNNnnn #1#2#3#4 \q_@@ #5#6#7#8#9
   {
-    \exp_args:Nof \@@_expandable_grab_D:nnNNNwN
-      { \use_ii:nn #6 #2 }
-      { \@@_expandable_grab_D:Nw #3 \exp_stop_f: #7 #8 }
-    #1#2#3 #4 \q_@@ #5
+    \exp_args:Nof \@@_expandable_grab_D:nnNNNwNN
+      { \use_ii:nn #7 #2 }
+      { \@@_expandable_grab_D:Nw #3 \exp_stop_f: #8 #9 }
+    #1#2#3 #4 \q_@@ #5 #6
   }
 \cs_new:Npn \@@_expandable_grab_D:Nw #1#2 \ERROR \ERROR { #2 #1 }
 %    \end{macrocode}
@@ -3400,10 +3430,10 @@
 %   delimiter. In that case, we are done, and put the argument (from which we
 %   remove a spurious pair of delimiters coming from how we started the loop).
 %   Otherwise, we go back to looping with
-%   \cs{@@_expandable_grab_D:NNNwNnnn}. The code to deal with brace stripping
+%   \cs{@@_expandable_grab_D:NNNwNNnnn}. The code to deal with brace stripping
 %   is much the same as for the non-expandable case.
 %    \begin{macrocode}
-\cs_new:Npn \@@_expandable_grab_D:nnNNNwN #1#2#3#4#5#6 \q_@@ #7
+\cs_new:Npn \@@_expandable_grab_D:nnNNNwNN #1#2#3#4#5#6 \q_@@ #7#8
   {
     \exp_args:No \tl_if_empty:oTF
       { #3 { \use_none:nnn } #2 \q_@@ #5 #4 \q_@@ #5 }
@@ -3417,11 +3447,11 @@
               { \@@_put_arg_expandable:ow { \use_iii:nnn #1#2 } }
               { \@@_put_arg_expandable:ow { \use_none:nn #1#2 } }
           }
-            #6 \q_@@ #7
+            #6 \q_@@ #7 #8
       }
       {
         #3
-          { \@@_expandable_grab_D:NNNwNnnn #3#4#5#6 \q_@@ #7 }
+          { \@@_expandable_grab_D:NNNwNNnnn #3#4#5#6 \q_@@ #7 #8 }
           \q_nil {#1} #2 \ERROR \q_@@ \ERROR
       }
   }
@@ -3433,58 +3463,66 @@
 % \end{macro}
 %
 % \begin{macro}[EXP]{\@@_expandable_grab_D_alt:w}
-% \begin{macro}[EXP]{\@@_expandable_grab_D_alt:NNwNn}
+% \begin{macro}[EXP]{\@@_expandable_grab_D_alt:NNwNNn}
 % \begin{macro}[EXP]{\@@_expandable_grab_D_alt:Nwn}
 %   When the delimiters are identical, nesting is not possible and a simplified
 %   approach is used. The test concept here is the same as for the case where
-%   the delimiters are different.
+%   the delimiters are different but there cannot be any nesting.
 %    \begin{macrocode}
-\cs_new:Npn \@@_expandable_grab_D_alt:w #1 \q_@@ #2
-  { #2 { \@@_expandable_grab_D_alt:NNwNn #1 \q_@@ #2 } }
+\cs_new:Npn \@@_expandable_grab_D_alt:w #1 \q_@@ #2#3
+  { #2 { \@@_expandable_grab_D_alt:NNwNNn #1 \q_@@ #2 #3 } }
 \cs_set_protected:Npn \@@_tmp:w #1
   {
-    \cs_new:Npn \@@_expandable_grab_D_alt:NNwNn ##1##2##3 \q_@@ ##4##5
+    \cs_new:Npn \@@_expandable_grab_D_alt:NNwNNn ##1##2##3 \q_@@ ##4##5##6
       {
-        \str_if_eq:onTF
-          { ##1 { } ##5 ##2 ##2 }
-          { { } ##2 }
+        \str_if_eq:nnTF {##6} {##2}
           {
+            \str_if_eq:onTF
+              { ##1 { } ##6 ##2 ##2 }
+              { { } ##2 }
+          }
+          { \use_ii:nn }
+          {
             ##1
-              { \@@_expandable_grab_D_alt:Nwn ##4 ##3 \q_@@ }
-              ##5 \ERROR
+              { \@@_expandable_grab_D_alt:NNwn ##4 ##5 ##3 \q_@@ }
+              ##6 \ERROR
           }
-          { ##3 {#1} \q_@@ ##4 {##5} }
+          { ##3 {#1} \q_@@ ##4 ##5 {##6} }
       }
   }
 \exp_args:No \@@_tmp:w { \c_@@_no_value_tl }
-\cs_new:Npn \@@_expandable_grab_D_alt:Nwn #1#2 \q_@@ #3
+\cs_new:Npn \@@_expandable_grab_D_alt:NNwn #1#2#3 \q_@@ #4
   {
-    \tl_if_blank:oTF { \use_none:n #3 }
-      { \@@_put_arg_expandable:ow { \use_none:n #3 } }
+    \tl_if_blank:oTF { \use_none:n #4 }
+      { \@@_put_arg_expandable:ow { \use_none:n #4 } }
       {
         \str_if_eq_x:nnTF
-          { \exp_not:o { \use_none:n #3 } }
-          { { \exp_not:o { \use_ii:nnn #3 \q_nil } } }
-          { \@@_put_arg_expandable:ow { \use_ii:nn #3 } }
-          { \@@_put_arg_expandable:ow { \use_none:n #3 } }
+          { \exp_not:o { \use_none:n #4 } }
+          { { \exp_not:o { \use_ii:nnn #4 \q_nil } } }
+          { \@@_put_arg_expandable:ow { \use_ii:nn #4 } }
+          { \@@_put_arg_expandable:ow { \use_none:n #4 } }
       }
-        #2 \q_@@ #1
+        #3 \q_@@ #1 #2
   }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
 % \end{macro}
 %
-% \begin{macro}[EXP]{\@@_expandable_grab_E:w}
-% \begin{macro}[EXP,aux]{\@@_expandable_grab_E_test:nnwn}
+% \begin{macro}[EXP]{\@@_expandable_grab_E:w, \@@_expandable_grab_E_long:w}
+% \begin{macro}[EXP,aux]{\@@_expandable_grab_E_aux:w}
+% \begin{macro}[EXP,aux]{\@@_expandable_grab_E_test:nnw}
 % \begin{macro}[EXP,aux]{\@@_expandable_grab_E_loop:nnnNNw}
-% \begin{macro}[EXP,aux]{\@@_expandable_grab_E_aux:nnw}
-% \begin{macro}[EXP,aux]{\@@_expandable_grab_E_aux:nnnnn}
+% \begin{macro}[EXP,aux]{\@@_expandable_grab_E_find:w}
+% \begin{macro}[EXP,aux]{\@@_expandable_grab_E_find:nnw}
 % \begin{macro}[EXP,aux]{\@@_expandable_grab_E_end:nnw}
-%   The function will be called repeatedly with two arguments: the set
+%   We keep track of long/short by placing the appropriate grabber as
+%   the third token after \cs{q_@@}; it is eventually removed by the
+%   \texttt{end:nnw} auxiliary.  The \texttt{aux:w} auxiliary will be
+%   called repeatedly with two arguments: the set
 %   of pairs \meta{parser} \meta{token}, and the set of arguments found
 %   so far (initially all |{-NoValue-}|).  At each step, grab what
-%   follows in the input stream then call the \texttt{loop:nnnNNwn}
+%   follows in the input stream then call the \texttt{loop:nnnNNw}
 %   auxiliary to compare it with each possible embellishment in turn.
 %   This auxiliary's |#1| is what was found in the input, |#2| collects
 %   \meta{parser} \meta{token} pairs that did not match, |#3| collects
@@ -3499,18 +3537,22 @@
 %   does not match |#5| (see \texttt{t}-type arguments below for a
 %   similar \cs{str_if_eq:onTF} test) then carry on the loop.
 %   Otherwise, we found a new embellishment: grab the corresponding
-%   argument in the input using the \texttt{:w} auxiliary.  To avoid
-%   losing braces around that auxiliary's argument |#4| we include a
+%   argument in the input using the \texttt{find:w} auxiliary.  To avoid
+%   losing braces around that auxiliary's argument we include a
 %   space, which will be eliminated in the next loop through
 %   embellishments.
 %    \begin{macrocode}
-\cs_new:Npn \@@_expandable_grab_E:w #1 \q_@@ #2
-  { #2 { \@@_expandable_grab_E_test:nnwn #1 \q_@@ #2 } }
-\cs_new:Npn \@@_expandable_grab_E_test:nnwn #1#2#3 \q_@@ #4#5
+\cs_new:Npn \@@_expandable_grab_E:w #1 \q_@@ #2#3
+  { \@@_expandable_grab_E_aux:w #1 \q_@@ #2 #3 #3 }
+\cs_new:Npn \@@_expandable_grab_E_long:w #1 \q_@@ #2#3
+  { \@@_expandable_grab_E_aux:w #1 \q_@@ #2 #3 #2 }
+\cs_new:Npn \@@_expandable_grab_E_aux:w #1 \q_@@ #2#3#4
+  { #2 { \@@_expandable_grab_E_test:nnw #1 \q_@@ #2 #3 #4 } }
+\cs_new:Npn \@@_expandable_grab_E_test:nnw #1#2#3 \q_@@ #4#5#6#7
   {
-    \@@_expandable_grab_E_loop:nnnNNw {#5} { } { }
+    \@@_expandable_grab_E_loop:nnnNNw {#7} { } { }
       #1 \q_nil \q_nil \q_nil \q_mark #2 \q_nil
-    #3 \q_@@ #4
+    #3 \q_@@ #4 #5 #6
   }
 \cs_new:Npn \@@_expandable_grab_E_loop:nnnNNw
     #1#2#3#4#5#6 \q_nil #7 \q_mark #8
@@ -3521,7 +3563,7 @@
         \@@_if_no_value:nTF {#8}
           { \str_if_eq:onTF { #4 { } #1 #5 } {#5} }
           { \use_ii:nn }
-            { \@@_expandable_grab_E_aux:w { #2 #4 #5 #6 } {#3} ~ }
+            { \@@_expandable_grab_E_find:w { #2 #4 #5 #6 } {#3} ~ }
             {
               \@@_expandable_grab_E_loop:nnnNNw
                 {#1} { #2 #4 #5 } { #3 {#8} }
@@ -3529,12 +3571,12 @@
             }
       }
   }
-\cs_new:Npn \@@_expandable_grab_E_aux:w #1 \q_@@ #2
-  { #2 { \@@_expandable_grab_E_aux:nnw #1 \q_@@ #2 } }
-\cs_new:Npn \@@_expandable_grab_E_aux:nnw #1#2#3 \q_nil #4 \q_@@ #5#6
-  { \@@_expandable_grab_E:w {#1} { #2 {#6} #3 } #4 \q_@@ #5 }
-\cs_new:Npn \@@_expandable_grab_E_end:nnw #1#2#3 \q_@@ #4
-  { #3 {#2} \q_@@ #4 {#1} }
+\cs_new:Npn \@@_expandable_grab_E_find:w #1 \q_@@ #2#3#4
+  { #4 { \@@_expandable_grab_E_find:nnw #1 \q_@@ #2 #3 #4 } }
+\cs_new:Npn \@@_expandable_grab_E_find:nnw #1#2#3 \q_nil #4 \q_@@ #5#6#7#8
+  { \@@_expandable_grab_E_aux:w {#1} { #2 {#8} #3 } #4 \q_@@ #5 #6 #7 }
+\cs_new:Npn \@@_expandable_grab_E_end:nnw #1#2#3 \q_@@ #4#5#6
+  { #3 {#2} \q_@@ #4 #5 {#1} }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
@@ -3542,44 +3584,51 @@
 % \end{macro}
 % \end{macro}
 % \end{macro}
+% \end{macro}
 %
-% \begin{macro}[EXP]{\@@_expandable_grab_m:w}
+% \begin{macro}[EXP]{\@@_expandable_grab_m:w, \@@_expandable_grab_m_long:w}
 % \begin{macro}[EXP, aux]{\@@_expandable_grab_m_aux:wNn}
 %   The mandatory case is easy: find the auxiliary after the \cs{q_@@},
-%   and use it directly to grab the argument.  The auxiliary here is
-%   used also for \texttt{u}-type (and \texttt{l}-type) arguments.
+%   and use it directly to grab the argument, then correctly position
+%   the argument before \cs{q_@@}.
 %    \begin{macrocode}
-\cs_new:Npn \@@_expandable_grab_m:w #1 \q_@@ #2
-  { #2 { \@@_expandable_grab_m_aux:wNn #1 \q_@@ #2 } }
-\cs_new:Npn \@@_expandable_grab_m_aux:wNn #1 \q_@@ #2#3
-  { #1 {#3} \q_@@ #2 }
+\cs_new:Npn \@@_expandable_grab_m:w #1 \q_@@ #2#3
+  { #3 { \@@_expandable_grab_m_aux:wNn #1 \q_@@ #2 #3 } }
+\cs_new:Npn \@@_expandable_grab_m_long:w #1 \q_@@ #2#3
+  { #2 { \@@_expandable_grab_m_aux:wNn #1 \q_@@ #2 #3 } }
+\cs_new:Npn \@@_expandable_grab_m_aux:wNn #1 \q_@@ #2#3#4
+  { #1 {#4} \q_@@ #2 #3 }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
 %
 % \begin{macro}[EXP]{\@@_expandable_grab_R:w}
-% \begin{macro}[EXP, aux]{\@@_expandable_grab_R_aux:NNNwNn}
+% \begin{macro}[EXP, aux]{\@@_expandable_grab_R_aux:NNNwNNn}
 %   Much the same as for the \texttt{D}-type argument, with only the lead-off
 %   function varying.
 %    \begin{macrocode}
-\cs_new:Npn \@@_expandable_grab_R:w #1 \q_@@ #2
-  { #2 { \@@_expandable_grab_R_aux:NNNwNn #1 \q_@@ #2 } }
+\cs_new:Npn \@@_expandable_grab_R:w #1 \q_@@ #2#3
+  { #2 { \@@_expandable_grab_R_aux:NNNwNNn #1 \q_@@ #2#3 } }
 \cs_set_protected:Npn \@@_tmp:w #1
   {
-    \cs_new:Npn \@@_expandable_grab_R_aux:NNNwNn ##1##2##3##4 \q_@@ ##5##6
+    \cs_new:Npn \@@_expandable_grab_R_aux:NNNwNNn ##1##2##3##4 \q_@@ ##5##6##7
       {
-        \str_if_eq:onTF
-          { ##1 { } { } ##6 ##2 \q_@@ ##3 }
-          { { } {##2} { } }
+        \str_if_eq:nnTF {##7} {##2}
           {
+            \str_if_eq:onTF
+              { ##1 { } { } ##7 ##2 \q_@@ ##3 }
+              { { } {##2} { } }
+          }
+          { \use_ii:nn }
+          {
             ##1
-              { \@@_expandable_grab_D:NNNwNnnn ##1##2##3##4 \q_@@ ##5 }
+              { \@@_expandable_grab_D:NNNwNNnnn ##1##2##3##4 \q_@@ ##5##6 }
               \q_nil { } ##2 \ERROR \q_@@ \ERROR
           }
           {
             \__msg_kernel_expandable_error:nnnn
               { xparse } { missing-required } {##5} {##2}
-            ##4 {#1} \q_@@ ##5 {##6}
+            ##4 {#1} \q_@@ ##5 ##6 {##7}
           }
       }
   }
@@ -3589,29 +3638,33 @@
 % \end{macro}
 %
 % \begin{macro}[EXP]{\@@_expandable_grab_R_alt:w}
-% \begin{macro}[EXP]{\@@_expandable_grab_R_alt_aux:NNwNn}
+% \begin{macro}[EXP]{\@@_expandable_grab_R_alt_aux:NNwNNn}
 %   When the delimiters are identical, nesting is not possible and a simplified
 %   approach is used. The test concept here is the same as for the case where
 %   the delimiters are different.
 %    \begin{macrocode}
-\cs_new:Npn \@@_expandable_grab_R_alt:w #1 \q_@@ #2
-  { #2 { \@@_expandable_grab_R_alt_aux:NNnwNn #1 \q_@@ #2 } }
+\cs_new:Npn \@@_expandable_grab_R_alt:w #1 \q_@@ #2#3
+  { #2 { \@@_expandable_grab_R_alt_aux:NNnwNn #1 \q_@@ #2#3 } }
 \cs_set_protected:Npn \@@_tmp:w #1
   {
-    \cs_new:Npn \@@_expandable_grab_R_alt_aux:NNwNn ##1##2##3 \q_@@ ##4##5
+    \cs_new:Npn \@@_expandable_grab_R_alt_aux:NNwNn ##1##2##3 \q_@@ ##4##5##6
       {
-        \str_if_eq:onTF
-          { ##1 { } ##5 ##2 ##2 }
-          { { } ##2 }
+        \str_if_eq:nnTF {##6} {##2}
           {
+            \str_if_eq:onTF
+              { ##1 { } ##6 ##2 ##2 }
+              { { } ##2 }
+          }
+          { \use_ii:nn }
+          {
             ##1
-              { \@@_expandable_grab_D_alt:Nwn ##4 ##3 \q_@@ }
-              ##5 \ERROR
+              { \@@_expandable_grab_D_alt:NNwn ##4 ##5 ##3 \q_@@ }
+              ##6 \ERROR
           }
           {
             \__msg_kernel_expandable_error:nnnn
               { xparse } { missing-required } {##4} {##2}
-            ##3 {#1} \q_@@ ##4 {##5}
+            ##3 {#1} \q_@@ ##4 ##5 {##6}
           }
       }
   }
@@ -3626,13 +3679,13 @@
 %   the only parser we have in order to work out if |#2| is exactly equal to
 %   the output of the grabber.
 %    \begin{macrocode}
-\cs_new:Npn \@@_expandable_grab_t:w #1 \q_@@ #2
-  { #2 { \@@_expandable_grab_t_aux:NNwn #1 \q_@@ #2 } }
-\cs_new:Npn \@@_expandable_grab_t_aux:NNwn #1#2#3 \q_@@ #4#5
+\cs_new:Npn \@@_expandable_grab_t:w #1 \q_@@ #2#3
+  { #2 { \@@_expandable_grab_t_aux:NNwn #1 \q_@@ #2 #3 } }
+\cs_new:Npn \@@_expandable_grab_t_aux:NNwn #1#2#3 \q_@@ #4#5#6
   {
-    \str_if_eq:onTF { #1 { } #5 #2 } {#2}
-      { #3 { \BooleanTrue } \q_@@ #4 }
-      { #3 { \BooleanFalse } \q_@@ #4 {#5} }
+    \str_if_eq:onTF { #1 { } #6 #2 } {#2}
+      { #3 { \BooleanTrue } \q_@@ #4 #5 }
+      { #3 { \BooleanFalse } \q_@@ #4 #5 {#6} }
   }
 %    \end{macrocode}
 % \end{macro}
@@ -4000,7 +4053,7 @@
 %   To determine whether the command is an \pkg{xparse} command check
 %   that its |arg_spec| is empty (this also excludes non-macros) and
 %   that its |replacement_spec| starts with either \cs{@@_start:nNNnnn}
-%   (non-expandable command) or \cs{@@_start_expandable:nNNNn}
+%   (non-expandable command) or \cs{@@_start_expandable:nNNNNn}
 %   (expandable command).
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_cmd_if_xparse:NTF #1
@@ -4015,7 +4068,7 @@
       }
       {
         { \token_to_str:N \@@_start:nNNnnn } { }
-        { \token_to_str:N \@@_start_expandable:nNNNn } { }
+        { \token_to_str:N \@@_start_expandable:nNNNNn } { }
       }
   }
 \cs_new:Npn \@@_cmd_if_xparse_aux:w #1 ~ #2 \q_stop {#1}
@@ -4078,8 +4131,8 @@
   { Inconsistent~long~arguments~for~expandable~command~'#1'. }
   {
     \c__msg_coding_error_text_tl
-    The~arguments~for~an~expandable~command~must~either~all~be~
-    short~or~all~be~long.~You~have~tried~to~mix~the~two~types.
+    The~arguments~for~an~expandable~command~must~not~involve~short~
+    arguments~after~long~arguments.~You~have~tried~to~mix~the~two~types.
   }
 \__msg_kernel_new:nnnn { xparse } { invalid-expandable-argument-type }
   { Argument~type~'#2'~not~available~for~expandable~command~'#1'. }



More information about the latex3-commits mailing list