LATEX-L Archives

Mailing list for the LaTeX3 project


Options: Use Forum View

Use Monospaced Font
Show Text Part by Default
Condense Mail Headers

Message: [<< First] [< Prev] [Next >] [Last >>]
Topic: [<< First] [< Prev] [Next >] [Last >>]
Author: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
Mailing list for the LaTeX3 project <[log in to unmask]>
Morten Høgholm <[log in to unmask]>
Thu, 13 Dec 2007 21:38:23 +0100
multipart/mixed; boundary=----------wi1AV4iqcyOUdZT25p4rBS
Mailing list for the LaTeX3 project <[log in to unmask]>
On Thu, 13 Dec 2007 15:01:13 +0100, Lars Hellström wrote:

Hi Larsm

> For various reasons,[1] I've decided it is time to start on a new  
> version[2] of my xdoc package. Since this was in some parts written with  
> LaTeX3 in mind, this meant I for the first time in several years had to  
> take a closer look at the codebase.
> Some things I like, other things I don't like.
> To start off on a positive note, I now appreciate \IfBooleanTF and will  
> probably use it quite a lot in the rewrite. That \BooleanTrue and  
> \BooleanFalse are no longer available with user catcodes is a bit of a  
> pity (since I suspect they'll occationally be needed), but perhaps  
> they'll resurface.

Did someone delete them? Apparently I did... No problem to add them and  
they should be there as they fit well with \IfBooleanTF.

> Less nice is that the documentation doesn't say whether \IfBooleanTF is  
> expandable.

I think we can agree that this is something needing attention in all of  
the experimental code.

> Examining the implementation, I can see that it is (good), but that the  
> companion \IfNoValueTF is not. [...]
> OTOH, I don't need to test for those well-maybe-it's-\NoValue-in-a-macro  
> situations that \IfNoValueTF currently aim to handle, so I'd prefer it  
> if you provided a simple expandable \IfNoValueTF conditional (perhaps  
> preserving the current one as \IfLeadingNoValueTF or something if you  
> really think it will be useful). In want of this, I'm been using the  
> incantation \ifx\NoValue#1\@empty which could probably serve as a  
> definition.

The complicated tests are there due to comments in old versions of xparse:

% However this makes testing for this token slightly complicated as in
% that case the test
%   \def\seen{#1}
%   \def\containsNoValue{\NoValue}
%   \ifx\seen\containsNoValue
% will be true if |#1| was |\NoValue| but false if if |#1| itself
% contains a macro which contains |\NoValue|; a case that happens
% unfortunately very often in practice.

The implementation was unfortunately fragile as it assumed one could  
safely expand one level and then check. I recall the *first* time I tried  
it on production code and performed
which then blew up with a much too familier
   ! Argument of \bBigg@ has an extra }

If we also wish to have a fast test just testing if the first token is  
\NoValue then I'd define it as
   \def_long_new:Npn \IfLeadingNoValueTF #1{
     \tlist_if_head_eq_meaning:nNTF {#1}\NoValue {<true>}{<false>}
which is relatively safe even if some weird \if:w thing comes first. Yes,  
the name for the tlist function is ridiculously long, I know. But at least  
it is precice (I had cases where I wanted to check charcodes, can't  
remember where though).

> The first thing is (not surprisingly) \catcode changes. xparse.dtx lists  
> this as an open issue and suggests the format specifier
>    g{<prepare-parsing>}
> for this, but also deems it problematic because g is envisioned as  
> signaling an \url-style argument which can be delimited both by braces  
> and by some arbitrary character. I think the latter is overkill and  
> anyway fairly rare, but fiddling with catcodes and the like is common  
> (e.g. \index, \glossary) enough to warrant support, even though such  
> fiddling is not unproblematic. However, the catcode trickeries I do, I  
> do mostly for compatibility with doc, so it would not be a total  
> disaster if this was lost, but several existing documents would need  
> editing.
[postprocessing argument]

The example file attached implements three new argument types:
   k = comma (komma in Danish and c was taken ;-)
     Takes {aaa,bbb,ccc} and transforms into {{aaa}{bbb}{ccc}}
   g {arg} = executes arg first.
   d = detokenizes the arguments.

Was this what you had in mind? It's just a first take on this - will  
continue tomorrow.

[snip rest for tonight]

> What else? \predicate_p:n caught my attention. On one hand, it is a very  
> nice feature, but on the other its syntax feels like begging for  
> trouble. || and && for boolean OR and AND in LaTeX?

In a mail to Frank I wrote

I know using || and && is begging for trouble... On the other hand && is  
easy to guard against and || brings up the question of when to make  
characters active. Even though there is a long tradition for using  
\MakeShortVerb in the preamble, it's the sort of thing I am always worried  
about and it raises the question of "proper" catcode defences.

I considered using control sequences such as
   \def:Npn \c_or: {OO}    \def:Npn\c_and: {AA}
and one can do that, no problem. As long as they just expand to something  
we know what is.

> That's just _so_ out of style, although perhaps comforting for  
> programmers coming from mainstream languages. Also, I wonder whether  
> (apparently legal) constructions like
>    \predicate_p:n{ \boolA && \boolB || \boolC && \boolD }
> does what anyone would expect.

What would you expect from that? When one knows AND and OR then one also  
knows that the expressions can be ambiguous when you mix both operations  
without delimiting subexpressions. The documentation doesn't say so  
explicitly but the example there shows such a subexpression.

> Separate predicates for the AND of a list of predicates and the OR of a  
> list of predicates respectively seems preferable.

We have had a few different implementations. The one in the December 2006  
release on CTAN provides
   \prg_if_predicate_and_p:nn {<test 1>}{<test 2>}
   \prg_if_predicate_or_p:nn {<test 1>}{<test 2>}
   \prg_if_predicate_not_p:n {<test>}
plus some for multiple ANDs and ORs
   \prg_if_predicate_ors_p:n {<test 1> <test 2> ... <test n>}
   \prg_if_predicate_ands_p:n {<test 1> <test 2> ... <test n>}

Two things were wrong with this implementation. Firstly: it evaluated  
everything and that doesn't fit with the minimal evaluation often needed.  
One place in xor it led to an error because when a certain switch was  
false, a <num> register also being tested had been undefined. Even the  
\..._or_p:nn function evalutated both arguments. Secondly: code written  
with these functions had a tendency to be incomprehensible. At first there  
were only the former three mentioned above which made it even harder to  
see what was being tested in comparison to what when, say, three or four  
tests where performed, hence the multiple Ands and Ors versions were added.

> OTOH, "Ask not what Them can do for you, ask what you can do for Them!"

Indeed! :-)

Thanks, I will take a look at that tomorrow because as you say:

> Well, there's more that could be said, but this is already a very long  
> mail.