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 p2IDieRJ032503 for ; Fri, 18 Mar 2011 14:44:41 +0100 Received: (qmail 16706 invoked by alias); 18 Mar 2011 13:44:35 -0000 Delivered-To: GMX delivery to rainer.schoepf@gmx.net Received: (qmail invoked by alias); 18 Mar 2011 13:44:34 -0000 Received: from relay.uni-heidelberg.de (EHLO relay.uni-heidelberg.de) [129.206.100.212] by mx0.gmx.net (mx017) with SMTP; 18 Mar 2011 14:44:34 +0100 Received: from listserv.uni-heidelberg.de (listserv.uni-heidelberg.de [129.206.100.94]) by relay.uni-heidelberg.de (8.14.1/8.14.1) with ESMTP id p2IDg4GO018834 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 18 Mar 2011 14:42:29 +0100 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 p2IDcdeB011272; Fri, 18 Mar 2011 14:39:29 +0100 Received: by LISTSERV.UNI-HEIDELBERG.DE (LISTSERV-TCP/IP release 16.0) with spool id 1223103 for LATEX-L@LISTSERV.UNI-HEIDELBERG.DE; Fri, 18 Mar 2011 14:39:29 +0100 Received: from relay.uni-heidelberg.de (relay.uni-heidelberg.de [129.206.100.212]) by listserv.uni-heidelberg.de (8.13.1/8.13.1) with ESMTP id p2IDdTwY014628 for ; Fri, 18 Mar 2011 14:39:29 +0100 Received: from mail-yi0-f49.google.com (mail-yi0-f49.google.com [209.85.218.49]) by relay.uni-heidelberg.de (8.14.1/8.14.1) with ESMTP id p2IDdG8U017236 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=FAIL) for ; Fri, 18 Mar 2011 14:39:22 +0100 Received: by yic15 with SMTP id 15so2474117yic.22 for ; Fri, 18 Mar 2011 06:39:15 -0700 (PDT) MIME-Version: 1.0 Received: by 10.151.135.34 with SMTP id m34mr1275148ybn.36.1300455555718; Fri, 18 Mar 2011 06:39:15 -0700 (PDT) Received: by 10.147.168.17 with HTTP; Fri, 18 Mar 2011 06:39:15 -0700 (PDT) References: <905C5ED0-6639-4DEB-95AC-A2FCB2C4491D@gmail.com> <935A1EA2-C971-4A3A-8DF4-6F890E0CFB32@gmail.com> <5256FD2C-CD53-4FF0-A405-5B8B2781E5EC@gmail.com> <19843.17637.935263.780194@morse.mittelbach-online.de> Content-Type: text/plain; charset=ISO-8859-1 X-Spam-Whitelist: Message-ID: Date: Fri, 18 Mar 2011 09:39:15 -0400 Reply-To: Mailing list for the LaTeX3 project Sender: Mailing list for the LaTeX3 project From: Bruno Le Floch Subject: Re: expl3's seq_pop_right etc. To: LATEX-L@listserv.uni-heidelberg.de In-Reply-To: <19843.17637.935263.780194@morse.mittelbach-online.de> Precedence: list List-Help: , List-Unsubscribe: List-Subscribe: List-Owner: List-Archive: X-GMX-Antispam: 0 (Mail was not recognized as spam); Detail=5D7Q89H36p4U4jfdfC5HDevlx1X2sAZgAaLl3DbFfW0PXxL7WgvovMFXXSEPrACW/b9IW Qp+GhEViZlUW4mdBntgP1X8KwB5tjHCA/yxSZMu7BXBiPs3ujyaoi2xLHDqpg8dk65Dhpb3Lg0c1 iTjGg==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: 6687 To be clear, I'm perfectly ready to keep the old interface. I was mostly concentrating on the implementation, and some functions appeared more natural than the existing ones in that context. > > Then there is the issue of l3candidates, which I have not > > re-programmed yet, as well as the quicksort defined in l3prg.dtx > > one step at a time i'd say. I meant that there are some \seq_from_clist and \clist_from_seq functions in l3candidates which will have to be rewritten, and a \seq_quicksort, or something like that, which I haven't looked at. I'm _definitely not_ rewriting l3prg.dtx :). > > - I don't like the fact that \seq_(g)pop return its value locally, so > > I changed which functions are provided there to \seq_pop_with:Nn > > {}. > > Im not sure here. > > - the general design principle is that all functions that get values from > some data structure *always* store them *locally* in a variable. > > - the data structure itself could be local or global and a manipulation of > the structure could then be local or global too. Is there any example of data structure other than seq or prop? > On the other hand popping + using the value is a quite common usage, so to > have to always write > > \seq_pop_left_with:Nn \l_foo_seq {\tl_set:Nn \l_bar_tl} > > instead of > > \seq_pop:NN \l_foo_seq \l_bar_tl I see your point. Then perhaps renaming \seq_pop_left_with:Nn to \seq_pop_left_do:Nn, and leaving \seq_pop:NN as it is could make sense. Then if we just want to remove the left-most element and apply some function onto it, we can do \seq_pop_left_do:Nn \l_foo_seq {\foo:nn {}} and to get a global return value we would do \seq_pop_left_do:Nn \l_foo_seq {\tl_gset:Nn \g_foo_tl} Basically, I'm just making an auxiliary function available to the user. > now having written that I noticed that it isn't true, this is violated in > l3prop where there are gget functions for key values, so hmmm ... still I > tend towards the rule above I guess I think that you are right: there should be a \..._pop_left:NN, which does something consistent between the various data structures. Choosing local return values is as good as anything. > not sure what you mean here. clearly if you loop directly over a sequence > then using mapping is preferable, but often when you do one element at a time the > actions are complex so that they don't quite fit into a mapping function I guess I was just stating the obvious to a TeX programmer: getting one element in the seq takes a time linear in the length of the seq. I.e., it is not much faster than mapping on every element. In terms of efficiency, it is _much_ better to do \seq_map_inline:Nn \l_foo_seq { } than \bool_until_do:nn {\seq_if_empty_p:N \l_foo_seq} { \seq_pop_left:NN \l_foo_seq \l_foo_tl } although the latter is probably clearer. > > - I expect the pop_right functions to be much faster for large > > sequences than simply storing the elements one by one. > > ??? Implementation detail. The naive way of doing things on the right-most element of the sequence is to remove elements one by one, and store them in a scratch register, until the last element is reached. That will be quadratic, and it turned out to be particularly tricky to get the linear version right. Anyways, unimportant here. > > - I'd like every "..._map_function:NN" to become > > "..._map_function:Nn", i.e. allow mapping several tokens at a time. It > > Personally I don't find this very intuitive; if you map a function you map a > function name and that would mean N. Besides you would lose the ability to > map a constructed function name ie "c" though that is something you would seldom > need I guess. My initial application was to be able to map a function with two arguments on two seq and at the same time. First I zipped the two seq into one seq whose item each have the form {}{}. Then I could map _expandably_ \seq_map_function:Nn \l_foo_zipped_seq {\exp_after:wN \foo_func:nn \use:n} where the \use:n unbraces its argument. Not a very convincing use. But Lars Madsen's examples with { \foo_func:nn {arg1} } are better. > I would rather do > > \cs_new:Npn \map_func:n #1 { \func:n #1} > ...map_function:NN \l_foo_seq \map_func:n That would be better as ...map_inline:Nn \l_foo_seq { \func:n {#1}} The key here is expandability. When it is not needed, map_inline:Nn and map_variable:NNn fit the bill nicely. The best might be to leave both the :NN and :Nn variants, synonyms of each other, hence taking little of TeX's memory. There is also the question of whether removing an elements once/all copies of it should be named as in l3clist or l3tl: \clist_remove_element:Nn \tl_remove_all_in:Nn \tl_remove_in:Nn I'd go for the tl version. Regards, -- Bruno