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