LATEX-L Archives

Mailing list for the LaTeX3 project

LATEX-L@LISTSERV.UNI-HEIDELBERG.DE

Options: Use Forum View

Use Monospaced Font
Show Text Part by Default
Show All Mail Headers

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

Print Reply
Subject:
From:
Joseph Wright <[log in to unmask]>
Reply To:
Mailing list for the LaTeX3 project <[log in to unmask]>
Date:
Sat, 7 May 2011 07:04:37 +0100
Content-Type:
text/plain
Parts/Attachments:
text/plain (112 lines)
On 07/05/2011 04:42, Bruno Le Floch wrote:
> if I understand correctly, quarks are meant to work in cases like
> 
> \def\foo{#1}
> \ifx\foo\quark  ... \else ... \fi
> 
> This requires quarks to be defined as expanding to themselves.
> Or it requires to distinguish between a quark and a token list containing
> that quark.
> 
> I personally don't use quarks as anything else than delimiters, so any
> definition is fine, but I guess that property of quarks is used in
> constructions
> like
> 
> \tl_set:Nn \foo {#1}
> \quark_if_recursion_tail_stop:N \foo
> 
> or
> 
> \prop_get:NnN \foo {key} \bar
> \quark_if_no_value:NTF \bar { } { }
> 
> This could be solved by altering quark tests, perhaps...?

This has all been discussed before, of course, but I think there is some
merit in looking again at it.

I think we have two quarks that are tested in this way: \q_no_value and
\q_nil. So I did some testing using the siunitx manual. With the definitions

\cs_set_nopar:Npn \q_no_value \q_no_value { \q_no_value }
\tl_const:Nn \c_q_no_value_tl { \q_no_value }
\prg_set_conditional:Npnn \quark_if_no_value:N #1 { p , T , F , TF }
  {
     \if_meaning:w \q_no_value #1
      \prg_return_true:
     \else:
       \if_meaning:w \c_q_no_value_tl #1
        \prg_return_true:
       \else:
         \prg_return_false:
       \fi:
     \fi:
  }
\cs_set_nopar:Npn \q_no_nil \q_no_nil { \q_no_nil }
\tl_const:Nn \c_q_nil_tl { \q_nil }
\prg_set_conditional:Npnn \quark_if_nil:N #1 { p , T , F , TF }
  {
     \if_meaning:w \q_nil #1
      \prg_return_true:
     \else:
       \if_meaning:w \c_q_nil_tl #1
        \prg_return_true:
       \else:
         \prg_return_false:
       \fi:
     \fi:
  }

I get very little change in compile time on my laptop (which admittedly
is a fast system): the .dtx takes about 13 seconds with the current
definitions and with the modified ones above. More importantly, they
does not break anything. (Delimiting the macro with itself will of
course be valid if there are two adjacent quarks, but should 'unwind' to
an error on full expansion.)

There is also a need to alter:

\tl_const:Nn \c_q_recursion_tail_tl { \q_recursion_tail }
\cs_set:Npn \quark_if_recursion_tail_stop:N #1
  {
    \if_meaning:w #1 \q_recursion_tail
      \exp_after:wN \use_none_delimit_by_q_recursion_stop:w
    \else:
      \if_meaning:w #1 \c_q_recursion_tail_tl
        \exp_after:wN \exp_after:wN \exp_after:wN
          \use_none_delimit_by_q_recursion_stop:w
      \fi:
    \fi:
  }
\cs_set:Npn \quark_if_recursion_tail_stop_do:Nn #1#2
  {
    \if_meaning:w #1 \q_recursion_tail
      \exp_after:wN \use_i_delimit_by_q_recursion_stop:nw
    \else:
      \if_meaning:w #1 \c_q_recursion_tail_tl
        \exp_after:wN \exp_after:wN \exp_after:wN
          \use_i_delimit_by_q_recursion_stop:nw
      \else:
        \exp_after:wN \exp_after:wN \exp_after:wN \use_none:n
      \fi:
    \fi:
      {#2}
  }

as these are needed by map_variable implementations (and perhaps in
other places).

Now, I think that this is not such a bad idea: the infinite loop problem
is one I suspect most of us have never been too keen on (it certainly
causes me headaches from time to time). In the test file, the proposed
change breaks the trivial 'print the definition stuff', obviously, but also

  \quark_if_nil:oTF \q_nil \TRUE \FALSE

which leaves me the question 'Do we really need this?' That I know of,
we've never used the fact that a single quark expansion leaves the quark
unchanged.

Joseph

ATOM RSS1 RSS2