2011/9/18 Joseph Wright <[log in to unmask]>: > On 18/09/2011 09:50, Philipp Stephani wrote: >> but I'm quite sure that the removal of >> \tl_new:Nn, \ior_new:N and \iow_new:N should be reverted. It is >> universally considered good style to combine declaration and >> initialization of variables, and having two different commands for >> declaration and setting leads to awkward duplication. > > Part of the reasoning we had here is that \tl_new:Nn was being used > almost entirely for declaring constants. We have a conceptually-separate > \tl_const:Nn for that job. I think both make sense, just like in other programming languages, where you have e.g. "const int x = ..." as well as "int x = ...". > > The other part to the reasoning was that while we had \tl_new:Nn, we did > not have \int_new:Nn, etc. So we were not exactly consistent in that > regard. I guess based on the underlying TeX concept that registers have > to be allocated separately to assignment, it seemed easier to take a > similar approach to everything. (I also note that we'd have issues with, > for example, property lists as they can't really be created and > fully-assigned in one shot, at least through anything like the > documented interface.) I would indeed propose having both _new:N and _new:Nn for all variable types. Adding them should not be a big deal (since all parts are already there), but simulating them manually is quite cumbersome, especially because variable names tend to be quite long due to the lack of namespaces: \int_new:N \l_package_foo_bar_int \int_set:Nn \l_package_foo_bar_int { 1 + 2 } > >> Regarding >> \io[rw]_new, without them it is is impossible to check for overwriting >> of stream names. Just like with all other variable types, these should >> be declared before usage. > > This is a slightly different issue, as streams are not exactly > variables. In the current implementation, streams are undefined when > they are closed, as once TeX closes a write stream we can't simple > re-open it. We could I guess check for an existing file, read the entire > thing to memory, then re-write it and then append. On the other hand, > perhaps this would be overkill and simply overwriting would be the > correct response. With a read stream, I guess we'd need to worry about > whether you'd store the position in the file, so that you'd re-start > from the same line. Again, this might be overkill. I guess an > alternative is to set up the code such that a stream which has been > closed will give a suitable error message if one tries to use it. I'm only talking about variable names here. I think at the moment it is possible to call \ior_open with both undefined and defined stream values, and I think that is a bit at odds with other variable types. If a dedicated \ior_new macro existed, then \ior_open could be modified to only accept defined variables. Or even simpler, \ior_new could just be \chk_if_free_cs. > >> Also a \cs_new:N command is missing which reserves a "function" name >> without assigning it. Both \io[rw]_new:N and \cs_new:N can essentially >> be aliases for \chk_if_free_cs. > > Well, they can't simply be \chk_if_free... as there has to be a > 'reserve' stage too. With \cs_new:N, the problem was that you don't know > how many arguments there may be, or in what form they could be. So you'd > at the least need \cs_new:Np, and then have to work out how to delimit > the end of the primitive argument specification. That's before you worry > about long and protected status (which apart from a small number of > tmp:w functions should not vary). So for functions I'm not sure I see a > gain over \cs_new(_protected)(_nopar):N(p)n. This is only for the situation where one wants to reserve a macro name for later use. In fact, \cs_new:N could be \chk_if_free_cs (then it is irrelevant what arguments will be there—I'm using this regularly to make sure a certain name is not taken yet), or \cs_new_eq:NN #1 \q_nil or \cs_new_eq:NN #1 \prg_do_nothing:c, with different semantics.