5

Various languages have constructs like

select;
   when <expression 1> then
      <action 1>;
   when <expression 2> then
      <action 2>;
   ...
   when <expression n> then
      <action n>;
   otherwise;
      <action false>;
   end;

or

if (<expression 1>) {
  <action 1>
  }
elsif (<expression 2>) {
  <action 2>
  }
...
elsif (<expression n>) {
  <action n>
  }
else {
  <action false>
  }

for evaluating a sequence of expressions and performing the first action for which the expression evaluates as true. I would have expected the expl3 kernel to include \case:n and \case:nTF for this purpose, but it does not. Is there any work in progress to add such a construct?

shmuel
  • 1,449
  • 3
    They are separated by variable type. There is \int_case for integers, \str_case for strings, \tl_case for token lists, and \dim_case for dimensions. – Phelype Oleinik Feb 08 '19 at 19:28
  • @Phelype None of those do as I described; they match a test variable against a list of cases, rather than evaluating the cases for true or false. – shmuel Feb 08 '19 at 19:39
  • 1
    You can then use \bool_if:nTF {<logical expression>} {<true code>} {<false code>} and nest them at will. – Phelype Oleinik Feb 08 '19 at 19:46
  • 1
    Related? https://tex.stackexchange.com/questions/350815/modified-ifstreqcase-with-multiple-matches-per-case – Steven B. Segletes Feb 08 '19 at 19:48
  • @ Phelype That leads to deep nesting, which I am trying to avoid. I'd like all of the tests to be at the same level. – shmuel Feb 08 '19 at 20:11
  • @Steven That link is for matching a test variable against multiple values for some of the action; I'd like a construct where there is no test variable and each case selector is evaluated as a stand-alone Boolean expression. – shmuel Feb 08 '19 at 20:13
  • I don't think that there is such a command, if you think it would be useful open an issue at the github and make a feature request. – Ulrike Fischer Feb 08 '19 at 20:15
  • Thanks for replying. But I don't understand...without a test variable, how does it work? Don't you need to compare something to the cases? – Steven B. Segletes Feb 08 '19 at 20:17
  • 1
    @StevenB.Segletes If I understood correctly, OP wants the same operation as \bool_if:nTF but that instead of if {<test>} { <true> } { if { <other test> } { <true> } { <nesting> } } he wants it all in one level: if { <test> } { <true> } elseif { <other test> } { <true> } elseif ... fi. The overall result would be the same, but the code wouldn't be (explicitly) nested. – Phelype Oleinik Feb 08 '19 at 20:21
  • @Steven The same as the sample code in the question; in Perl or Ruby it's if/elsif/else, in Python it's if/elif/else in REXX or PL/I it's SELECT/WHEN/OTHERWISE, in several languages there are shorthand forms. – shmuel Feb 08 '19 at 20:26
  • Which makes me wonder if there’s a chance for pattern guards. – Davislor Feb 08 '19 at 20:28
  • @David If I understand what you're suggesting, that would execute all of the actions with true expressions rather than just the first. – shmuel Feb 08 '19 at 20:48
  • @shmuel that isn't what I meant but it may need a bit more fiddling I'll post again in a bit – David Carlisle Feb 08 '19 at 20:51
  • @Ulrike I opened https://github.com/latex3/latex3.github.io/issues/2 – shmuel Feb 08 '19 at 20:52
  • 1
    that's the wrong repo, but Frank already moved your issue. – Ulrike Fischer Feb 08 '19 at 20:56
  • @shmuel which is the wrong place as I'm not going to add a case statement to the website :-) but thanks to github beta I already transfered it – Frank Mittelbach Feb 08 '19 at 20:56
  • @PhelypeOleinik Thanks. My brain was screening out the word "boolean". Makes sense now. – Steven B. Segletes Feb 08 '19 at 21:29

1 Answers1

3

It's easy to make such a construct, I may not have quite the official naming scheme, but that could be arranged

enter image description here

\documentclass{article}

\usepackage{expl3}
\begin{document}


\ExplSyntaxOn
\def\zz#1\zzz{}\def\zzz{}

two ~true ~just ~do ~first ~
aaa ~ \bool_if:nT {\int_compare_p:n{3=1}} {3 ~ is ~ 1\zz}
      \bool_if:nT {\int_compare_p:n{3=2}} {3 ~ is ~ 2\zz}
      \bool_if:nT {\int_compare_p:n{3=3}} {3 ~ is ~ 3\zz}
      \bool_if:nT {\int_compare_p:n{3=4}} {3 ~ is ~ 4\zz}
      \bool_if:nT {\int_compare_p:n{1=1}} {1 ~ is ~ 1}
      \zzz \ bbb

\par

one ~true ~
aaa ~ \bool_if:nT {\int_compare_p:n{3=1}} {3 ~ is ~ 1\zz}
      \bool_if:nT {\int_compare_p:n{3=2}} {3 ~ is ~ 2\zz}
      \bool_if:nT {\int_compare_p:n{3=4}} {3 ~ is ~ 4\zz}
      \bool_if:nT {\int_compare_p:n{3=4}} {3 ~ is ~ 4\zz}
      \bool_if:nT {\int_compare_p:n{1=1}} {1 ~ is ~ 1}
      \zzz \ bbb

\par

none ~true ~
aaa ~ \bool_if:nT {\int_compare_p:n{3=1}} {3 ~ is ~ 1\zz}
      \bool_if:nT {\int_compare_p:n{3=2}} {3 ~ is ~ 2\zz}
      \bool_if:nT {\int_compare_p:n{3=4}} {3 ~ is ~ 4\zz}
      \bool_if:nT {\int_compare_p:n{3=4}} {3 ~ is ~ 4\zz}
      \bool_if:nT {\int_compare_p:n{1=4}} {1 ~ is ~ 4}
      \zzz \ bbb

\ExplSyntaxOff


\end{document}
David Carlisle
  • 757,742