Print

Print


Frank Mittelbach skrev 2011-03-18 12.41:
>   >  - I'd like every "..._map_function:NN" to become
>   >  "..._map_function:Nn", i.e. allow mapping several tokens at a time. It
>   >  isn't difficult to adapt the code for that, and it would be quite
>   >  practical, since among the mappings, only the "map_function" are
>   >  expandable. For that reason, "\seq_map_function:NN" is not defined in
>   >  the file I attach.
>
> 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.

And it would be covered by applying a suitable \exp_args:... to the 
..._map_function:... call, would it not?

> If you map several tokens then this means that you either have a bunch of
> static tokens plus a final token/function that picks up the argument. Or
> alternatively you map a function with several arguments (and only the last one
> is filled with items from the sequence)

This is what /I/ would expect to use such a feature for. In some circles, 
it's called currying: construct an n-k arguments function from an n 
arguments function by passing it with the first k arguments already supplied.

> or it is a mixture of both. None of
> those scenarios feel right to me. From a programming aspect I would probably
> always prefer to define my mapping function properly first and then apply it,
> ie instead of
>
>   ...map_function:Nn \l_foo_seq {<some tokens>  \func:n }
>
> I would rather do
>
>   \cs_new:Npn \map_func:n #1 {<some tokens>  \func:n #1}
>
>   ...map_function:NN \l_foo_seq \map_func:n

And instead of

   ...map_function:Nn \l_foo_seq { \func:nn{foo} }

rather do

   \cs_new:Npn \map_func:n #1 { \func:nn{foo}{#1} }

   ...map_function:NN \l_foo_seq \map_func:n

? The downside of this is that it hardwires the "foo" into a function 
body, when in practice it might be data that changes from call to call. 
You can of course redefine \map_func:n before every use, but it feels 
unelegant.

> This has to be done anyway if the #1 needs to be somewhere other than at the
> end, eg
>
>   \cs_new:Npn \map_func:n #1 {\func:nnn {foo}{#1}{bar}}

Not at all! In that case, you do

   \cs_new:Npn \exch_args:Nnnn #1 #2 #3 #4 { #1{#2}{#4}{#3} }

   ...map_function:Nn \l_foo_seq { \exch_args:Nnnn\func:nnn{foo}{bar} }

(the stem "exch" is of course from the postscript operator which exchanges 
the top two operands on the stack) or possibly

   \cs_new:Npn \exchd_func:nnn #1 #2 #3 { \func:nnn{#1}{#3}{#2} }

   ...map_function:Nn \l_foo_seq { \exchd_func:nnn{foo}{bar} }

but \exch_args:Nnnn is more elegant, since it can be reused in more places.


Lars Hellström