Bruno Le Floch skrev 2011-10-19 18.16: >> A better formatting would be >> >> \bool_if:nTF { >> \bool_pred:n{\l_my_first_bool}&& ( >> \bool_pred:n{\l_my_second_bool}&& >> ! \bool_pred:n{\l_my_third_bool} >> ) >> } > > Still unreadable in my view, because the \bool_pred:n add no > information, and are just there to make TeX happy. Since we can avoid > them altogether, let's do it. We can also avoid these corny infix expressions altogether... ;-) > \bool_if:nTF > { > \l_my_first_bool > && ( > \l_my_second_bool > && ! \l_my_third_bool > ) > } > >> :) But maybe the problem is that&&, (, ), !, and || do not really stand out >> from the background of braces and backslashes (far less than against the >> background of alphanumeric identifiers you'd encounter in C)? Fortanish >> .AND., .OR., and .NOT. would be more eye-catching, but the parentheses are >> probably a lost cause readability-wise. > > I find&& and || to be more visible than AND and OR in fact (probably > a matter of syntax highlighting in the editor). I find it unlikely that an editor with syntax highlighting for LaTeX would assign special highlighting to || and !, unless someone has specially reconfigured it to do so. >> Well, it depends on the parsing scheme one uses. If instead going for >> delimited-argument style subformula grabbing, then it wouldn't matter how >> many tokens an expression terminal (predicate) consists of, and as a >> side-effect operation priority becomes straightforward (the operation you >> split at first gets the lowest priority). What would be tricky for this >> approach is the handling of parentheses, since in that case there are two >> distinct possibilities for "the next token of interest here", but I think it >> is doable (first split on one, then try to split on the second, and treat >> the combination of the outcomes as a case). > > The other problem with this approach is that my working copy with > Church booleans is now catcode agnostic, while delimited arguments > would require one particular catcode. You are right on the other > arguments for that approach. Catcodes for ADNORT and () don't tend to change much. >> I believe one could preferably structure the whole thing as an expand-only >> rewrite of infix boolean expression to Church-style compositions of >> booleans. It probably wouldn't be good at catching certain syntax errors, >> though. > > That's a pretty big change. I need some time to ponder it. (And in any > case, changes won't happen before a few weeks from now.) Well, changes could as a matter of fact happen tonight already, since I had just completed my implementation of it when I received your mail. See attached file (I hope it gets through). I've probably picked strange names for some macros, but I think the post-colon parts are acceptable. Here's an example: \if_bool_expr:nTF{ ( NOT \l_my_first_bool OR \IfFileExists{latex.ltx} ) AND \l_my_second_bool }{Evaluates~to~true.}{Evaluates~to~false.} This works. And it's done using macros. *Nothing* but macros. >> Consider a command whose role is similar to that of the 2e \makelabel: A >> user-definable command which gets its argument(s) from more basic levels of >> LaTeX, and is supposed to do something in a configurable way. ((In the >> future all such commands should be template keys, you say? Why, yes, it may >> well be. Template instances will often be defined with \ExplSyntaxOff, I >> think.)) Suppose further that one of these arguments is a boolean. ((Poor >> design? Well, such things will happen; it's an open system.)) Now, if said >> boolean is a Church boolean (effectively \use_i:nn or \use_ii:nn), then it >> can be used directly to select between two pieces of code, e.g. like >> >> \def\makesomething#1#2{% Assuming \ExplSyntaxOff >> % #1 is some text >> % #2 is the boolean >> #1% >> #2{ \thetheorem}{}% >> .\ % >> } > > What about \let \ifthenelse \bool_if:nTF ? That doesn't assume > anything about the internals, and allows precisely what you describe > (and is slightly more general, since the user can now use boolean > expressions). I'm not particularly fond of that. In particular, requiring the use of a command that does fancy expression parsing just for the sake of even using a boolean seems highly wasteful. >>> We could provide \bool_and:nn etc. (or some variation thereof). One >>> problem is where to stop: here you've used the three argument variant >>> \add:nnn, but we should then provide a four argument variant, etc. >> >> Even if you include everything up to the nine argument forms, you'll end up >> with fewer macros in total than for the alternative. ;-) > > True with the current code, I think, but my new code doesn't need two > separate branches, so that statement becomes false :). Then it _is_ > true that 18 cs is not that much. However, > > \bool_if:nTF > { > \bool_and:nnnnnnn % n? > \l_i_bool > \l_ii_bool > \l_iii_bool > \l_iv_bool > \l_v_bool > \l_vi_bool > \l_vii_bool > \l_viii_bool > } Provided that the booleans are really Church booleans, that \bool_if:nTF serves no purpose. > is not exactly obvious to update if a boolean is added. The&& version > is simple: add "&& \l_last_bool". Anyone writing expressions with that many clauses deserve a little difficulty in updating them; usually, it is a sign that one is making things far too complicated, and should rethink one's approach to the problem. :-) Lars Hellström