Received: from mout.gmx.net (mout.gmx.net [212.227.17.20]) by h1439878.stratoserver.net (8.14.2/8.14.2/Debian-2build1) with ESMTP id r6GJCGV1003742 for ; Tue, 16 Jul 2013 21:12:18 +0200 Received: from relay2.uni-heidelberg.de ([129.206.210.211]) by mx-ha.gmx.net (mxgmx102) with ESMTP (Nemesis) id 0MBr8l-1UpaA925PL-00AoEm for ; Tue, 16 Jul 2013 21:12:11 +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 r6GJ9bt2014315 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 16 Jul 2013 21:09:37 +0200 Received: from listserv.uni-heidelberg.de (listserv.uni-heidelberg.de [127.0.0.1]) by listserv.uni-heidelberg.de (8.13.8/8.13.8) with ESMTP id r6GDGSW6022061; Tue, 16 Jul 2013 21:09:36 +0200 Received: by LISTSERV.UNI-HEIDELBERG.DE (LISTSERV-TCP/IP release 16.0) with spool id 10313900 for LATEX-L@LISTSERV.UNI-HEIDELBERG.DE; Tue, 16 Jul 2013 21:09:36 +0200 Received: from relay.uni-heidelberg.de (relay.uni-heidelberg.de [129.206.100.212]) by listserv.uni-heidelberg.de (8.13.8/8.13.8) with ESMTP id r6GJ9ZsG024515 for ; Tue, 16 Jul 2013 21:09:35 +0200 Received: from mail-oa0-f50.google.com (mail-oa0-f50.google.com [209.85.219.50]) by relay.uni-heidelberg.de (8.14.1/8.14.1) with ESMTP id r6GJ9NNl017338 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=FAIL) for ; Tue, 16 Jul 2013 21:09:26 +0200 Received: by mail-oa0-f50.google.com with SMTP id k7so1360349oag.37 for ; Tue, 16 Jul 2013 12:09:22 -0700 (PDT) X-Received: by 10.60.39.193 with SMTP id r1mr3621924oek.40.1374001762642; Tue, 16 Jul 2013 12:09:22 -0700 (PDT) MIME-Version: 1.0 Received: by 10.76.68.99 with HTTP; Tue, 16 Jul 2013 12:09:02 -0700 (PDT) References: Content-Type: text/plain; charset=windows-1252 X-MIME-Autoconverted: from quoted-printable to 8bit by listserv.uni-heidelberg.de id r6GJ9asG024516 Message-ID: Date: Tue, 16 Jul 2013 21:09:02 +0200 Reply-To: Mailing list for the LaTeX3 project Sender: Mailing list for the LaTeX3 project From: Michiel Helvensteijn Subject: Re: Request for argument specifiers which generate unique csnames To: LATEX-L@LISTSERV.UNI-HEIDELBERG.DE In-Reply-To: Precedence: list List-Help: , List-Unsubscribe: List-Subscribe: List-Owner: List-Archive: Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by relay2.uni-heidelberg.de id r6GJ9bt2014315 Envelope-To: X-GMX-Antispam: 0 (Mail was not recognized as spam); Detail=V3; X-GMX-Antivirus: 0 (no virus found) X-UI-Filterresults: notjunk:1;V01:K0:fWUu15xik3I=:TLb4fDhMkro3SNQtyDS//W +7zLCQH6rY6+Qjc+2Ho75Sa+R2D88dwHPS2S/o3/bcGjvw3xNTjL0P4G76wvq0EBxU3y2kI yMli482MmjDd0300NcG/Pyao0dkZ0NLMCPJcJUmSP/13PeDvsyQyqWE2y8XkjcydB8URRRN hFX4XD6asexRJYV6R5ok3CtvizrcXjIM/eq6RPd0V8NjMGnNZDAdC41WgGdY7Wp/oJwB3xY iZ0asze0Qw/wpjthXM7rV0zuWysp2ZOt8/XU4/cs38XeH/cHHggxhXa3WB5UO9zmgd0wqUp rr34pwOHT0pE6dURswNdREeSYWttxNM9NOIAR53p8WqsqQTSyQjymBncJCiXXZvWTqQA12A j7drHNFAna1Y/yycNOoCDJVopAGuGG/EXXPD9GVoPpZrE6I1vxy5qol8rbdRh8k6nlrIs1k 6PF6KQiG6fg3F85U8ymFwFbRyGBU6pJv4/D3kr4gSG3awX73+wxmBpdA5EHNvRFvbCHWZzE h9ZgPaGCthxV1Zxgm33XvsNtjQurViBGnydGEn+GnQHwgKRw7Hy72y6Xfv5pBS+aSDkdEJA 09P26l2ukuwMZpRIvPLNt5w3b7ntf4X3o6bTLfLiyBfEMZ+xR0w/RPse4bkhEV0b67BaWgd 4wV1l1XEd+vItF0wjl9Kt629A+MxNxxjH5gZ10HXkEiCGPKgA5Z4TJwcEjQfFbI0Kp0OKZQ bNsduquL3FjimAl1c9BbTRlvCMnKb20LiZP+D7MZp6JykNDuxjUAOmdpPw8SOrTMlCYHwtT hMiV/qgDjFgi0k8k5wblLwChxfzbjfbgZDre2DgAolSH/yiUW7hi5fGWd0v4rCEJg2arFFH Rks2utl2EnhhInke8ibSzm9FjtMriL4tLLmbMuBLNk9QQ0swocSbyP/u/v32DfhlAr3hPDT zilx47HeVxlUPrtbCg67B9ajdQ9B7kWMaTv62PWpngHn4Hrh0IDnuPvAX+0wkG54FpIyQBW +hLviiR+TNGixcjftelAUeCPcjr9ZU0PGS5K5PG5qoWeWUYshwboPDBF9atLLNHepqnHYt3 y5p5pMOufkIpUKtGgp1CXOM8gndJpoBz51ZJWQvDsonezAZ8ERTjKfcsitVUDvIscIGG419 ZJxRu2UGw3goZn7VYdcN25vItL2tAPNPBc0pyHP5+Dq95TjLOdknMYyLceMe1NavBgCsWsd gA320pxUE0ShEOU6LQ4DURF8Nvmpjjd45TWACwluBC053iJF1ADpGY/K4aS2gWDLplH8y5a 6foyYRmPzOcQ1fpSjU+ZQxq1Cn8hMdJSqbQ+yVHq9Cyzk2Kzyn5hayV4IjPn3i2smrrh8hC KAx7ytgTCoIkSaF4bHZtiaoaTvJWxpC+zm7AJwC/HB0IUGFlwDR0Hhgdf8WMoGfIcz/OgaV 0p/d2Il8XsP/HB9Yuqb8pEbHATDQNCmNMaDz8OmivoLoIU5U3d44ueSlJ0anDJzf9HgXfZk wG2+GenPY5zKZ4i4qn1TLIPk0G/fyH/HEZFS6AQKBTxxhyT1ZZWcHfuxOOG9ObFAyZc4a3D dlQQh4tAEkZbElmbh/rHDYJ0LfGb2Inlcp1Lhio76wMBR2dYzJnPTo14WAs= X-UI-Loop:V01:xkgudV9OCFo=:40A0XtlT72J85yoLMrRVVqDcWCaqLtwsP/Wv6H0nGDg= Status: R X-Status: X-Keywords: X-UID: 7248 On Tue, Jul 16, 2013 at 7:25 PM, Bruno Le Floch wrot= e: > It is indeed useful to have unique csnames generated automatically. > However, the need is sufficiently rare that it does not warrant adding > a new variant letter: I can understand that =97 if there are reasonable alternatives. I would, however, like to dissect your reasoning a bit if you don't mind =97 not to press my idea forward (though I know I have a tendency to give that impression) but to better understand your considerations. > this is expensive, since each function would > need a new variant, hence a new entry in TeX's hash table, and this > adds up pretty quickly to a very large number of csnames spent, > slowing TeX down. I don't see why every function should be pre-generated with a :U variant. In fact, I would suggest that the programmer be forced to generate, for himself, all the :U variants that he needs, because its use will indeed be relatively rare. > The proposed 'U' argument type would be altering the variable > appearing as the corresponding argument, which is quite contrary to > anything that any other argument type does. That, in and of itself, is never a convincing argument to me. The principle of least surprise sometimes has to be sacrificed to add useful features or solve problems. And in this case it's not even that much surprise. The existing argument-types already have fundamentally different behaviors: * :c and :v turn a csname into a cs, * :x makes a function unexandable, * :p has one very specific use-case; * :w can basically do anything; * :D may not be used at all (but is still in the interface documentation= ); * :T and :F are just for show. This is not meant negatively. I'm just saying that by comparison, :U would not be all that shocking. > Indeed, \unique_csname:N has no way to know when a given > unique name is not used anymore. This means that every time > the map_inline function is called, a new unique csname is used. > TeX will run out of hash table space relatively fast A very good point. > \cs_new_protected:Nn \something_map_inline:Nn { > \unique_csname:n { > \cs_set:cpn {##1} ####1####2 {#2} > \something_map_function:Nc #1 {##1} > } > } This looks familiar. In anticipation of your question at the end of the mail: this is a very specific case of what my `\with` command does. It's basically a one-shot anonymous-function-body =97 with arbitrary argument-types =97 which is called immediately. It allows you to "turn values into #-arguments" by beta-reduction. > \cs_new_protected:Nn \something_map_inline:Nn { > \unique_csname:n { > \cs_set:cpn { \l_unique_tl } ##1##2 {#2} > \something_map_function:Nc #1 { \l_unique_tl } > } > } > > The first one is a bit confusing since # does not need doubling, but > ## does become ####. Actually, the user of `\something_map_inline:Nn` will now need to double all their #s. I've run into this problem myself, and the solution is to let #2 pass through \unique_csname too, unaltered, then use it as ##2. (See below for my `\with` solution.) > The second one is a bit risky since one can only > use \l_unique_tl before any other \unique_csname:n is called: here it > is safe because \cs_set:cpn does not use \unique_csname:n. This is exactly the kind of risk I wanted to mitigate with `\with`. Though it has other uses. > In fact, perhaps the right approach is that I revive some ideas I had > about objects. Mapping a function then amounts to repeatedly popping > the first item and acting with the function. I roughly see how to > write a wrapper for that, which would mean that the package writer > would not need to worry about defining the mapping function: rather he > would define a \something_get:N or \something_pop:NN function, and the > framework would do the work of defining map_function and map_inline. > This is a longer term idea. This would be a very useful contribution. Anything to auto-generate all three mapping functions (including _map_tokens) from a simple description. > In any case, most of the above concerns specifically the application > of your idea to defining map_inline. If you have more examples where > unique identifiers are useful, it would be very helpful to give them, > so as to either find alternatives or get a better view of what would > be needed. Generally, any situation where an unbounded number of separate internal macros are needed without the API user providing names for them. I use it for `\with`. I use it for my ":r pointers". > Can you give a short example of use of that package? I'm curious, and > slightly too lazy to figure out the code. :-) I don't want you to read the code right now anyway. ;-) It doesn't exactly follow LaTeX3 guidelines yet. To give you some examples of its use, here's a simple one, used to force some specific expansion on a value buried deep inside an expression: \with:Vn \l_variable_tl { \bla:n { \do_not_expand_me bla bla bla #1 bla bla } } Here's how I currently implement my `\something_map_inline`s. I use the non-expl3 version of `\with`, because expl3 doesn't have :U. \cs_new_protected:Nn \something_map_inline:Nn { \with {Unn} [map_inline] [#2] { \cs_set:cpn {##1} ####1####2 {##2} \something_map_function:NN #1 {##1} } } The argument I give to the :U here is just some description which is added to the csname, for debugging purposes. Finally, here's how I create a new pointer with an initialized value: \cs_new_protected:Nn \ptr_new:Nn { \with{u} [ptr] [#2] { \tl_set:Nn #1 {##1} \tl_new:c {##1} \tl_set:cn {##1} {##2} } } -- www.mhelvens.net