Problems with def









up vote
8
down vote

favorite












I have created the following macros in LaTeX:



deftwomate(#1,#2,#3,#4)beginpmatrix#1&#2\#3&#4endpmatrix
defpwr(#1)^#1
deftwoclmn(#1,#2)beginpmatrix#1\#2endpmatrix


Where twomate is a 2x2 matrix, twoclmn creates a 2x1 column vector, and pwr is a command to raise the argument to the power.
However, if I try to do the following:



$$twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t) )$$


I get an error. However, if I replace the last entry with something that is not a def command:



$$twomate(3epwr(-3t),epwr(2t),-epwr(-3t),5 )$$


The document complies successfully. In addition, the following does not compile successfully:



$$twoclmn(frac625epwr(2t)-frac15tepwr(2t),-frac225epwr(2t) + frac25 t epwr(2t))$$


But the following does:



$$twoclmn(frac625e^2t-frac15te^2t,-frac225e^2t + frac25 t e^2t)$$


So the problem seems to be the nested def commands. How may I nest def commands, without the compiler complaining?










share|improve this question





















  • Since you're using LaTeX, please consider using [ ... ] instead of $$ ... $$, as the latter causes some inconsistencies.
    – AJFarmar
    Nov 10 at 13:14














up vote
8
down vote

favorite












I have created the following macros in LaTeX:



deftwomate(#1,#2,#3,#4)beginpmatrix#1&#2\#3&#4endpmatrix
defpwr(#1)^#1
deftwoclmn(#1,#2)beginpmatrix#1\#2endpmatrix


Where twomate is a 2x2 matrix, twoclmn creates a 2x1 column vector, and pwr is a command to raise the argument to the power.
However, if I try to do the following:



$$twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t) )$$


I get an error. However, if I replace the last entry with something that is not a def command:



$$twomate(3epwr(-3t),epwr(2t),-epwr(-3t),5 )$$


The document complies successfully. In addition, the following does not compile successfully:



$$twoclmn(frac625epwr(2t)-frac15tepwr(2t),-frac225epwr(2t) + frac25 t epwr(2t))$$


But the following does:



$$twoclmn(frac625e^2t-frac15te^2t,-frac225e^2t + frac25 t e^2t)$$


So the problem seems to be the nested def commands. How may I nest def commands, without the compiler complaining?










share|improve this question





















  • Since you're using LaTeX, please consider using [ ... ] instead of $$ ... $$, as the latter causes some inconsistencies.
    – AJFarmar
    Nov 10 at 13:14












up vote
8
down vote

favorite









up vote
8
down vote

favorite











I have created the following macros in LaTeX:



deftwomate(#1,#2,#3,#4)beginpmatrix#1&#2\#3&#4endpmatrix
defpwr(#1)^#1
deftwoclmn(#1,#2)beginpmatrix#1\#2endpmatrix


Where twomate is a 2x2 matrix, twoclmn creates a 2x1 column vector, and pwr is a command to raise the argument to the power.
However, if I try to do the following:



$$twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t) )$$


I get an error. However, if I replace the last entry with something that is not a def command:



$$twomate(3epwr(-3t),epwr(2t),-epwr(-3t),5 )$$


The document complies successfully. In addition, the following does not compile successfully:



$$twoclmn(frac625epwr(2t)-frac15tepwr(2t),-frac225epwr(2t) + frac25 t epwr(2t))$$


But the following does:



$$twoclmn(frac625e^2t-frac15te^2t,-frac225e^2t + frac25 t e^2t)$$


So the problem seems to be the nested def commands. How may I nest def commands, without the compiler complaining?










share|improve this question













I have created the following macros in LaTeX:



deftwomate(#1,#2,#3,#4)beginpmatrix#1&#2\#3&#4endpmatrix
defpwr(#1)^#1
deftwoclmn(#1,#2)beginpmatrix#1\#2endpmatrix


Where twomate is a 2x2 matrix, twoclmn creates a 2x1 column vector, and pwr is a command to raise the argument to the power.
However, if I try to do the following:



$$twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t) )$$


I get an error. However, if I replace the last entry with something that is not a def command:



$$twomate(3epwr(-3t),epwr(2t),-epwr(-3t),5 )$$


The document complies successfully. In addition, the following does not compile successfully:



$$twoclmn(frac625epwr(2t)-frac15tepwr(2t),-frac225epwr(2t) + frac25 t epwr(2t))$$


But the following does:



$$twoclmn(frac625e^2t-frac15te^2t,-frac225e^2t + frac25 t e^2t)$$


So the problem seems to be the nested def commands. How may I nest def commands, without the compiler complaining?







math-mode macros






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 9 at 22:49









Hossmeister

433




433











  • Since you're using LaTeX, please consider using [ ... ] instead of $$ ... $$, as the latter causes some inconsistencies.
    – AJFarmar
    Nov 10 at 13:14
















  • Since you're using LaTeX, please consider using [ ... ] instead of $$ ... $$, as the latter causes some inconsistencies.
    – AJFarmar
    Nov 10 at 13:14















Since you're using LaTeX, please consider using [ ... ] instead of $$ ... $$, as the latter causes some inconsistencies.
– AJFarmar
Nov 10 at 13:14




Since you're using LaTeX, please consider using [ ... ] instead of $$ ... $$, as the latter causes some inconsistencies.
– AJFarmar
Nov 10 at 13:14










4 Answers
4






active

oldest

votes

















up vote
12
down vote



accepted










You can use xparse for this job, because the r argument type takes care of nesting.



documentclassarticle
usepackageamsmath
usepackagexparse

NewDocumentCommandtwomate>SplitArgument3,r()%
maketwomate#1%

NewDocumentCommandmaketwomatemmmm%
beginpmatrix#1&#2\#3&#4endpmatrix%

NewDocumentCommandpwrr()^#1

begindocument

[
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t) )
]

enddocument


However, using () as delimiters doesn't seem a good idea. The following is as clear and behaves better with syntax coloring of front ends.



documentclassarticle
usepackageamsmath
usepackagexparse

NewDocumentCommandtwomate>SplitArgument3,m%
maketwomate#1%

NewDocumentCommandmaketwomatemmmm%
beginpmatrix#1&#2\#3&#4endpmatrix%

NewDocumentCommandpwrm^#1

begindocument

[
twomate3epwr-3t,epwr2t,-epwr-3t,-2epwr2t
]

enddocument


enter image description here






share|improve this answer




















  • can one nest like this foo(a,bar(b,c,d),baz(e,f),g) ?
    – jfbu
    Nov 10 at 16:11










  • @jfbu Yes, but why? There's no advantage whatsoever over braces.
    – egreg
    Nov 10 at 16:13










  • actually I now tried and it does not seem to work with the code you posted (LaTeX error: "xparse/split-excess-tokens"). So I guess you meant "yes it can be done", not "yes, it does it". Again I agree that TeX has its own syntax and trying to use another one (with all induced complications) is not the way to go for user macros.
    – jfbu
    Nov 10 at 16:50










  • @jfbu Without seeing how you define foo, bar and baz it's just guesswork.
    – egreg
    Nov 10 at 16:51










  • twomate(twomate(1,2,3,4),5,6,7), with NewDocumentCommandmaketwomatemmmm(#1+#2+#3+#4) in place of the definition in your code
    – jfbu
    Nov 10 at 16:52

















up vote
10
down vote













Your def contains a very specific sequence defined as the parameter text:



% 1 2 3 4 5
deftwomate(<1>,<2>,<3>,<4>) ...
% ^ ^ ^ ^ ^
% │ │ │ │ │
% │ └ comma ┘ │
% └─── bracket ───┘


This parameter text is matched exactly in order (almost like a first-come-first-served style) to extract the four arguments <1>, <2>, <3> and <4>. Here's how the elements are grabbed for twomate with the above notation:



% 1 2 3 4 5
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
% ^ ^ ^ ^ ^
% │ │ │ │ │
% │ └────── comma ────────┘ │
% └───────────────── bracket ──────────────────┘


It should be clear that the last bracket ) isn't properly captured for pwr. The way around it is to hide pwr(.) from twomate:



documentclassarticle

usepackageamsmath

deftwomate(#1,#2,#3,#4)beginpmatrix#1&#2\#3&#4endpmatrix
defpwr(#1)^#1

begindocument

[
twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
]

enddocument


This solves the problem only temporarily. If you nest elements, you'll run into similar problems because of the parameter text pattern matching. In general, it is safer to group arguments using ....






share|improve this answer





























    up vote
    6
    down vote













    TeX's delimited parameters parsing doesn't take nesting into account properly. So if you call twomate(3epwr(-3t), ...), the final ) for twomate isn't found at the end of that line but at the end of pwr(-3t). The improperly formed call of pwr then causes trouble.



    To hide nested calls of your commands, put them into ... groups (though this probably defeats the purpose):



    documentclassarticle
    usepackageamsmath

    deftwomate(#1,#2,#3,#4)beginpmatrix#1&#2\#3&#4endpmatrix
    defpwr(#1)^#1
    deftwoclmn(#1,#2)beginpmatrix#1\#2endpmatrix

    begindocument
    [ twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t)) ]
    enddocument


    enter image description here



    By the way, don't use $$ ... $$ for display math environments but LaTeX's or amsmath's variants like [ ... ].






    share|improve this answer





























      up vote
      2
      down vote













      Here is how to define macros expecting comma separated arguments enclosed in parentheses. The code converts any standard LaTeX command (macro with non-delimited parameters) into one expecting (..., ..., ...) input syntax. When used, the number of arguments must be the one expected by the macro, there is no error-checking.



      Nesting works, as we will test with this kind of input:



      foo(Bar(3,5,7),Bar(9,foo(a,Bar(W,X,Y),c,d),13),Bar(15,17,19),Bar(21,23,25))


      Attention that there is no special handling of spaces in the input, and also some brace-stripping may occur in certain circumstances.



      As this all works purely by expansion, expandable commands remain expandable commands.



      Important: for a fuller implementation of the analogy with "functional notation", the macro foo(a, b, c) should first expand completely the a, b, c before doing whatever it wants to do (if only for reasons of efficiency). But this would limit from the start such constructs to the realm of expandable macros. And furthermore, only the new expanded primitive allows (easy) such complete expansion. Else, one can make do restricting to only "first-fully" expandable macros using some romannumeral-`Q governed expansion (with a problem if macro expands to something starting with a space token.) Anyway, here I did not add the automatic expansion of a, b, c, before applying the foo macro, I stayed more on the side of usual macro expansion in TeX for things such as fooabc.



      documentclassarticle
      usepackageamsmath

      % copy over some utility code from package xintexpr
      catcode`_ 11

      makeatletter
      letxint_c_monem@ne
      letxint_c_z@
      letxint_c_i@ne
      longdefxint_bye #1xint_bye %
      makeatother
      % THE XINT_isbalanced_... MACROS COPIED OVER FROM XINTEXPR CODE MADE
      % HERE ALL long
      % % endmacrocode
      % subsubsectioncshXINT_isbalanced_a for cshnolabelXINT_expr_onliteral_seq_a
      % lverb|Expands to xint_c_mone in case a closing ) had no opening ( matching
      % it, to @ne if opening ( had no closing ) matching it, to z@ if expression
      % was balanced.|
      % beginmacrocode
      % use as XINT_isbalanced_a relax #1(xint_bye)xint_bye
      longdefXINT_isbalanced_a #1(XINT_isbalanced_b #1)xint_bye %
      longdefXINT_isbalanced_b #1)#2%
      xint_bye #2XINT_isbalanced_cxint_byeXINT_isbalanced_error %
      % endmacrocode
      % lverb|if #2 is not xint_bye, a ) was found, but there was no (. Hence error -> -1|
      % beginmacrocode
      longdefXINT_isbalanced_error #1)xint_bye xint_c_mone%
      % endmacrocode
      % lverb|#2 was xint_bye, was there a ) in original #1?|
      % beginmacrocode
      longdefXINT_isbalanced_cxint_byeXINT_isbalanced_error #1%
      xint_bye #1XINT_isbalanced_yesxint_byeXINT_isbalanced_d #1%
      % endmacrocode
      % lverb|#1 is xint_bye, there was never ( nor ) in original #1, hence OK.|
      % beginmacrocode
      longdefXINT_isbalanced_yesxint_byeXINT_isbalanced_dxint_bye )xint_bye xint_c_ %
      % endmacrocode
      % lverb|#1 is not xint_bye, there was indeed a ( in original #1. We check if
      % we see a ). If we do, we then loop until no ( nor ) is to be found.|
      % beginmacrocode
      longdefXINT_isbalanced_d #1)#2%
      xint_bye #2XINT_isbalanced_noxint_byeXINT_isbalanced_a #1#2%
      % endmacrocode
      % lverb|#2 was xint_bye, we did not find a closing ) in original #1. Error.|
      % beginmacrocode
      longdefXINT_isbalanced_noxint_bye #1xint_byexint_bye xint_c_i %

      % NEW EXPANDABLE UTILITY

      longdefapplyfunction #1#2)%
      %
      ifcaseXINT_isbalanced_a relax #1#2)(xint_bye)xint_bye
      expandafterapplyfunction_b
      orexpandafterapplyfunction_again
      elseexpandafterwe_are_doomed
      fi #1#2%
      %
      longdefapplyfunction_again #1applyfunction #1)%
      longdefmy_bbye #1my_bbye %
      longdefapplyfunction_b #1applyfunction_c #1,my_bbye,%
      longdefapplyfunction_c #1(applyfunction_d #1%
      % we will take care of brace removal another day
      longdefapplyfunction_d #1#2#3#4,%
      %
      ifcaseXINT_isbalanced_a relax #3#4(xint_bye)xint_bye
      expandafterapplyfunction_e
      orexpandafterapplyfunction_d_again
      elseexpandafterwe_are_doomed
      fi #1#2#3#4%
      %
      longdefapplyfunction_d_again #1#2#3#4%
      %
      applyfunction_d #1#2#3#4,%
      %
      longdefapplyfunction_e #1#2#3#4%
      %
      my_bbye#4applyfunction_finishmy_bbye
      applyfunction_g #1#2#3#4%
      %
      longdefapplyfunction_g #1#2#3applyfunction_d #1#2#3%
      longdefapplyfunction_finishmy_bbyeapplyfunction_g #1#2#3#1#2%

      catcode`_ 8

      %% USAGE
      % to define a "function" to be used as foo(a,b,c,...),
      % we need a foomacro which uses standard non-delimited parameters,
      % thus e.g. defined via newcommand, and then one only needs
      % newcommandfooapplyfunctionfoomacro
      % to get a foo to be used with parentheses.

      newcommandtwomateapplyfunctiontwomatemacro
      newcommandpwrapplyfunctionpwrmacro
      newcommandtwoclmnapplyfunctiontwoclmnmacro

      % define here the **non-delimited** auxiliary macros
      newcommandtwomatemacro[4]beginpmatrix#1&#2\#3&#4endpmatrix
      newcommandpwrmacro[1]^#1
      newcommandtwoclmnmacro[2]beginpmatrix#1\#2endpmatrix

      %% TESTING NESTING
      newcommandfooapplyfunctionfoomacro
      newcommandfoomacro[4]left[#1+#2+#3+#4right]
      letBarrelax
      newcommandBarapplyfunctionBarmacro
      newcommandBarmacro[3]left(#1*#2*#3right)

      delimiterfactor1001

      begindocument

      [
      twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
      ]
      [
      twoclmn(frac625epwr(2t)-frac15tepwr(2t),-frac225epwr(2t)
      + frac25 t epwr(2t))
      ]
      [foo(Bar(3,5,7),Bar(9,foo(a,Bar(W,X,Y),c,d),13),Bar(15,17,19),Bar(21,23,25))]
      enddocument


      enter image description here






      share|improve this answer






















        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',
        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%2f459229%2fproblems-with-def%23new-answer', 'question_page');

        );

        Post as a guest















        Required, but never shown

























        4 Answers
        4






        active

        oldest

        votes








        4 Answers
        4






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes








        up vote
        12
        down vote



        accepted










        You can use xparse for this job, because the r argument type takes care of nesting.



        documentclassarticle
        usepackageamsmath
        usepackagexparse

        NewDocumentCommandtwomate>SplitArgument3,r()%
        maketwomate#1%

        NewDocumentCommandmaketwomatemmmm%
        beginpmatrix#1&#2\#3&#4endpmatrix%

        NewDocumentCommandpwrr()^#1

        begindocument

        [
        twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t) )
        ]

        enddocument


        However, using () as delimiters doesn't seem a good idea. The following is as clear and behaves better with syntax coloring of front ends.



        documentclassarticle
        usepackageamsmath
        usepackagexparse

        NewDocumentCommandtwomate>SplitArgument3,m%
        maketwomate#1%

        NewDocumentCommandmaketwomatemmmm%
        beginpmatrix#1&#2\#3&#4endpmatrix%

        NewDocumentCommandpwrm^#1

        begindocument

        [
        twomate3epwr-3t,epwr2t,-epwr-3t,-2epwr2t
        ]

        enddocument


        enter image description here






        share|improve this answer




















        • can one nest like this foo(a,bar(b,c,d),baz(e,f),g) ?
          – jfbu
          Nov 10 at 16:11










        • @jfbu Yes, but why? There's no advantage whatsoever over braces.
          – egreg
          Nov 10 at 16:13










        • actually I now tried and it does not seem to work with the code you posted (LaTeX error: "xparse/split-excess-tokens"). So I guess you meant "yes it can be done", not "yes, it does it". Again I agree that TeX has its own syntax and trying to use another one (with all induced complications) is not the way to go for user macros.
          – jfbu
          Nov 10 at 16:50










        • @jfbu Without seeing how you define foo, bar and baz it's just guesswork.
          – egreg
          Nov 10 at 16:51










        • twomate(twomate(1,2,3,4),5,6,7), with NewDocumentCommandmaketwomatemmmm(#1+#2+#3+#4) in place of the definition in your code
          – jfbu
          Nov 10 at 16:52














        up vote
        12
        down vote



        accepted










        You can use xparse for this job, because the r argument type takes care of nesting.



        documentclassarticle
        usepackageamsmath
        usepackagexparse

        NewDocumentCommandtwomate>SplitArgument3,r()%
        maketwomate#1%

        NewDocumentCommandmaketwomatemmmm%
        beginpmatrix#1&#2\#3&#4endpmatrix%

        NewDocumentCommandpwrr()^#1

        begindocument

        [
        twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t) )
        ]

        enddocument


        However, using () as delimiters doesn't seem a good idea. The following is as clear and behaves better with syntax coloring of front ends.



        documentclassarticle
        usepackageamsmath
        usepackagexparse

        NewDocumentCommandtwomate>SplitArgument3,m%
        maketwomate#1%

        NewDocumentCommandmaketwomatemmmm%
        beginpmatrix#1&#2\#3&#4endpmatrix%

        NewDocumentCommandpwrm^#1

        begindocument

        [
        twomate3epwr-3t,epwr2t,-epwr-3t,-2epwr2t
        ]

        enddocument


        enter image description here






        share|improve this answer




















        • can one nest like this foo(a,bar(b,c,d),baz(e,f),g) ?
          – jfbu
          Nov 10 at 16:11










        • @jfbu Yes, but why? There's no advantage whatsoever over braces.
          – egreg
          Nov 10 at 16:13










        • actually I now tried and it does not seem to work with the code you posted (LaTeX error: "xparse/split-excess-tokens"). So I guess you meant "yes it can be done", not "yes, it does it". Again I agree that TeX has its own syntax and trying to use another one (with all induced complications) is not the way to go for user macros.
          – jfbu
          Nov 10 at 16:50










        • @jfbu Without seeing how you define foo, bar and baz it's just guesswork.
          – egreg
          Nov 10 at 16:51










        • twomate(twomate(1,2,3,4),5,6,7), with NewDocumentCommandmaketwomatemmmm(#1+#2+#3+#4) in place of the definition in your code
          – jfbu
          Nov 10 at 16:52












        up vote
        12
        down vote



        accepted







        up vote
        12
        down vote



        accepted






        You can use xparse for this job, because the r argument type takes care of nesting.



        documentclassarticle
        usepackageamsmath
        usepackagexparse

        NewDocumentCommandtwomate>SplitArgument3,r()%
        maketwomate#1%

        NewDocumentCommandmaketwomatemmmm%
        beginpmatrix#1&#2\#3&#4endpmatrix%

        NewDocumentCommandpwrr()^#1

        begindocument

        [
        twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t) )
        ]

        enddocument


        However, using () as delimiters doesn't seem a good idea. The following is as clear and behaves better with syntax coloring of front ends.



        documentclassarticle
        usepackageamsmath
        usepackagexparse

        NewDocumentCommandtwomate>SplitArgument3,m%
        maketwomate#1%

        NewDocumentCommandmaketwomatemmmm%
        beginpmatrix#1&#2\#3&#4endpmatrix%

        NewDocumentCommandpwrm^#1

        begindocument

        [
        twomate3epwr-3t,epwr2t,-epwr-3t,-2epwr2t
        ]

        enddocument


        enter image description here






        share|improve this answer












        You can use xparse for this job, because the r argument type takes care of nesting.



        documentclassarticle
        usepackageamsmath
        usepackagexparse

        NewDocumentCommandtwomate>SplitArgument3,r()%
        maketwomate#1%

        NewDocumentCommandmaketwomatemmmm%
        beginpmatrix#1&#2\#3&#4endpmatrix%

        NewDocumentCommandpwrr()^#1

        begindocument

        [
        twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t) )
        ]

        enddocument


        However, using () as delimiters doesn't seem a good idea. The following is as clear and behaves better with syntax coloring of front ends.



        documentclassarticle
        usepackageamsmath
        usepackagexparse

        NewDocumentCommandtwomate>SplitArgument3,m%
        maketwomate#1%

        NewDocumentCommandmaketwomatemmmm%
        beginpmatrix#1&#2\#3&#4endpmatrix%

        NewDocumentCommandpwrm^#1

        begindocument

        [
        twomate3epwr-3t,epwr2t,-epwr-3t,-2epwr2t
        ]

        enddocument


        enter image description here







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 10 at 0:13









        egreg

        701k8618673141




        701k8618673141











        • can one nest like this foo(a,bar(b,c,d),baz(e,f),g) ?
          – jfbu
          Nov 10 at 16:11










        • @jfbu Yes, but why? There's no advantage whatsoever over braces.
          – egreg
          Nov 10 at 16:13










        • actually I now tried and it does not seem to work with the code you posted (LaTeX error: "xparse/split-excess-tokens"). So I guess you meant "yes it can be done", not "yes, it does it". Again I agree that TeX has its own syntax and trying to use another one (with all induced complications) is not the way to go for user macros.
          – jfbu
          Nov 10 at 16:50










        • @jfbu Without seeing how you define foo, bar and baz it's just guesswork.
          – egreg
          Nov 10 at 16:51










        • twomate(twomate(1,2,3,4),5,6,7), with NewDocumentCommandmaketwomatemmmm(#1+#2+#3+#4) in place of the definition in your code
          – jfbu
          Nov 10 at 16:52
















        • can one nest like this foo(a,bar(b,c,d),baz(e,f),g) ?
          – jfbu
          Nov 10 at 16:11










        • @jfbu Yes, but why? There's no advantage whatsoever over braces.
          – egreg
          Nov 10 at 16:13










        • actually I now tried and it does not seem to work with the code you posted (LaTeX error: "xparse/split-excess-tokens"). So I guess you meant "yes it can be done", not "yes, it does it". Again I agree that TeX has its own syntax and trying to use another one (with all induced complications) is not the way to go for user macros.
          – jfbu
          Nov 10 at 16:50










        • @jfbu Without seeing how you define foo, bar and baz it's just guesswork.
          – egreg
          Nov 10 at 16:51










        • twomate(twomate(1,2,3,4),5,6,7), with NewDocumentCommandmaketwomatemmmm(#1+#2+#3+#4) in place of the definition in your code
          – jfbu
          Nov 10 at 16:52















        can one nest like this foo(a,bar(b,c,d),baz(e,f),g) ?
        – jfbu
        Nov 10 at 16:11




        can one nest like this foo(a,bar(b,c,d),baz(e,f),g) ?
        – jfbu
        Nov 10 at 16:11












        @jfbu Yes, but why? There's no advantage whatsoever over braces.
        – egreg
        Nov 10 at 16:13




        @jfbu Yes, but why? There's no advantage whatsoever over braces.
        – egreg
        Nov 10 at 16:13












        actually I now tried and it does not seem to work with the code you posted (LaTeX error: "xparse/split-excess-tokens"). So I guess you meant "yes it can be done", not "yes, it does it". Again I agree that TeX has its own syntax and trying to use another one (with all induced complications) is not the way to go for user macros.
        – jfbu
        Nov 10 at 16:50




        actually I now tried and it does not seem to work with the code you posted (LaTeX error: "xparse/split-excess-tokens"). So I guess you meant "yes it can be done", not "yes, it does it". Again I agree that TeX has its own syntax and trying to use another one (with all induced complications) is not the way to go for user macros.
        – jfbu
        Nov 10 at 16:50












        @jfbu Without seeing how you define foo, bar and baz it's just guesswork.
        – egreg
        Nov 10 at 16:51




        @jfbu Without seeing how you define foo, bar and baz it's just guesswork.
        – egreg
        Nov 10 at 16:51












        twomate(twomate(1,2,3,4),5,6,7), with NewDocumentCommandmaketwomatemmmm(#1+#2+#3+#4) in place of the definition in your code
        – jfbu
        Nov 10 at 16:52




        twomate(twomate(1,2,3,4),5,6,7), with NewDocumentCommandmaketwomatemmmm(#1+#2+#3+#4) in place of the definition in your code
        – jfbu
        Nov 10 at 16:52










        up vote
        10
        down vote













        Your def contains a very specific sequence defined as the parameter text:



        % 1 2 3 4 5
        deftwomate(<1>,<2>,<3>,<4>) ...
        % ^ ^ ^ ^ ^
        % │ │ │ │ │
        % │ └ comma ┘ │
        % └─── bracket ───┘


        This parameter text is matched exactly in order (almost like a first-come-first-served style) to extract the four arguments <1>, <2>, <3> and <4>. Here's how the elements are grabbed for twomate with the above notation:



        % 1 2 3 4 5
        twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
        % ^ ^ ^ ^ ^
        % │ │ │ │ │
        % │ └────── comma ────────┘ │
        % └───────────────── bracket ──────────────────┘


        It should be clear that the last bracket ) isn't properly captured for pwr. The way around it is to hide pwr(.) from twomate:



        documentclassarticle

        usepackageamsmath

        deftwomate(#1,#2,#3,#4)beginpmatrix#1&#2\#3&#4endpmatrix
        defpwr(#1)^#1

        begindocument

        [
        twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
        ]

        enddocument


        This solves the problem only temporarily. If you nest elements, you'll run into similar problems because of the parameter text pattern matching. In general, it is safer to group arguments using ....






        share|improve this answer


























          up vote
          10
          down vote













          Your def contains a very specific sequence defined as the parameter text:



          % 1 2 3 4 5
          deftwomate(<1>,<2>,<3>,<4>) ...
          % ^ ^ ^ ^ ^
          % │ │ │ │ │
          % │ └ comma ┘ │
          % └─── bracket ───┘


          This parameter text is matched exactly in order (almost like a first-come-first-served style) to extract the four arguments <1>, <2>, <3> and <4>. Here's how the elements are grabbed for twomate with the above notation:



          % 1 2 3 4 5
          twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
          % ^ ^ ^ ^ ^
          % │ │ │ │ │
          % │ └────── comma ────────┘ │
          % └───────────────── bracket ──────────────────┘


          It should be clear that the last bracket ) isn't properly captured for pwr. The way around it is to hide pwr(.) from twomate:



          documentclassarticle

          usepackageamsmath

          deftwomate(#1,#2,#3,#4)beginpmatrix#1&#2\#3&#4endpmatrix
          defpwr(#1)^#1

          begindocument

          [
          twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
          ]

          enddocument


          This solves the problem only temporarily. If you nest elements, you'll run into similar problems because of the parameter text pattern matching. In general, it is safer to group arguments using ....






          share|improve this answer
























            up vote
            10
            down vote










            up vote
            10
            down vote









            Your def contains a very specific sequence defined as the parameter text:



            % 1 2 3 4 5
            deftwomate(<1>,<2>,<3>,<4>) ...
            % ^ ^ ^ ^ ^
            % │ │ │ │ │
            % │ └ comma ┘ │
            % └─── bracket ───┘


            This parameter text is matched exactly in order (almost like a first-come-first-served style) to extract the four arguments <1>, <2>, <3> and <4>. Here's how the elements are grabbed for twomate with the above notation:



            % 1 2 3 4 5
            twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
            % ^ ^ ^ ^ ^
            % │ │ │ │ │
            % │ └────── comma ────────┘ │
            % └───────────────── bracket ──────────────────┘


            It should be clear that the last bracket ) isn't properly captured for pwr. The way around it is to hide pwr(.) from twomate:



            documentclassarticle

            usepackageamsmath

            deftwomate(#1,#2,#3,#4)beginpmatrix#1&#2\#3&#4endpmatrix
            defpwr(#1)^#1

            begindocument

            [
            twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
            ]

            enddocument


            This solves the problem only temporarily. If you nest elements, you'll run into similar problems because of the parameter text pattern matching. In general, it is safer to group arguments using ....






            share|improve this answer














            Your def contains a very specific sequence defined as the parameter text:



            % 1 2 3 4 5
            deftwomate(<1>,<2>,<3>,<4>) ...
            % ^ ^ ^ ^ ^
            % │ │ │ │ │
            % │ └ comma ┘ │
            % └─── bracket ───┘


            This parameter text is matched exactly in order (almost like a first-come-first-served style) to extract the four arguments <1>, <2>, <3> and <4>. Here's how the elements are grabbed for twomate with the above notation:



            % 1 2 3 4 5
            twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
            % ^ ^ ^ ^ ^
            % │ │ │ │ │
            % │ └────── comma ────────┘ │
            % └───────────────── bracket ──────────────────┘


            It should be clear that the last bracket ) isn't properly captured for pwr. The way around it is to hide pwr(.) from twomate:



            documentclassarticle

            usepackageamsmath

            deftwomate(#1,#2,#3,#4)beginpmatrix#1&#2\#3&#4endpmatrix
            defpwr(#1)^#1

            begindocument

            [
            twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
            ]

            enddocument


            This solves the problem only temporarily. If you nest elements, you'll run into similar problems because of the parameter text pattern matching. In general, it is safer to group arguments using ....







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 9 at 23:10

























            answered Nov 9 at 23:04









            Werner

            432k609511633




            432k609511633




















                up vote
                6
                down vote













                TeX's delimited parameters parsing doesn't take nesting into account properly. So if you call twomate(3epwr(-3t), ...), the final ) for twomate isn't found at the end of that line but at the end of pwr(-3t). The improperly formed call of pwr then causes trouble.



                To hide nested calls of your commands, put them into ... groups (though this probably defeats the purpose):



                documentclassarticle
                usepackageamsmath

                deftwomate(#1,#2,#3,#4)beginpmatrix#1&#2\#3&#4endpmatrix
                defpwr(#1)^#1
                deftwoclmn(#1,#2)beginpmatrix#1\#2endpmatrix

                begindocument
                [ twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t)) ]
                enddocument


                enter image description here



                By the way, don't use $$ ... $$ for display math environments but LaTeX's or amsmath's variants like [ ... ].






                share|improve this answer


























                  up vote
                  6
                  down vote













                  TeX's delimited parameters parsing doesn't take nesting into account properly. So if you call twomate(3epwr(-3t), ...), the final ) for twomate isn't found at the end of that line but at the end of pwr(-3t). The improperly formed call of pwr then causes trouble.



                  To hide nested calls of your commands, put them into ... groups (though this probably defeats the purpose):



                  documentclassarticle
                  usepackageamsmath

                  deftwomate(#1,#2,#3,#4)beginpmatrix#1&#2\#3&#4endpmatrix
                  defpwr(#1)^#1
                  deftwoclmn(#1,#2)beginpmatrix#1\#2endpmatrix

                  begindocument
                  [ twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t)) ]
                  enddocument


                  enter image description here



                  By the way, don't use $$ ... $$ for display math environments but LaTeX's or amsmath's variants like [ ... ].






                  share|improve this answer
























                    up vote
                    6
                    down vote










                    up vote
                    6
                    down vote









                    TeX's delimited parameters parsing doesn't take nesting into account properly. So if you call twomate(3epwr(-3t), ...), the final ) for twomate isn't found at the end of that line but at the end of pwr(-3t). The improperly formed call of pwr then causes trouble.



                    To hide nested calls of your commands, put them into ... groups (though this probably defeats the purpose):



                    documentclassarticle
                    usepackageamsmath

                    deftwomate(#1,#2,#3,#4)beginpmatrix#1&#2\#3&#4endpmatrix
                    defpwr(#1)^#1
                    deftwoclmn(#1,#2)beginpmatrix#1\#2endpmatrix

                    begindocument
                    [ twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t)) ]
                    enddocument


                    enter image description here



                    By the way, don't use $$ ... $$ for display math environments but LaTeX's or amsmath's variants like [ ... ].






                    share|improve this answer














                    TeX's delimited parameters parsing doesn't take nesting into account properly. So if you call twomate(3epwr(-3t), ...), the final ) for twomate isn't found at the end of that line but at the end of pwr(-3t). The improperly formed call of pwr then causes trouble.



                    To hide nested calls of your commands, put them into ... groups (though this probably defeats the purpose):



                    documentclassarticle
                    usepackageamsmath

                    deftwomate(#1,#2,#3,#4)beginpmatrix#1&#2\#3&#4endpmatrix
                    defpwr(#1)^#1
                    deftwoclmn(#1,#2)beginpmatrix#1\#2endpmatrix

                    begindocument
                    [ twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t)) ]
                    enddocument


                    enter image description here



                    By the way, don't use $$ ... $$ for display math environments but LaTeX's or amsmath's variants like [ ... ].







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Nov 9 at 23:11

























                    answered Nov 9 at 23:00









                    siracusa

                    4,48011127




                    4,48011127




















                        up vote
                        2
                        down vote













                        Here is how to define macros expecting comma separated arguments enclosed in parentheses. The code converts any standard LaTeX command (macro with non-delimited parameters) into one expecting (..., ..., ...) input syntax. When used, the number of arguments must be the one expected by the macro, there is no error-checking.



                        Nesting works, as we will test with this kind of input:



                        foo(Bar(3,5,7),Bar(9,foo(a,Bar(W,X,Y),c,d),13),Bar(15,17,19),Bar(21,23,25))


                        Attention that there is no special handling of spaces in the input, and also some brace-stripping may occur in certain circumstances.



                        As this all works purely by expansion, expandable commands remain expandable commands.



                        Important: for a fuller implementation of the analogy with "functional notation", the macro foo(a, b, c) should first expand completely the a, b, c before doing whatever it wants to do (if only for reasons of efficiency). But this would limit from the start such constructs to the realm of expandable macros. And furthermore, only the new expanded primitive allows (easy) such complete expansion. Else, one can make do restricting to only "first-fully" expandable macros using some romannumeral-`Q governed expansion (with a problem if macro expands to something starting with a space token.) Anyway, here I did not add the automatic expansion of a, b, c, before applying the foo macro, I stayed more on the side of usual macro expansion in TeX for things such as fooabc.



                        documentclassarticle
                        usepackageamsmath

                        % copy over some utility code from package xintexpr
                        catcode`_ 11

                        makeatletter
                        letxint_c_monem@ne
                        letxint_c_z@
                        letxint_c_i@ne
                        longdefxint_bye #1xint_bye %
                        makeatother
                        % THE XINT_isbalanced_... MACROS COPIED OVER FROM XINTEXPR CODE MADE
                        % HERE ALL long
                        % % endmacrocode
                        % subsubsectioncshXINT_isbalanced_a for cshnolabelXINT_expr_onliteral_seq_a
                        % lverb|Expands to xint_c_mone in case a closing ) had no opening ( matching
                        % it, to @ne if opening ( had no closing ) matching it, to z@ if expression
                        % was balanced.|
                        % beginmacrocode
                        % use as XINT_isbalanced_a relax #1(xint_bye)xint_bye
                        longdefXINT_isbalanced_a #1(XINT_isbalanced_b #1)xint_bye %
                        longdefXINT_isbalanced_b #1)#2%
                        xint_bye #2XINT_isbalanced_cxint_byeXINT_isbalanced_error %
                        % endmacrocode
                        % lverb|if #2 is not xint_bye, a ) was found, but there was no (. Hence error -> -1|
                        % beginmacrocode
                        longdefXINT_isbalanced_error #1)xint_bye xint_c_mone%
                        % endmacrocode
                        % lverb|#2 was xint_bye, was there a ) in original #1?|
                        % beginmacrocode
                        longdefXINT_isbalanced_cxint_byeXINT_isbalanced_error #1%
                        xint_bye #1XINT_isbalanced_yesxint_byeXINT_isbalanced_d #1%
                        % endmacrocode
                        % lverb|#1 is xint_bye, there was never ( nor ) in original #1, hence OK.|
                        % beginmacrocode
                        longdefXINT_isbalanced_yesxint_byeXINT_isbalanced_dxint_bye )xint_bye xint_c_ %
                        % endmacrocode
                        % lverb|#1 is not xint_bye, there was indeed a ( in original #1. We check if
                        % we see a ). If we do, we then loop until no ( nor ) is to be found.|
                        % beginmacrocode
                        longdefXINT_isbalanced_d #1)#2%
                        xint_bye #2XINT_isbalanced_noxint_byeXINT_isbalanced_a #1#2%
                        % endmacrocode
                        % lverb|#2 was xint_bye, we did not find a closing ) in original #1. Error.|
                        % beginmacrocode
                        longdefXINT_isbalanced_noxint_bye #1xint_byexint_bye xint_c_i %

                        % NEW EXPANDABLE UTILITY

                        longdefapplyfunction #1#2)%
                        %
                        ifcaseXINT_isbalanced_a relax #1#2)(xint_bye)xint_bye
                        expandafterapplyfunction_b
                        orexpandafterapplyfunction_again
                        elseexpandafterwe_are_doomed
                        fi #1#2%
                        %
                        longdefapplyfunction_again #1applyfunction #1)%
                        longdefmy_bbye #1my_bbye %
                        longdefapplyfunction_b #1applyfunction_c #1,my_bbye,%
                        longdefapplyfunction_c #1(applyfunction_d #1%
                        % we will take care of brace removal another day
                        longdefapplyfunction_d #1#2#3#4,%
                        %
                        ifcaseXINT_isbalanced_a relax #3#4(xint_bye)xint_bye
                        expandafterapplyfunction_e
                        orexpandafterapplyfunction_d_again
                        elseexpandafterwe_are_doomed
                        fi #1#2#3#4%
                        %
                        longdefapplyfunction_d_again #1#2#3#4%
                        %
                        applyfunction_d #1#2#3#4,%
                        %
                        longdefapplyfunction_e #1#2#3#4%
                        %
                        my_bbye#4applyfunction_finishmy_bbye
                        applyfunction_g #1#2#3#4%
                        %
                        longdefapplyfunction_g #1#2#3applyfunction_d #1#2#3%
                        longdefapplyfunction_finishmy_bbyeapplyfunction_g #1#2#3#1#2%

                        catcode`_ 8

                        %% USAGE
                        % to define a "function" to be used as foo(a,b,c,...),
                        % we need a foomacro which uses standard non-delimited parameters,
                        % thus e.g. defined via newcommand, and then one only needs
                        % newcommandfooapplyfunctionfoomacro
                        % to get a foo to be used with parentheses.

                        newcommandtwomateapplyfunctiontwomatemacro
                        newcommandpwrapplyfunctionpwrmacro
                        newcommandtwoclmnapplyfunctiontwoclmnmacro

                        % define here the **non-delimited** auxiliary macros
                        newcommandtwomatemacro[4]beginpmatrix#1&#2\#3&#4endpmatrix
                        newcommandpwrmacro[1]^#1
                        newcommandtwoclmnmacro[2]beginpmatrix#1\#2endpmatrix

                        %% TESTING NESTING
                        newcommandfooapplyfunctionfoomacro
                        newcommandfoomacro[4]left[#1+#2+#3+#4right]
                        letBarrelax
                        newcommandBarapplyfunctionBarmacro
                        newcommandBarmacro[3]left(#1*#2*#3right)

                        delimiterfactor1001

                        begindocument

                        [
                        twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
                        ]
                        [
                        twoclmn(frac625epwr(2t)-frac15tepwr(2t),-frac225epwr(2t)
                        + frac25 t epwr(2t))
                        ]
                        [foo(Bar(3,5,7),Bar(9,foo(a,Bar(W,X,Y),c,d),13),Bar(15,17,19),Bar(21,23,25))]
                        enddocument


                        enter image description here






                        share|improve this answer


























                          up vote
                          2
                          down vote













                          Here is how to define macros expecting comma separated arguments enclosed in parentheses. The code converts any standard LaTeX command (macro with non-delimited parameters) into one expecting (..., ..., ...) input syntax. When used, the number of arguments must be the one expected by the macro, there is no error-checking.



                          Nesting works, as we will test with this kind of input:



                          foo(Bar(3,5,7),Bar(9,foo(a,Bar(W,X,Y),c,d),13),Bar(15,17,19),Bar(21,23,25))


                          Attention that there is no special handling of spaces in the input, and also some brace-stripping may occur in certain circumstances.



                          As this all works purely by expansion, expandable commands remain expandable commands.



                          Important: for a fuller implementation of the analogy with "functional notation", the macro foo(a, b, c) should first expand completely the a, b, c before doing whatever it wants to do (if only for reasons of efficiency). But this would limit from the start such constructs to the realm of expandable macros. And furthermore, only the new expanded primitive allows (easy) such complete expansion. Else, one can make do restricting to only "first-fully" expandable macros using some romannumeral-`Q governed expansion (with a problem if macro expands to something starting with a space token.) Anyway, here I did not add the automatic expansion of a, b, c, before applying the foo macro, I stayed more on the side of usual macro expansion in TeX for things such as fooabc.



                          documentclassarticle
                          usepackageamsmath

                          % copy over some utility code from package xintexpr
                          catcode`_ 11

                          makeatletter
                          letxint_c_monem@ne
                          letxint_c_z@
                          letxint_c_i@ne
                          longdefxint_bye #1xint_bye %
                          makeatother
                          % THE XINT_isbalanced_... MACROS COPIED OVER FROM XINTEXPR CODE MADE
                          % HERE ALL long
                          % % endmacrocode
                          % subsubsectioncshXINT_isbalanced_a for cshnolabelXINT_expr_onliteral_seq_a
                          % lverb|Expands to xint_c_mone in case a closing ) had no opening ( matching
                          % it, to @ne if opening ( had no closing ) matching it, to z@ if expression
                          % was balanced.|
                          % beginmacrocode
                          % use as XINT_isbalanced_a relax #1(xint_bye)xint_bye
                          longdefXINT_isbalanced_a #1(XINT_isbalanced_b #1)xint_bye %
                          longdefXINT_isbalanced_b #1)#2%
                          xint_bye #2XINT_isbalanced_cxint_byeXINT_isbalanced_error %
                          % endmacrocode
                          % lverb|if #2 is not xint_bye, a ) was found, but there was no (. Hence error -> -1|
                          % beginmacrocode
                          longdefXINT_isbalanced_error #1)xint_bye xint_c_mone%
                          % endmacrocode
                          % lverb|#2 was xint_bye, was there a ) in original #1?|
                          % beginmacrocode
                          longdefXINT_isbalanced_cxint_byeXINT_isbalanced_error #1%
                          xint_bye #1XINT_isbalanced_yesxint_byeXINT_isbalanced_d #1%
                          % endmacrocode
                          % lverb|#1 is xint_bye, there was never ( nor ) in original #1, hence OK.|
                          % beginmacrocode
                          longdefXINT_isbalanced_yesxint_byeXINT_isbalanced_dxint_bye )xint_bye xint_c_ %
                          % endmacrocode
                          % lverb|#1 is not xint_bye, there was indeed a ( in original #1. We check if
                          % we see a ). If we do, we then loop until no ( nor ) is to be found.|
                          % beginmacrocode
                          longdefXINT_isbalanced_d #1)#2%
                          xint_bye #2XINT_isbalanced_noxint_byeXINT_isbalanced_a #1#2%
                          % endmacrocode
                          % lverb|#2 was xint_bye, we did not find a closing ) in original #1. Error.|
                          % beginmacrocode
                          longdefXINT_isbalanced_noxint_bye #1xint_byexint_bye xint_c_i %

                          % NEW EXPANDABLE UTILITY

                          longdefapplyfunction #1#2)%
                          %
                          ifcaseXINT_isbalanced_a relax #1#2)(xint_bye)xint_bye
                          expandafterapplyfunction_b
                          orexpandafterapplyfunction_again
                          elseexpandafterwe_are_doomed
                          fi #1#2%
                          %
                          longdefapplyfunction_again #1applyfunction #1)%
                          longdefmy_bbye #1my_bbye %
                          longdefapplyfunction_b #1applyfunction_c #1,my_bbye,%
                          longdefapplyfunction_c #1(applyfunction_d #1%
                          % we will take care of brace removal another day
                          longdefapplyfunction_d #1#2#3#4,%
                          %
                          ifcaseXINT_isbalanced_a relax #3#4(xint_bye)xint_bye
                          expandafterapplyfunction_e
                          orexpandafterapplyfunction_d_again
                          elseexpandafterwe_are_doomed
                          fi #1#2#3#4%
                          %
                          longdefapplyfunction_d_again #1#2#3#4%
                          %
                          applyfunction_d #1#2#3#4,%
                          %
                          longdefapplyfunction_e #1#2#3#4%
                          %
                          my_bbye#4applyfunction_finishmy_bbye
                          applyfunction_g #1#2#3#4%
                          %
                          longdefapplyfunction_g #1#2#3applyfunction_d #1#2#3%
                          longdefapplyfunction_finishmy_bbyeapplyfunction_g #1#2#3#1#2%

                          catcode`_ 8

                          %% USAGE
                          % to define a "function" to be used as foo(a,b,c,...),
                          % we need a foomacro which uses standard non-delimited parameters,
                          % thus e.g. defined via newcommand, and then one only needs
                          % newcommandfooapplyfunctionfoomacro
                          % to get a foo to be used with parentheses.

                          newcommandtwomateapplyfunctiontwomatemacro
                          newcommandpwrapplyfunctionpwrmacro
                          newcommandtwoclmnapplyfunctiontwoclmnmacro

                          % define here the **non-delimited** auxiliary macros
                          newcommandtwomatemacro[4]beginpmatrix#1&#2\#3&#4endpmatrix
                          newcommandpwrmacro[1]^#1
                          newcommandtwoclmnmacro[2]beginpmatrix#1\#2endpmatrix

                          %% TESTING NESTING
                          newcommandfooapplyfunctionfoomacro
                          newcommandfoomacro[4]left[#1+#2+#3+#4right]
                          letBarrelax
                          newcommandBarapplyfunctionBarmacro
                          newcommandBarmacro[3]left(#1*#2*#3right)

                          delimiterfactor1001

                          begindocument

                          [
                          twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
                          ]
                          [
                          twoclmn(frac625epwr(2t)-frac15tepwr(2t),-frac225epwr(2t)
                          + frac25 t epwr(2t))
                          ]
                          [foo(Bar(3,5,7),Bar(9,foo(a,Bar(W,X,Y),c,d),13),Bar(15,17,19),Bar(21,23,25))]
                          enddocument


                          enter image description here






                          share|improve this answer
























                            up vote
                            2
                            down vote










                            up vote
                            2
                            down vote









                            Here is how to define macros expecting comma separated arguments enclosed in parentheses. The code converts any standard LaTeX command (macro with non-delimited parameters) into one expecting (..., ..., ...) input syntax. When used, the number of arguments must be the one expected by the macro, there is no error-checking.



                            Nesting works, as we will test with this kind of input:



                            foo(Bar(3,5,7),Bar(9,foo(a,Bar(W,X,Y),c,d),13),Bar(15,17,19),Bar(21,23,25))


                            Attention that there is no special handling of spaces in the input, and also some brace-stripping may occur in certain circumstances.



                            As this all works purely by expansion, expandable commands remain expandable commands.



                            Important: for a fuller implementation of the analogy with "functional notation", the macro foo(a, b, c) should first expand completely the a, b, c before doing whatever it wants to do (if only for reasons of efficiency). But this would limit from the start such constructs to the realm of expandable macros. And furthermore, only the new expanded primitive allows (easy) such complete expansion. Else, one can make do restricting to only "first-fully" expandable macros using some romannumeral-`Q governed expansion (with a problem if macro expands to something starting with a space token.) Anyway, here I did not add the automatic expansion of a, b, c, before applying the foo macro, I stayed more on the side of usual macro expansion in TeX for things such as fooabc.



                            documentclassarticle
                            usepackageamsmath

                            % copy over some utility code from package xintexpr
                            catcode`_ 11

                            makeatletter
                            letxint_c_monem@ne
                            letxint_c_z@
                            letxint_c_i@ne
                            longdefxint_bye #1xint_bye %
                            makeatother
                            % THE XINT_isbalanced_... MACROS COPIED OVER FROM XINTEXPR CODE MADE
                            % HERE ALL long
                            % % endmacrocode
                            % subsubsectioncshXINT_isbalanced_a for cshnolabelXINT_expr_onliteral_seq_a
                            % lverb|Expands to xint_c_mone in case a closing ) had no opening ( matching
                            % it, to @ne if opening ( had no closing ) matching it, to z@ if expression
                            % was balanced.|
                            % beginmacrocode
                            % use as XINT_isbalanced_a relax #1(xint_bye)xint_bye
                            longdefXINT_isbalanced_a #1(XINT_isbalanced_b #1)xint_bye %
                            longdefXINT_isbalanced_b #1)#2%
                            xint_bye #2XINT_isbalanced_cxint_byeXINT_isbalanced_error %
                            % endmacrocode
                            % lverb|if #2 is not xint_bye, a ) was found, but there was no (. Hence error -> -1|
                            % beginmacrocode
                            longdefXINT_isbalanced_error #1)xint_bye xint_c_mone%
                            % endmacrocode
                            % lverb|#2 was xint_bye, was there a ) in original #1?|
                            % beginmacrocode
                            longdefXINT_isbalanced_cxint_byeXINT_isbalanced_error #1%
                            xint_bye #1XINT_isbalanced_yesxint_byeXINT_isbalanced_d #1%
                            % endmacrocode
                            % lverb|#1 is xint_bye, there was never ( nor ) in original #1, hence OK.|
                            % beginmacrocode
                            longdefXINT_isbalanced_yesxint_byeXINT_isbalanced_dxint_bye )xint_bye xint_c_ %
                            % endmacrocode
                            % lverb|#1 is not xint_bye, there was indeed a ( in original #1. We check if
                            % we see a ). If we do, we then loop until no ( nor ) is to be found.|
                            % beginmacrocode
                            longdefXINT_isbalanced_d #1)#2%
                            xint_bye #2XINT_isbalanced_noxint_byeXINT_isbalanced_a #1#2%
                            % endmacrocode
                            % lverb|#2 was xint_bye, we did not find a closing ) in original #1. Error.|
                            % beginmacrocode
                            longdefXINT_isbalanced_noxint_bye #1xint_byexint_bye xint_c_i %

                            % NEW EXPANDABLE UTILITY

                            longdefapplyfunction #1#2)%
                            %
                            ifcaseXINT_isbalanced_a relax #1#2)(xint_bye)xint_bye
                            expandafterapplyfunction_b
                            orexpandafterapplyfunction_again
                            elseexpandafterwe_are_doomed
                            fi #1#2%
                            %
                            longdefapplyfunction_again #1applyfunction #1)%
                            longdefmy_bbye #1my_bbye %
                            longdefapplyfunction_b #1applyfunction_c #1,my_bbye,%
                            longdefapplyfunction_c #1(applyfunction_d #1%
                            % we will take care of brace removal another day
                            longdefapplyfunction_d #1#2#3#4,%
                            %
                            ifcaseXINT_isbalanced_a relax #3#4(xint_bye)xint_bye
                            expandafterapplyfunction_e
                            orexpandafterapplyfunction_d_again
                            elseexpandafterwe_are_doomed
                            fi #1#2#3#4%
                            %
                            longdefapplyfunction_d_again #1#2#3#4%
                            %
                            applyfunction_d #1#2#3#4,%
                            %
                            longdefapplyfunction_e #1#2#3#4%
                            %
                            my_bbye#4applyfunction_finishmy_bbye
                            applyfunction_g #1#2#3#4%
                            %
                            longdefapplyfunction_g #1#2#3applyfunction_d #1#2#3%
                            longdefapplyfunction_finishmy_bbyeapplyfunction_g #1#2#3#1#2%

                            catcode`_ 8

                            %% USAGE
                            % to define a "function" to be used as foo(a,b,c,...),
                            % we need a foomacro which uses standard non-delimited parameters,
                            % thus e.g. defined via newcommand, and then one only needs
                            % newcommandfooapplyfunctionfoomacro
                            % to get a foo to be used with parentheses.

                            newcommandtwomateapplyfunctiontwomatemacro
                            newcommandpwrapplyfunctionpwrmacro
                            newcommandtwoclmnapplyfunctiontwoclmnmacro

                            % define here the **non-delimited** auxiliary macros
                            newcommandtwomatemacro[4]beginpmatrix#1&#2\#3&#4endpmatrix
                            newcommandpwrmacro[1]^#1
                            newcommandtwoclmnmacro[2]beginpmatrix#1\#2endpmatrix

                            %% TESTING NESTING
                            newcommandfooapplyfunctionfoomacro
                            newcommandfoomacro[4]left[#1+#2+#3+#4right]
                            letBarrelax
                            newcommandBarapplyfunctionBarmacro
                            newcommandBarmacro[3]left(#1*#2*#3right)

                            delimiterfactor1001

                            begindocument

                            [
                            twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
                            ]
                            [
                            twoclmn(frac625epwr(2t)-frac15tepwr(2t),-frac225epwr(2t)
                            + frac25 t epwr(2t))
                            ]
                            [foo(Bar(3,5,7),Bar(9,foo(a,Bar(W,X,Y),c,d),13),Bar(15,17,19),Bar(21,23,25))]
                            enddocument


                            enter image description here






                            share|improve this answer














                            Here is how to define macros expecting comma separated arguments enclosed in parentheses. The code converts any standard LaTeX command (macro with non-delimited parameters) into one expecting (..., ..., ...) input syntax. When used, the number of arguments must be the one expected by the macro, there is no error-checking.



                            Nesting works, as we will test with this kind of input:



                            foo(Bar(3,5,7),Bar(9,foo(a,Bar(W,X,Y),c,d),13),Bar(15,17,19),Bar(21,23,25))


                            Attention that there is no special handling of spaces in the input, and also some brace-stripping may occur in certain circumstances.



                            As this all works purely by expansion, expandable commands remain expandable commands.



                            Important: for a fuller implementation of the analogy with "functional notation", the macro foo(a, b, c) should first expand completely the a, b, c before doing whatever it wants to do (if only for reasons of efficiency). But this would limit from the start such constructs to the realm of expandable macros. And furthermore, only the new expanded primitive allows (easy) such complete expansion. Else, one can make do restricting to only "first-fully" expandable macros using some romannumeral-`Q governed expansion (with a problem if macro expands to something starting with a space token.) Anyway, here I did not add the automatic expansion of a, b, c, before applying the foo macro, I stayed more on the side of usual macro expansion in TeX for things such as fooabc.



                            documentclassarticle
                            usepackageamsmath

                            % copy over some utility code from package xintexpr
                            catcode`_ 11

                            makeatletter
                            letxint_c_monem@ne
                            letxint_c_z@
                            letxint_c_i@ne
                            longdefxint_bye #1xint_bye %
                            makeatother
                            % THE XINT_isbalanced_... MACROS COPIED OVER FROM XINTEXPR CODE MADE
                            % HERE ALL long
                            % % endmacrocode
                            % subsubsectioncshXINT_isbalanced_a for cshnolabelXINT_expr_onliteral_seq_a
                            % lverb|Expands to xint_c_mone in case a closing ) had no opening ( matching
                            % it, to @ne if opening ( had no closing ) matching it, to z@ if expression
                            % was balanced.|
                            % beginmacrocode
                            % use as XINT_isbalanced_a relax #1(xint_bye)xint_bye
                            longdefXINT_isbalanced_a #1(XINT_isbalanced_b #1)xint_bye %
                            longdefXINT_isbalanced_b #1)#2%
                            xint_bye #2XINT_isbalanced_cxint_byeXINT_isbalanced_error %
                            % endmacrocode
                            % lverb|if #2 is not xint_bye, a ) was found, but there was no (. Hence error -> -1|
                            % beginmacrocode
                            longdefXINT_isbalanced_error #1)xint_bye xint_c_mone%
                            % endmacrocode
                            % lverb|#2 was xint_bye, was there a ) in original #1?|
                            % beginmacrocode
                            longdefXINT_isbalanced_cxint_byeXINT_isbalanced_error #1%
                            xint_bye #1XINT_isbalanced_yesxint_byeXINT_isbalanced_d #1%
                            % endmacrocode
                            % lverb|#1 is xint_bye, there was never ( nor ) in original #1, hence OK.|
                            % beginmacrocode
                            longdefXINT_isbalanced_yesxint_byeXINT_isbalanced_dxint_bye )xint_bye xint_c_ %
                            % endmacrocode
                            % lverb|#1 is not xint_bye, there was indeed a ( in original #1. We check if
                            % we see a ). If we do, we then loop until no ( nor ) is to be found.|
                            % beginmacrocode
                            longdefXINT_isbalanced_d #1)#2%
                            xint_bye #2XINT_isbalanced_noxint_byeXINT_isbalanced_a #1#2%
                            % endmacrocode
                            % lverb|#2 was xint_bye, we did not find a closing ) in original #1. Error.|
                            % beginmacrocode
                            longdefXINT_isbalanced_noxint_bye #1xint_byexint_bye xint_c_i %

                            % NEW EXPANDABLE UTILITY

                            longdefapplyfunction #1#2)%
                            %
                            ifcaseXINT_isbalanced_a relax #1#2)(xint_bye)xint_bye
                            expandafterapplyfunction_b
                            orexpandafterapplyfunction_again
                            elseexpandafterwe_are_doomed
                            fi #1#2%
                            %
                            longdefapplyfunction_again #1applyfunction #1)%
                            longdefmy_bbye #1my_bbye %
                            longdefapplyfunction_b #1applyfunction_c #1,my_bbye,%
                            longdefapplyfunction_c #1(applyfunction_d #1%
                            % we will take care of brace removal another day
                            longdefapplyfunction_d #1#2#3#4,%
                            %
                            ifcaseXINT_isbalanced_a relax #3#4(xint_bye)xint_bye
                            expandafterapplyfunction_e
                            orexpandafterapplyfunction_d_again
                            elseexpandafterwe_are_doomed
                            fi #1#2#3#4%
                            %
                            longdefapplyfunction_d_again #1#2#3#4%
                            %
                            applyfunction_d #1#2#3#4,%
                            %
                            longdefapplyfunction_e #1#2#3#4%
                            %
                            my_bbye#4applyfunction_finishmy_bbye
                            applyfunction_g #1#2#3#4%
                            %
                            longdefapplyfunction_g #1#2#3applyfunction_d #1#2#3%
                            longdefapplyfunction_finishmy_bbyeapplyfunction_g #1#2#3#1#2%

                            catcode`_ 8

                            %% USAGE
                            % to define a "function" to be used as foo(a,b,c,...),
                            % we need a foomacro which uses standard non-delimited parameters,
                            % thus e.g. defined via newcommand, and then one only needs
                            % newcommandfooapplyfunctionfoomacro
                            % to get a foo to be used with parentheses.

                            newcommandtwomateapplyfunctiontwomatemacro
                            newcommandpwrapplyfunctionpwrmacro
                            newcommandtwoclmnapplyfunctiontwoclmnmacro

                            % define here the **non-delimited** auxiliary macros
                            newcommandtwomatemacro[4]beginpmatrix#1&#2\#3&#4endpmatrix
                            newcommandpwrmacro[1]^#1
                            newcommandtwoclmnmacro[2]beginpmatrix#1\#2endpmatrix

                            %% TESTING NESTING
                            newcommandfooapplyfunctionfoomacro
                            newcommandfoomacro[4]left[#1+#2+#3+#4right]
                            letBarrelax
                            newcommandBarapplyfunctionBarmacro
                            newcommandBarmacro[3]left(#1*#2*#3right)

                            delimiterfactor1001

                            begindocument

                            [
                            twomate(3epwr(-3t),epwr(2t),-epwr(-3t),-2epwr(2t))
                            ]
                            [
                            twoclmn(frac625epwr(2t)-frac15tepwr(2t),-frac225epwr(2t)
                            + frac25 t epwr(2t))
                            ]
                            [foo(Bar(3,5,7),Bar(9,foo(a,Bar(W,X,Y),c,d),13),Bar(15,17,19),Bar(21,23,25))]
                            enddocument


                            enter image description here







                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Nov 12 at 13:53

























                            answered Nov 10 at 8:59









                            jfbu

                            44.7k65143




                            44.7k65143



























                                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.





                                Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                Please pay close attention to the following guidance:


                                • 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%2f459229%2fproblems-with-def%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

                                Darth Vader #20

                                How to how show current date and time by default on contact form 7 in WordPress without taking input from user in datetimepicker

                                Ondo