Received: from mx0.gmx.net (mx0.gmx.net [213.165.64.100]) by h1439878.stratoserver.net (8.14.2/8.14.2/Debian-2build1) with SMTP id p4767mjc015361 for ; Sat, 7 May 2011 08:07:49 +0200 Received: (qmail 1254 invoked by alias); 7 May 2011 06:07:43 -0000 Delivered-To: GMX delivery to rainer.schoepf@gmx.net Received: (qmail invoked by alias); 07 May 2011 06:07:43 -0000 Received: from relay2.uni-heidelberg.de (EHLO relay2.uni-heidelberg.de) [129.206.210.211] by mx0.gmx.net (mx031) with SMTP; 07 May 2011 08:07:43 +0200 Received: from listserv.uni-heidelberg.de (listserv.uni-heidelberg.de [129.206.100.94]) by relay2.uni-heidelberg.de (8.13.8/8.13.8) with ESMTP id p4764xg9002372 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sat, 7 May 2011 08:04:59 +0200 Received: from listserv.uni-heidelberg.de (localhost.localdomain [127.0.0.1]) by listserv.uni-heidelberg.de (8.13.1/8.13.1) with ESMTP id p46M1kxV017908; Sat, 7 May 2011 08:04:58 +0200 Received: by LISTSERV.UNI-HEIDELBERG.DE (LISTSERV-TCP/IP release 16.0) with spool id 1207934 for LATEX-L@LISTSERV.UNI-HEIDELBERG.DE; Sat, 7 May 2011 08:04:58 +0200 Received: from relay2.uni-heidelberg.de (relay2.uni-heidelberg.de [129.206.210.211]) by listserv.uni-heidelberg.de (8.13.1/8.13.1) with ESMTP id p4764w9a018045 for ; Sat, 7 May 2011 08:04:58 +0200 Received: from anchor-post-3.mail.demon.net (anchor-post-3.mail.demon.net [195.173.77.134]) by relay2.uni-heidelberg.de (8.13.8/8.13.8) with ESMTP id p4764bF7002321 for ; Sat, 7 May 2011 08:04:42 +0200 Received: from morningstar2.demon.co.uk ([80.176.134.7] helo=palladium.local) by anchor-post-3.mail.demon.net with esmtp (Exim 4.69) id 1QIad3-000142-oK; Sat, 07 May 2011 06:04:37 +0000 User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-GB; rv:1.9.2.17) Gecko/20110414 Thunderbird/3.1.10 MIME-Version: 1.0 References: X-Enigmail-Version: 1.1.1 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Message-ID: <4DC4E0F5.1050307@morningstar2.co.uk> Date: Sat, 7 May 2011 07:04:37 +0100 Reply-To: Mailing list for the LaTeX3 project Sender: Mailing list for the LaTeX3 project From: Joseph Wright Subject: Re: safer quarks To: LATEX-L@listserv.uni-heidelberg.de In-Reply-To: Precedence: list List-Help: , List-Unsubscribe: List-Subscribe: List-Owner: List-Archive: X-GMX-Antispam: 0 (eXpurgate); Detail=5D7Q89H36p4qWX7V4skqN/nRxO8fUNijDxptQ9WncOywnkkzFM4PrT8EJV5egHOYlUzoK 01t4TAVGb3pM4CVCAwwBZtK/A1qyBXecfnuPPblLQjb44MyF+jFcHSpjaR117sVnF64zYNX8M6F7 pXGjAlGHel0Yyg70CZxUOpxdlADdvFV3EzYy9o5bvD7SMbTeavZjGDCj07Ffr32BWGUqw==V1; X-Resent-By: Forwarder X-Resent-For: rainer.schoepf@gmx.net X-Resent-To: rainer@rainer-schoepf.de Status: R X-Status: X-Keywords: X-UID: 6734 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