Subtleties when using def and ifnum conditionals

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
2
down vote

favorite
1












I am having some difficultly comparing two numbers passed as arguments using ifnum. Consider the command



defcomparenum[#1,#2]

defx#1
defy#2
ifnumx=y
TRUE
else
FALSE
fi



comparenum[1,1] gives TRUE as I would expect. However, if I replace the above with



ifnumx=y
1
else
0
fi


The same call comparenum[1,1] produces 0 (replacing y with y, or indeed #2 seems to fix this). What is the reason for this behaviour? I would like to use the second construction so that I can nest the statement inside another conditional as in the top answer to How to form “if … or … then” conditionals in TeX?










share|improve this question









New contributor




Pippip19 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.















  • 1




    You may want to look into etoolbox and its ifnumequal test. Together with ifboolexpr you can easily nest stuff. But you can also look into expl3 and its vast array of tests.
    – moewe
    53 mins ago










  • Your first code produces TRUE but does not produce FALSE if you call comparenum[1,2].
    – Sigur
    52 mins ago










  • @Sigur I just realised the same. defx#1 defy#1 could explain that ;-) But I'm wondering why the def's are needed at all... ifnum#1=#2 should do more or less the same.
    – moewe
    51 mins ago











  • If you want to be able to use 1 and 0 as "return" values you should try ifnumx=yrelax
    – moewe
    50 mins ago










  • @moewe, ohhhhh, I missed that!!! Good!
    – Sigur
    50 mins ago














up vote
2
down vote

favorite
1












I am having some difficultly comparing two numbers passed as arguments using ifnum. Consider the command



defcomparenum[#1,#2]

defx#1
defy#2
ifnumx=y
TRUE
else
FALSE
fi



comparenum[1,1] gives TRUE as I would expect. However, if I replace the above with



ifnumx=y
1
else
0
fi


The same call comparenum[1,1] produces 0 (replacing y with y, or indeed #2 seems to fix this). What is the reason for this behaviour? I would like to use the second construction so that I can nest the statement inside another conditional as in the top answer to How to form “if … or … then” conditionals in TeX?










share|improve this question









New contributor




Pippip19 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.















  • 1




    You may want to look into etoolbox and its ifnumequal test. Together with ifboolexpr you can easily nest stuff. But you can also look into expl3 and its vast array of tests.
    – moewe
    53 mins ago










  • Your first code produces TRUE but does not produce FALSE if you call comparenum[1,2].
    – Sigur
    52 mins ago










  • @Sigur I just realised the same. defx#1 defy#1 could explain that ;-) But I'm wondering why the def's are needed at all... ifnum#1=#2 should do more or less the same.
    – moewe
    51 mins ago











  • If you want to be able to use 1 and 0 as "return" values you should try ifnumx=yrelax
    – moewe
    50 mins ago










  • @moewe, ohhhhh, I missed that!!! Good!
    – Sigur
    50 mins ago












up vote
2
down vote

favorite
1









up vote
2
down vote

favorite
1






1





I am having some difficultly comparing two numbers passed as arguments using ifnum. Consider the command



defcomparenum[#1,#2]

defx#1
defy#2
ifnumx=y
TRUE
else
FALSE
fi



comparenum[1,1] gives TRUE as I would expect. However, if I replace the above with



ifnumx=y
1
else
0
fi


The same call comparenum[1,1] produces 0 (replacing y with y, or indeed #2 seems to fix this). What is the reason for this behaviour? I would like to use the second construction so that I can nest the statement inside another conditional as in the top answer to How to form “if … or … then” conditionals in TeX?










share|improve this question









New contributor




Pippip19 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











I am having some difficultly comparing two numbers passed as arguments using ifnum. Consider the command



defcomparenum[#1,#2]

defx#1
defy#2
ifnumx=y
TRUE
else
FALSE
fi



comparenum[1,1] gives TRUE as I would expect. However, if I replace the above with



ifnumx=y
1
else
0
fi


The same call comparenum[1,1] produces 0 (replacing y with y, or indeed #2 seems to fix this). What is the reason for this behaviour? I would like to use the second construction so that I can nest the statement inside another conditional as in the top answer to How to form “if … or … then” conditionals in TeX?







tex-core conditionals






share|improve this question









New contributor




Pippip19 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




Pippip19 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 16 mins ago





















New contributor




Pippip19 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 1 hour ago









Pippip19

132




132




New contributor




Pippip19 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Pippip19 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Pippip19 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







  • 1




    You may want to look into etoolbox and its ifnumequal test. Together with ifboolexpr you can easily nest stuff. But you can also look into expl3 and its vast array of tests.
    – moewe
    53 mins ago










  • Your first code produces TRUE but does not produce FALSE if you call comparenum[1,2].
    – Sigur
    52 mins ago










  • @Sigur I just realised the same. defx#1 defy#1 could explain that ;-) But I'm wondering why the def's are needed at all... ifnum#1=#2 should do more or less the same.
    – moewe
    51 mins ago











  • If you want to be able to use 1 and 0 as "return" values you should try ifnumx=yrelax
    – moewe
    50 mins ago










  • @moewe, ohhhhh, I missed that!!! Good!
    – Sigur
    50 mins ago












  • 1




    You may want to look into etoolbox and its ifnumequal test. Together with ifboolexpr you can easily nest stuff. But you can also look into expl3 and its vast array of tests.
    – moewe
    53 mins ago










  • Your first code produces TRUE but does not produce FALSE if you call comparenum[1,2].
    – Sigur
    52 mins ago










  • @Sigur I just realised the same. defx#1 defy#1 could explain that ;-) But I'm wondering why the def's are needed at all... ifnum#1=#2 should do more or less the same.
    – moewe
    51 mins ago











  • If you want to be able to use 1 and 0 as "return" values you should try ifnumx=yrelax
    – moewe
    50 mins ago










  • @moewe, ohhhhh, I missed that!!! Good!
    – Sigur
    50 mins ago







1




1




You may want to look into etoolbox and its ifnumequal test. Together with ifboolexpr you can easily nest stuff. But you can also look into expl3 and its vast array of tests.
– moewe
53 mins ago




You may want to look into etoolbox and its ifnumequal test. Together with ifboolexpr you can easily nest stuff. But you can also look into expl3 and its vast array of tests.
– moewe
53 mins ago












Your first code produces TRUE but does not produce FALSE if you call comparenum[1,2].
– Sigur
52 mins ago




Your first code produces TRUE but does not produce FALSE if you call comparenum[1,2].
– Sigur
52 mins ago












@Sigur I just realised the same. defx#1 defy#1 could explain that ;-) But I'm wondering why the def's are needed at all... ifnum#1=#2 should do more or less the same.
– moewe
51 mins ago





@Sigur I just realised the same. defx#1 defy#1 could explain that ;-) But I'm wondering why the def's are needed at all... ifnum#1=#2 should do more or less the same.
– moewe
51 mins ago













If you want to be able to use 1 and 0 as "return" values you should try ifnumx=yrelax
– moewe
50 mins ago




If you want to be able to use 1 and 0 as "return" values you should try ifnumx=yrelax
– moewe
50 mins ago












@moewe, ohhhhh, I missed that!!! Good!
– Sigur
50 mins ago




@moewe, ohhhhh, I missed that!!! Good!
– Sigur
50 mins ago










1 Answer
1






active

oldest

votes

















up vote
2
down vote



accepted










Your second code is equivalent to



defcomparenum[#1,#2] defx#1 defy#1 ifnumx=y1 else0 fi


(because spaces and end-of-lines are ignored after a control word). Now you should be able to see the main problem with the code. When TeX evaluates the conditional, it needs two numbers and does full expansion until finding tokens that cannot be interpreted as digits.



So it expands x and = stops the search for digits while also starting the lookup for the next number; y is expanded and 1 follows. So the call comparenum[1,1] translates into



ifnum1=11 else0 fi


which of course returns false.



You solve the issue with



defcomparenum[#1,#2]%
defx#1%
defy#1%
ifnumx=yrelax
1%
else
0%
fi



The relax token stops the lookup for digits.



On the other hand, this construct is not expandable. You can make an expandable version with



defcomparenum[#1,#2]%
ifnum#1=number#2spacespace
1%
else
0%
fi



The first space expands to a space token that stops number from looking up for more digits and is then ignored by rule; the second space stops the search for digit related to ifnum and is again ignored.



An e-TeX version would be



defcomparenum[#1,#2]%
ifnum#1=numexpr#2relax
1%
else
0%
fi



Please, note the % that protect the end-of-lines avoiding that they make spaces in the output.






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: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );






    Pippip19 is a new contributor. Be nice, and check out our Code of Conduct.









     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f456106%2fsubtleties-when-using-def-and-ifnum-conditionals%23new-answer', 'question_page');

    );

    Post as a guest






























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    2
    down vote



    accepted










    Your second code is equivalent to



    defcomparenum[#1,#2] defx#1 defy#1 ifnumx=y1 else0 fi


    (because spaces and end-of-lines are ignored after a control word). Now you should be able to see the main problem with the code. When TeX evaluates the conditional, it needs two numbers and does full expansion until finding tokens that cannot be interpreted as digits.



    So it expands x and = stops the search for digits while also starting the lookup for the next number; y is expanded and 1 follows. So the call comparenum[1,1] translates into



    ifnum1=11 else0 fi


    which of course returns false.



    You solve the issue with



    defcomparenum[#1,#2]%
    defx#1%
    defy#1%
    ifnumx=yrelax
    1%
    else
    0%
    fi



    The relax token stops the lookup for digits.



    On the other hand, this construct is not expandable. You can make an expandable version with



    defcomparenum[#1,#2]%
    ifnum#1=number#2spacespace
    1%
    else
    0%
    fi



    The first space expands to a space token that stops number from looking up for more digits and is then ignored by rule; the second space stops the search for digit related to ifnum and is again ignored.



    An e-TeX version would be



    defcomparenum[#1,#2]%
    ifnum#1=numexpr#2relax
    1%
    else
    0%
    fi



    Please, note the % that protect the end-of-lines avoiding that they make spaces in the output.






    share|improve this answer
























      up vote
      2
      down vote



      accepted










      Your second code is equivalent to



      defcomparenum[#1,#2] defx#1 defy#1 ifnumx=y1 else0 fi


      (because spaces and end-of-lines are ignored after a control word). Now you should be able to see the main problem with the code. When TeX evaluates the conditional, it needs two numbers and does full expansion until finding tokens that cannot be interpreted as digits.



      So it expands x and = stops the search for digits while also starting the lookup for the next number; y is expanded and 1 follows. So the call comparenum[1,1] translates into



      ifnum1=11 else0 fi


      which of course returns false.



      You solve the issue with



      defcomparenum[#1,#2]%
      defx#1%
      defy#1%
      ifnumx=yrelax
      1%
      else
      0%
      fi



      The relax token stops the lookup for digits.



      On the other hand, this construct is not expandable. You can make an expandable version with



      defcomparenum[#1,#2]%
      ifnum#1=number#2spacespace
      1%
      else
      0%
      fi



      The first space expands to a space token that stops number from looking up for more digits and is then ignored by rule; the second space stops the search for digit related to ifnum and is again ignored.



      An e-TeX version would be



      defcomparenum[#1,#2]%
      ifnum#1=numexpr#2relax
      1%
      else
      0%
      fi



      Please, note the % that protect the end-of-lines avoiding that they make spaces in the output.






      share|improve this answer






















        up vote
        2
        down vote



        accepted







        up vote
        2
        down vote



        accepted






        Your second code is equivalent to



        defcomparenum[#1,#2] defx#1 defy#1 ifnumx=y1 else0 fi


        (because spaces and end-of-lines are ignored after a control word). Now you should be able to see the main problem with the code. When TeX evaluates the conditional, it needs two numbers and does full expansion until finding tokens that cannot be interpreted as digits.



        So it expands x and = stops the search for digits while also starting the lookup for the next number; y is expanded and 1 follows. So the call comparenum[1,1] translates into



        ifnum1=11 else0 fi


        which of course returns false.



        You solve the issue with



        defcomparenum[#1,#2]%
        defx#1%
        defy#1%
        ifnumx=yrelax
        1%
        else
        0%
        fi



        The relax token stops the lookup for digits.



        On the other hand, this construct is not expandable. You can make an expandable version with



        defcomparenum[#1,#2]%
        ifnum#1=number#2spacespace
        1%
        else
        0%
        fi



        The first space expands to a space token that stops number from looking up for more digits and is then ignored by rule; the second space stops the search for digit related to ifnum and is again ignored.



        An e-TeX version would be



        defcomparenum[#1,#2]%
        ifnum#1=numexpr#2relax
        1%
        else
        0%
        fi



        Please, note the % that protect the end-of-lines avoiding that they make spaces in the output.






        share|improve this answer












        Your second code is equivalent to



        defcomparenum[#1,#2] defx#1 defy#1 ifnumx=y1 else0 fi


        (because spaces and end-of-lines are ignored after a control word). Now you should be able to see the main problem with the code. When TeX evaluates the conditional, it needs two numbers and does full expansion until finding tokens that cannot be interpreted as digits.



        So it expands x and = stops the search for digits while also starting the lookup for the next number; y is expanded and 1 follows. So the call comparenum[1,1] translates into



        ifnum1=11 else0 fi


        which of course returns false.



        You solve the issue with



        defcomparenum[#1,#2]%
        defx#1%
        defy#1%
        ifnumx=yrelax
        1%
        else
        0%
        fi



        The relax token stops the lookup for digits.



        On the other hand, this construct is not expandable. You can make an expandable version with



        defcomparenum[#1,#2]%
        ifnum#1=number#2spacespace
        1%
        else
        0%
        fi



        The first space expands to a space token that stops number from looking up for more digits and is then ignored by rule; the second space stops the search for digit related to ifnum and is again ignored.



        An e-TeX version would be



        defcomparenum[#1,#2]%
        ifnum#1=numexpr#2relax
        1%
        else
        0%
        fi



        Please, note the % that protect the end-of-lines avoiding that they make spaces in the output.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 19 mins ago









        egreg

        691k8518383086




        691k8518383086




















            Pippip19 is a new contributor. Be nice, and check out our Code of Conduct.









             

            draft saved


            draft discarded


















            Pippip19 is a new contributor. Be nice, and check out our Code of Conduct.












            Pippip19 is a new contributor. Be nice, and check out our Code of Conduct.











            Pippip19 is a new contributor. Be nice, and check out our Code of Conduct.













             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f456106%2fsubtleties-when-using-def-and-ifnum-conditionals%23new-answer', 'question_page');

            );

            Post as a guest













































































            Comments

            Popular posts from this blog

            What does second last employer means? [closed]

            List of Gilmore Girls characters

            Confectionery