add tag
3 years ago निरंजन

I was experimenting with these two commands and I realized that there are cases where they aren’t identical.

I expect the output of both the commands to be same which it isn’t.

Screenshot_2022-06-08_21-27-25.png

This is rather strange. Is this the expected behavior or a bug?

Top Answer
3 years ago Skillmon

The issue is that \NewDocumentEnvironment has an argument more than \NewDocumentCommand, that argument defines what should be done in the \end part of said environment. So the syntax is:

(this is analogue to \newenvironment, that also allows you to define the action in \begin and \end).

Now when you call your environment fooenv it’ll do the \NewDocumentEnvironment{barenv} definition, and that one will grab an argument more than you provide (in your example that argument is H). Now the environments do what you tell them to, and on \end{barenv} the H is reinserted (as that’s the definition for the \end-part now).

Please note that I’d say using \NewDocumentEnvironment to define a nested environment seems wrong. What I’d do is define it globally, but also define a toggle that’ll throw an error if you don’t use it nested in fooenv.

Consider the following example:

3 years
निरंजन replying to Skillmon — Sunday, 12th Jun 2022 14:31

Cool, thanks!

2 days
frougon replying to Skillmon — Friday, 10th Jun 2022 20:45

That would be a perverse user, for sure. 😉

Skillmon replying to frougon — Friday, 10th Jun 2022 20:43

Also, the thing about \empty is that I can definitely imagine some user doing \renewcommand\empty{\ensuremath{\{\}}} just to have some macro way to input an empty set (and yes, I deliberately put \ensuremath there to show bad code 😛)

Skillmon replying to frougon — Friday, 10th Jun 2022 20:41

oh, I almost forgot about Heiko’s package O.o Of course the full argument was a bit constructed (but never trust the user!)

a day
frougon replying to Skillmon — Thursday, 9th Jun 2022 22:04

\empty is about as much document-level as \endgraf, \space, \null and… \bgroup & \egroup (all defined in plain.tex). But that’s okay. 😃 \ltx@empty is indeed not defined by the LaTeX kernel but by the ltxcmds package from Heiko Oberdiek. Had it been widely used from the beginning, that would have made it possible to change kernel macros that can be considered as implementation details without breaking everything (though the emphasis in the manual is more on making useful basic things available to non-LaTeX formats; plus, I don’t see a pressing need to change trivial things like \@firstoftwo or \@empty… this argument is therefore a bit theoretical, but when it comes to less trivial things like \@for, \@tfor, etc., it might be considered…).

2 hours
Skillmon replying to frougon — Thursday, 9th Jun 2022 20:08

Force of habit. \@empty is more “secure” than \empty (that one lives on the document-level syntax, never trust the average user to not redefine it!), and \ltx@empty isn’t defined by the kernel, afaik.

Skillmon replying to निरंजन — Thursday, 9th Jun 2022 20:07

I’d say that defining new commands with a command is fine, hence there might be reason to use \NewDocumentCommand inside \NewDocumentCommand (but I’d not define a command for the scope of another command’s replacement text with \NewDocumentCommand, maybe with \RenewDocumentCommand – same is true for the environment, instead of my flag approach you could \RenewDocumentEnvironment).

4 hours
frougon — Thursday, 9th Jun 2022 16:12

The question I would like to see answered is why Skillmon chose \@empty over \empty and ltxcmds's \ltx@empty. 😉

3 hours
निरंजन — Thursday, 9th Jun 2022 13:20

@Skillmon, re: your answer, Thanks for your answer. I understood my mistake. Can you please elaborate why nested commands are okay, but nested environments aren’t?

निरंजन replying to Skillmon — Thursday, 9th Jun 2022 13:19

Ah! A syntax-error. Sorry and thanks.

20 hours
Skillmon — Wednesday, 8th Jun 2022 17:10

@निरंजन, re: your question, not the issue/explanation (well, actually it is the issue, but this comment doesn’t contain the full explanation), but note that \NewDocumentEnvironment has an argument more than \NewDocumentCommand (namely the definition for the \end part).

Enter question or answer id or url (and optionally further answer ids/urls from the same question) from

Separate each id/url with a space. No need to list your own answers; they will be imported automatically.