4

How can I stop function from running rest of the code if some conditions are met in latex3?

Now I have to build nested conditions and have a couple of default cases duplicated. Code readability gets worse if the default case is quite huge.

\ExplSyntaxOn
\cs_set:Npn \my_func #1 {
    \token_if_cs:NTF #1 {
        \str_eq:nnTF {#1} {\\} {
            first case
        }{
            \token_if_expandable:NTF #1 {
                second case
            }{
                default
            }
        }
    }{
        default
    }
}

\my_func{\\}
\ExplSyntaxOff

Here's what I'd like to have in terms of programming language

function(arg){
    if(condition 1){
        return <first case>;
    }
    if(condition 2){
        return <second case>;
    }

    return <default case>;
}
6
  • Nope, it's not possible, what you have done is the best available. Try using my new <advanced language> to TeX compiler (which I will maybe write in the future...)
    – user202729
    May 11, 2022 at 14:13
  • I think functional package can do that (actually it cannot.) Alternatively use a trick like use_none_delimit_by_q_nil when you want to return and put a q_nil at the end (cheating?) / program with Lua inside LaTeX.
    – user202729
    May 11, 2022 at 14:13
  • @user202729 This feature is already in the todo list of functional package. I have created an issue for it.
    – L.J.R.
    May 11, 2022 at 14:47
  • @L.J.R. Presumably using a do-nothing internal marker? \long\def\return#1#2\internalEnd{#1}?
    – Joseph Wright
    May 11, 2022 at 15:29
  • @JosephWright Yes, I think I need to use this kind of definition.
    – L.J.R.
    May 11, 2022 at 15:44

1 Answer 1

7

There are a few ways to achieve this. I'd likely use a predicate-based approach and lazy evaluation:

\ExplSyntaxOn
\cs_set:Npn \my_func:N #1
  {
    \bool_lazy_and:nnTF
      { \token_if_cs_p:N #1 }
      { \token_if_expandable_p:N #1 }
      {
        \str_if_eq:nnTF {#1} { \\ }
          { first case }
          { second case }
      }
      { default }
  }

\my_func:N { \\ }
\ExplSyntaxOff

For more complex cases, I would usually put the 'payload' (actions) into auxiliaries.


If you are wedded to the 'return' format, you need some end marker token

\cs_set:Npn \my_func:N #1
  {
    \token_if_cs:NF #1
      { \__my_func_return:nw { not-a-cs } }
    \token_if_expandable:NF #1
      { \__my_func_return:nw { not-expandable } }
    \__my_func_return:nw { default }
    \__my_func_end:
  }
\cs_new_eq:NN \__my_func_end: \prg_do_nothing:
\cs_new:Npn \__my_func_return:nw #1#2 \__my_func_end:
  {#1}

but honestly I would stick to predicates and appropriate auxiliaries.

7
  • I provided somehow artificial example because couldn't come up with something more appropriate, but the main point was described in the last part of my post: if condition 1 is met, then function should return first case and only it despite that the second condition might be met as well. But if condition 1 is logically false, then the condition 2 will be proceed. If it occurs to be true then the function has to return second case and ignore all the following code. And if and only if both condition 1 and condition 2 have failed, the last default code returns.
    – antshar
    May 11, 2022 at 19:20
  • @antshar That's doable as I've suggested under the question, but at least without a 'wrapper' it's not really going to give the 'nicest looking' expl3 code - I can add an example, but the predicate method is the 'standard' one for expl3 code.
    – Joseph Wright
    May 11, 2022 at 19:23
  • That would be nice, because I didn't really get how would it look like in the real code, on an example.
    – antshar
    May 11, 2022 at 19:29
  • 1
    @antshar I've added an example, but honestly this is really not the expl3 pattern - it's not 'naturally' how TeX works, so you will always be somewhat fighting against the way macro expansion works.
    – Joseph Wright
    May 11, 2022 at 19:35
  • Now looks exactly what I was after. It's a really clever approach. May I only wonder why to switched to negated conditions? Shouldn't they be T?
    – antshar
    May 11, 2022 at 19:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .