[NTG-context] The odd semantics of \begincsname

Henri Menke henrimenke at gmail.com
Sat Aug 17 10:56:56 CEST 2019

On 17/08/19 8:48 PM, Hans Hagen wrote:
> On 8/17/2019 9:19 AM, Henri Menke wrote:
>> Dear list,
>>
>> According to the LuaTeX documentation:
>>
>>      “The \begincsname primitive is like \csname but doesn’t create a
>>      relaxed equivalent when there is no such name.”
>>
>> I thought it would be possible to use this fact to skip the \relax-ed
>> definition when \def-ining a new control sequence, but the following MWE
>> fails with \inaccessible:
>>
>>      \expandafter\gdef\csname yes\endcsname{}
>>      \expandafter\gdef\begincsname no\endcsname{}
>>      \bye
>>
>> Is this a bug or is this behaviour intended?  Could this be fixed by
>> making manufacture_csname aware whether it is in a def_cmd context or
>> not?
> [sorry to those who are not interested in these low level issues, just skip]
>
> intended ... it expands to basically nothing so you get no token
> representing a 'name' after the gdef .. the expansion is pushed in from
> of whatever comes next (which could be another \expandafter for instance)
>
> you suggest that if \begincsname could behave differently when it's
> after a \def, \gdef, (and then quite some more definition related
> commands), it could behave differently but it not an option
>
> for instance (as mentioned) there can be more than one expansion going
> on after these define commands, like expanding a macro that itself
> expands to \csname so one has several \expandafters before the gdef
> then); there is actually no looking back in scanning tokens unless a
> token has been scanned already and looking forward would involve
> expansion so a circular mess
>
> an option could be not to push something on the save stack (a side
> effect of creating the csname, which has a little impact on performance
> and nesting) but removing that bit might give other side effects (e.g.
> for successive reassignments inside a group, maybe even mixed local and
> global); i did a quick test with that and it gives quite incompatible
> output in ConTeXt so that's definitely a no-go (adding all kind fo
> saveguards and checks in the engine doesn't pay off, especially not for
> something that never was a problem)
>
> some time ago i considered a convenience command \[e]defcsname, as it
> saves a few tokens (no gain in performance as all the related things
> still need to happen); but even that one would probably create the name
> in the same way
>
> so ... this is the way it is ... (i must admit that it never gave me any
> issues so whatever triggered the question, there's probbaly a way around
> it)

I can accept this answer.  Just for a little context, the question was
triggered by this:

https://tex.stackexchange.com/questions/504501/global-variant-of-csname-endcsname

In short: Having thousands of

\expandafter\gdef\csname foo\endcsname{}

inside a group (as happens for xmltex), can lead to a save_stack
overflow.  One way around it is to do

\begingroup\expandafter\endgroup\expandafter\gdef\csname foo\endcsname{}

The \expandafter inside the group will pull the evaluation of \csname
into the group which will discard the save_stack at the \endgroup, thus
avoiding the build-up.  However, this construction is a bit hard to
understand so I was wondering whether

\expandafter\gdef\begincsname foo\endcsname{}

could be used instead to elide the save_stack (which doesn't work
because \begincsname does not actually build a \csname).

Cheers, Henri

> Hans
>
> -----------------------------------------------------------------
>                                            Hans Hagen | PRAGMA ADE
>                Ridderstraat 27 | 8061 GH Hasselt | The Netherlands
>         tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl
> -----------------------------------------------------------------
>