## LATEX-L@LISTSERV.UNI-HEIDELBERG.DE

 Options: Use Forum View Use Proportional Font Show Text Part by Default Condense Mail Headers Message: [<< First] [< Prev] [Next >] [Last >>] Topic: [<< First] [< Prev] [Next >] [Last >>] Author: [<< First] [< Prev] [Next >] [Last >>]

Hello all,

It occurs to me, as I write my new expl3 datastructure, that the
current convention for specifying and propagating 'global'ness of a
function (namely, by inserting a 'g' in the name somewhere) leads to
either code duplication or to the definition of boilerplace auxiliary
functions. It is also too easy to get copy-paste-happy and forget to
add a 'g' in an implementation somewhere.

I just wanted to suggest an alternative approach. It is compatible
with all existing code and might make implementations more readable.

Wherever functions now exist in pairs `\prop_put:Nnn` and
`\prop_gput:Nnn` I suggest the addition of a function
`\prop_sput:NNnn`, where 'global'ness is passed as the first parameter
(s stands for scoped). That is the one that would be directly
implemented —in terms of other s-functions. The other two are then
implemented in terms of it.

The choice of tokens for the first parameter are not important for
this idea. It might be one of `\pref_global:D` or `\tex_relax:D` to be
used directly at the lowest level, but I'm not yet familiar enough
with the l3 core to make a proper decision there.

To encapsulate that detail and to save typing, I furthermore suggest
that functions like `\cs_new_protected(_nopar)_scoped:NpnNN` are made
available. To demonstrate their use, I compare the current `\prop_put`
definitions with the new ones I propose:

-------------------- Current code --------------------
\cs_new_protected_nopar:Npn \prop_put:Nnn
{ \@@_put:NNNnn \tl_set:Nx \tl_put_right:Nx }
\cs_new_protected_nopar:Npn \prop_gput:Nnn
{ \@@_put:NNNnn \tl_gset:Nx \tl_gput_right:Nx }
\cs_new_protected:Npn \@@_put:NNNnn #1#2#3#4#5
{
\tl_set:Nn \l_@@_internal_tl
{ \s_@@ \tl_to_str:n {#4} \s_@@ { \exp_not:n {#5} } }
\@@_split:NnTF #3 {#4}
{ #1 #3 { \exp_not:n {##1} \l_@@_internal_tl \exp_not:n {##3} } }
{ #2 #3 { \l_@@_internal_tl } }
}
-------------------- Proposed code --------------------
\cs_new_protected_nopar_scoped:NpnNN \prop_sput:NNnn #1#2#3#4
{
\tl_set:Nn \l_@@_internal_tl
{ \s_@@ \tl_to_str:n {#3} \s_@@ { \exp_not:n {#4} } }
\@@_split:NnTF #2 {#3}
{ \tl_sset:NNx #1 #2 { \exp_not:n {##1} \l_@@_internal_tl
\exp_not:n {##3} } }
{ \tl_sput_right:NNx #1 #2 { \l_@@_internal_tl } }
}
\prop_put:Nnn  \prop_gput:Nnn
------------------------------------------------------------

Some of the above (like the naming-scheme and the argument specifiers)
might even be automatically derived, but for the purpose of this
example I didn't want to go that far.

Note that `\tl_sset:NNx` and `\tl_sput_right:NNx` are now spelled out
in their proper place, so the reader doesn't have to go back and forth
to understand what's going on. There is no need for auxiliary
functions and errors of omission are unlikely, since omitting #1 would