A curious dependency between newcommand and curly braces












10















An example is a bit artificial, but the point is that I do not understand why
{} influence the outcome of newcommand in the way described below.



Consider the following definition:



newcommandprintit[1]{#1}


whose outcome is obvious. However, a small alteration:



newcommand{printit[1]}{#1}


and e.g. printit{2} yields:



enter image description here



I have no idea why. Could you please shed some light on what is going on here?










share|improve this question




















  • 1





    defnew@command#1{% @testopt{@newcommand#1}0} from latex.ltx, i.e. LaTeX tests whether there is an optional argument in the first argument of newcommand, i.e. printit[1] and returns 0, the {2} in its usage is not regarded as an argument. You could use printit without {} and it will still print 0, use it as printit[2] and it will print 2. In fact you have defined a macro with optional arguments in a non-obvious way

    – Christian Hupfer
    17 hours ago













  • The correct syntax is newcommandprintit[1]{#1} or newcommand{printit}[1]{#1} (The number of parameters to be expected is given in square brackets, outside of the {}). In case people come across this and are confused by the above syntax.

    – Peter Grill
    17 hours ago













  • @PeterGrill Yes, I know the correct syntax. But I was curious why grouping printit[1] results in the (rather unexpected) outcome.

    – Mad Hatter
    15 hours ago











  • @MadHatter: Yep, I figured that. My comment was intended for others who may come across this and be confused.

    – Peter Grill
    14 hours ago
















10















An example is a bit artificial, but the point is that I do not understand why
{} influence the outcome of newcommand in the way described below.



Consider the following definition:



newcommandprintit[1]{#1}


whose outcome is obvious. However, a small alteration:



newcommand{printit[1]}{#1}


and e.g. printit{2} yields:



enter image description here



I have no idea why. Could you please shed some light on what is going on here?










share|improve this question




















  • 1





    defnew@command#1{% @testopt{@newcommand#1}0} from latex.ltx, i.e. LaTeX tests whether there is an optional argument in the first argument of newcommand, i.e. printit[1] and returns 0, the {2} in its usage is not regarded as an argument. You could use printit without {} and it will still print 0, use it as printit[2] and it will print 2. In fact you have defined a macro with optional arguments in a non-obvious way

    – Christian Hupfer
    17 hours ago













  • The correct syntax is newcommandprintit[1]{#1} or newcommand{printit}[1]{#1} (The number of parameters to be expected is given in square brackets, outside of the {}). In case people come across this and are confused by the above syntax.

    – Peter Grill
    17 hours ago













  • @PeterGrill Yes, I know the correct syntax. But I was curious why grouping printit[1] results in the (rather unexpected) outcome.

    – Mad Hatter
    15 hours ago











  • @MadHatter: Yep, I figured that. My comment was intended for others who may come across this and be confused.

    – Peter Grill
    14 hours ago














10












10








10


1






An example is a bit artificial, but the point is that I do not understand why
{} influence the outcome of newcommand in the way described below.



Consider the following definition:



newcommandprintit[1]{#1}


whose outcome is obvious. However, a small alteration:



newcommand{printit[1]}{#1}


and e.g. printit{2} yields:



enter image description here



I have no idea why. Could you please shed some light on what is going on here?










share|improve this question
















An example is a bit artificial, but the point is that I do not understand why
{} influence the outcome of newcommand in the way described below.



Consider the following definition:



newcommandprintit[1]{#1}


whose outcome is obvious. However, a small alteration:



newcommand{printit[1]}{#1}


and e.g. printit{2} yields:



enter image description here



I have no idea why. Could you please shed some light on what is going on here?







macros braces grouping






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 5 hours ago







Mad Hatter

















asked 17 hours ago









Mad HatterMad Hatter

600420




600420








  • 1





    defnew@command#1{% @testopt{@newcommand#1}0} from latex.ltx, i.e. LaTeX tests whether there is an optional argument in the first argument of newcommand, i.e. printit[1] and returns 0, the {2} in its usage is not regarded as an argument. You could use printit without {} and it will still print 0, use it as printit[2] and it will print 2. In fact you have defined a macro with optional arguments in a non-obvious way

    – Christian Hupfer
    17 hours ago













  • The correct syntax is newcommandprintit[1]{#1} or newcommand{printit}[1]{#1} (The number of parameters to be expected is given in square brackets, outside of the {}). In case people come across this and are confused by the above syntax.

    – Peter Grill
    17 hours ago













  • @PeterGrill Yes, I know the correct syntax. But I was curious why grouping printit[1] results in the (rather unexpected) outcome.

    – Mad Hatter
    15 hours ago











  • @MadHatter: Yep, I figured that. My comment was intended for others who may come across this and be confused.

    – Peter Grill
    14 hours ago














  • 1





    defnew@command#1{% @testopt{@newcommand#1}0} from latex.ltx, i.e. LaTeX tests whether there is an optional argument in the first argument of newcommand, i.e. printit[1] and returns 0, the {2} in its usage is not regarded as an argument. You could use printit without {} and it will still print 0, use it as printit[2] and it will print 2. In fact you have defined a macro with optional arguments in a non-obvious way

    – Christian Hupfer
    17 hours ago













  • The correct syntax is newcommandprintit[1]{#1} or newcommand{printit}[1]{#1} (The number of parameters to be expected is given in square brackets, outside of the {}). In case people come across this and are confused by the above syntax.

    – Peter Grill
    17 hours ago













  • @PeterGrill Yes, I know the correct syntax. But I was curious why grouping printit[1] results in the (rather unexpected) outcome.

    – Mad Hatter
    15 hours ago











  • @MadHatter: Yep, I figured that. My comment was intended for others who may come across this and be confused.

    – Peter Grill
    14 hours ago








1




1





defnew@command#1{% @testopt{@newcommand#1}0} from latex.ltx, i.e. LaTeX tests whether there is an optional argument in the first argument of newcommand, i.e. printit[1] and returns 0, the {2} in its usage is not regarded as an argument. You could use printit without {} and it will still print 0, use it as printit[2] and it will print 2. In fact you have defined a macro with optional arguments in a non-obvious way

– Christian Hupfer
17 hours ago







defnew@command#1{% @testopt{@newcommand#1}0} from latex.ltx, i.e. LaTeX tests whether there is an optional argument in the first argument of newcommand, i.e. printit[1] and returns 0, the {2} in its usage is not regarded as an argument. You could use printit without {} and it will still print 0, use it as printit[2] and it will print 2. In fact you have defined a macro with optional arguments in a non-obvious way

– Christian Hupfer
17 hours ago















The correct syntax is newcommandprintit[1]{#1} or newcommand{printit}[1]{#1} (The number of parameters to be expected is given in square brackets, outside of the {}). In case people come across this and are confused by the above syntax.

– Peter Grill
17 hours ago







The correct syntax is newcommandprintit[1]{#1} or newcommand{printit}[1]{#1} (The number of parameters to be expected is given in square brackets, outside of the {}). In case people come across this and are confused by the above syntax.

– Peter Grill
17 hours ago















@PeterGrill Yes, I know the correct syntax. But I was curious why grouping printit[1] results in the (rather unexpected) outcome.

– Mad Hatter
15 hours ago





@PeterGrill Yes, I know the correct syntax. But I was curious why grouping printit[1] results in the (rather unexpected) outcome.

– Mad Hatter
15 hours ago













@MadHatter: Yep, I figured that. My comment was intended for others who may come across this and be confused.

– Peter Grill
14 hours ago





@MadHatter: Yep, I figured that. My comment was intended for others who may come across this and be confused.

– Peter Grill
14 hours ago










1 Answer
1






active

oldest

votes


















16














If LaTeX was being written now,



newcommand{printit[1]}{#1}


would give an error message that printit[1] was not a single token.



The correct syntax is



newcommand{printit}[1]{#1}


or



newcommandprintit[1]{#1}


LaTeX does nothing special to allow both forms, it is just on the general TeX macro syntax rules that braces can be omitted if a macro argument is a single token.



If you pass two (or in this case, four) tokens to newcommand then anything that happens is essentially just accidental behaviour, as the system could not really afford the space or time required to catch "unlikely" errors.



As to what happens,



documentclass{article}

begin{document}

newcommand{printit[1]}{#1}

showprintit
expandaftershowcsnamestringprintitendcsname
end{document}


produces the terminal log



> printit=macro:
->@protected@testopt printit \printit {0}.
l.7 showprintit

?
> \printit=long macro:
[#1]->#1.


The command defines printit to have an optional first argument, although the default value of 0 being supplied was intended as the default value for newcommand itself.
it is what makes newcommandfoo the same as newcommandfoo[0] and define a command with no arguments.



The inner part of the command handling the optional argument is \printit which just drops the square brackets.



So



 printit{2}


is



 printit[0]{2}


which is



0{2}


which typesets as 02






share|improve this answer


























  • Thanks for a thorough explanation!

    – Mad Hatter
    15 hours ago











  • What about LaTeX3, which is being written now? ;-)

    – Socob
    11 hours ago






  • 1





    @Socob I hadn't actually checked but add usepackage{xparse} and replace newcommand by NewDocumentCommand and you get ! LaTeX3 Error: First argument of 'NewDocumentCommand' must be a command.

    – David Carlisle
    5 hours ago











Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "85"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f469994%2fa-curious-dependency-between-newcommand-and-curly-braces%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









16














If LaTeX was being written now,



newcommand{printit[1]}{#1}


would give an error message that printit[1] was not a single token.



The correct syntax is



newcommand{printit}[1]{#1}


or



newcommandprintit[1]{#1}


LaTeX does nothing special to allow both forms, it is just on the general TeX macro syntax rules that braces can be omitted if a macro argument is a single token.



If you pass two (or in this case, four) tokens to newcommand then anything that happens is essentially just accidental behaviour, as the system could not really afford the space or time required to catch "unlikely" errors.



As to what happens,



documentclass{article}

begin{document}

newcommand{printit[1]}{#1}

showprintit
expandaftershowcsnamestringprintitendcsname
end{document}


produces the terminal log



> printit=macro:
->@protected@testopt printit \printit {0}.
l.7 showprintit

?
> \printit=long macro:
[#1]->#1.


The command defines printit to have an optional first argument, although the default value of 0 being supplied was intended as the default value for newcommand itself.
it is what makes newcommandfoo the same as newcommandfoo[0] and define a command with no arguments.



The inner part of the command handling the optional argument is \printit which just drops the square brackets.



So



 printit{2}


is



 printit[0]{2}


which is



0{2}


which typesets as 02






share|improve this answer


























  • Thanks for a thorough explanation!

    – Mad Hatter
    15 hours ago











  • What about LaTeX3, which is being written now? ;-)

    – Socob
    11 hours ago






  • 1





    @Socob I hadn't actually checked but add usepackage{xparse} and replace newcommand by NewDocumentCommand and you get ! LaTeX3 Error: First argument of 'NewDocumentCommand' must be a command.

    – David Carlisle
    5 hours ago
















16














If LaTeX was being written now,



newcommand{printit[1]}{#1}


would give an error message that printit[1] was not a single token.



The correct syntax is



newcommand{printit}[1]{#1}


or



newcommandprintit[1]{#1}


LaTeX does nothing special to allow both forms, it is just on the general TeX macro syntax rules that braces can be omitted if a macro argument is a single token.



If you pass two (or in this case, four) tokens to newcommand then anything that happens is essentially just accidental behaviour, as the system could not really afford the space or time required to catch "unlikely" errors.



As to what happens,



documentclass{article}

begin{document}

newcommand{printit[1]}{#1}

showprintit
expandaftershowcsnamestringprintitendcsname
end{document}


produces the terminal log



> printit=macro:
->@protected@testopt printit \printit {0}.
l.7 showprintit

?
> \printit=long macro:
[#1]->#1.


The command defines printit to have an optional first argument, although the default value of 0 being supplied was intended as the default value for newcommand itself.
it is what makes newcommandfoo the same as newcommandfoo[0] and define a command with no arguments.



The inner part of the command handling the optional argument is \printit which just drops the square brackets.



So



 printit{2}


is



 printit[0]{2}


which is



0{2}


which typesets as 02






share|improve this answer


























  • Thanks for a thorough explanation!

    – Mad Hatter
    15 hours ago











  • What about LaTeX3, which is being written now? ;-)

    – Socob
    11 hours ago






  • 1





    @Socob I hadn't actually checked but add usepackage{xparse} and replace newcommand by NewDocumentCommand and you get ! LaTeX3 Error: First argument of 'NewDocumentCommand' must be a command.

    – David Carlisle
    5 hours ago














16












16








16







If LaTeX was being written now,



newcommand{printit[1]}{#1}


would give an error message that printit[1] was not a single token.



The correct syntax is



newcommand{printit}[1]{#1}


or



newcommandprintit[1]{#1}


LaTeX does nothing special to allow both forms, it is just on the general TeX macro syntax rules that braces can be omitted if a macro argument is a single token.



If you pass two (or in this case, four) tokens to newcommand then anything that happens is essentially just accidental behaviour, as the system could not really afford the space or time required to catch "unlikely" errors.



As to what happens,



documentclass{article}

begin{document}

newcommand{printit[1]}{#1}

showprintit
expandaftershowcsnamestringprintitendcsname
end{document}


produces the terminal log



> printit=macro:
->@protected@testopt printit \printit {0}.
l.7 showprintit

?
> \printit=long macro:
[#1]->#1.


The command defines printit to have an optional first argument, although the default value of 0 being supplied was intended as the default value for newcommand itself.
it is what makes newcommandfoo the same as newcommandfoo[0] and define a command with no arguments.



The inner part of the command handling the optional argument is \printit which just drops the square brackets.



So



 printit{2}


is



 printit[0]{2}


which is



0{2}


which typesets as 02






share|improve this answer















If LaTeX was being written now,



newcommand{printit[1]}{#1}


would give an error message that printit[1] was not a single token.



The correct syntax is



newcommand{printit}[1]{#1}


or



newcommandprintit[1]{#1}


LaTeX does nothing special to allow both forms, it is just on the general TeX macro syntax rules that braces can be omitted if a macro argument is a single token.



If you pass two (or in this case, four) tokens to newcommand then anything that happens is essentially just accidental behaviour, as the system could not really afford the space or time required to catch "unlikely" errors.



As to what happens,



documentclass{article}

begin{document}

newcommand{printit[1]}{#1}

showprintit
expandaftershowcsnamestringprintitendcsname
end{document}


produces the terminal log



> printit=macro:
->@protected@testopt printit \printit {0}.
l.7 showprintit

?
> \printit=long macro:
[#1]->#1.


The command defines printit to have an optional first argument, although the default value of 0 being supplied was intended as the default value for newcommand itself.
it is what makes newcommandfoo the same as newcommandfoo[0] and define a command with no arguments.



The inner part of the command handling the optional argument is \printit which just drops the square brackets.



So



 printit{2}


is



 printit[0]{2}


which is



0{2}


which typesets as 02







share|improve this answer














share|improve this answer



share|improve this answer








edited 15 hours ago

























answered 16 hours ago









David CarlisleDavid Carlisle

485k4111201863




485k4111201863













  • Thanks for a thorough explanation!

    – Mad Hatter
    15 hours ago











  • What about LaTeX3, which is being written now? ;-)

    – Socob
    11 hours ago






  • 1





    @Socob I hadn't actually checked but add usepackage{xparse} and replace newcommand by NewDocumentCommand and you get ! LaTeX3 Error: First argument of 'NewDocumentCommand' must be a command.

    – David Carlisle
    5 hours ago



















  • Thanks for a thorough explanation!

    – Mad Hatter
    15 hours ago











  • What about LaTeX3, which is being written now? ;-)

    – Socob
    11 hours ago






  • 1





    @Socob I hadn't actually checked but add usepackage{xparse} and replace newcommand by NewDocumentCommand and you get ! LaTeX3 Error: First argument of 'NewDocumentCommand' must be a command.

    – David Carlisle
    5 hours ago

















Thanks for a thorough explanation!

– Mad Hatter
15 hours ago





Thanks for a thorough explanation!

– Mad Hatter
15 hours ago













What about LaTeX3, which is being written now? ;-)

– Socob
11 hours ago





What about LaTeX3, which is being written now? ;-)

– Socob
11 hours ago




1




1





@Socob I hadn't actually checked but add usepackage{xparse} and replace newcommand by NewDocumentCommand and you get ! LaTeX3 Error: First argument of 'NewDocumentCommand' must be a command.

– David Carlisle
5 hours ago





@Socob I hadn't actually checked but add usepackage{xparse} and replace newcommand by NewDocumentCommand and you get ! LaTeX3 Error: First argument of 'NewDocumentCommand' must be a command.

– David Carlisle
5 hours ago


















draft saved

draft discarded




















































Thanks for contributing an answer to TeX - LaTeX Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f469994%2fa-curious-dependency-between-newcommand-and-curly-braces%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Knooppunt Holsloot

Altaar (religie)

Gregoriusmis