debug a reserved keyword (even for enums?)

libxmoc libxmoc at gmail.com
Sat Apr 11 09:33:34 UTC 2026


On Saturday, 11 April 2026 at 01:38:30 UTC, Jonathan M Davis 
wrote:
> On Friday, April 10, 2026 4:37:54 PM Mountain Daylight Time 
> Katastic via Digitalmars-d wrote:
>> Hello all, it's been awhile. I have a question. Does it make 
>> 'sense' that debug is a reserved keyword even when its inside 
>> an enum?
>>
>> ```D
>> enum loggingLevel {
>>   none = 0,
>>   debug, // Error: found `debug` when expecting `identifier`
>>   info,
>>   warning,
>>   error
>> }
>> ```
>>
>> Is there anywhere where that would actually clash?
>> ```D
>> void myFunction(loggingLevel l);
>> myFunction(loggingLevel.debug);
>>
>> with(loggingLevel){
>> myFunction(debug);
>> }
>> ```
>>
>> Is 'debug' used anywhere outside of version() statements? Would
>> it explode templates or something?
>
> As a general rule, keywords in D are keywords no matter where 
> they are. They are not contextual. As such, you cannot use them 
> anywhere other than where the language uses that word. There 
> are of course downsides to that approach, but it's simpler to 
> process than contextual keywords, and it tends to work better 
> with stuff like error messages (since the keyword then is 
> essentially an anchor point in the grammar instead of the 
> compiler needing to figure which context you're trying to use 
> the keyword in when the context isn't well-formed due to typos 
> or whatnot).
>
> Obviously, that's annoying when you have a situation where a 
> keyword is the best identfier, but you can't use it, because 
> it's a keyword. However, the solution that's generally used in 
> D (and given in the official style guide) is that when you need 
> to use a keyword as an identifier, you apppend an underscore to 
> it:
>
> https://dlang.org/dstyle.html#naming_keywords
>
> So, you'd have LoggingLevel.debug_ rather than 
> LoggingLevel.debug.
>
> A prime example of where this comes up in the standard library 
> is with std.traits.FunctionAttribute:
>
> https://dlang.org/phobos/std_traits.html#.FunctionAttribute
>
> The enum literally needs to list a bunch of keywords as its 
> values, and that's not legal, so trailing underscores have been 
> added to those keywords.
>
> - Jonathan M Davis

This is exactly the kind of friction that D editions should 
address.

I've been bitten by this twice recently: once designing a UI 
system where Align align; was illegal, and again a few months ago 
with SemVer version. Both times, the trailing underscore 
workaround felt like unnecessary concessions for perfectly 
unambiguous code.

The fundamental issue isn't whether non-contextual keywords are 
easier to parse, it's that D already has a mechanism to 
disambiguate: the dot operator. loggingLevel.debug, Align.align, 
and SemVer.version are all unambiguous to both the parser and the 
reader. The token following a dot is already in a different 
lexical context.

There's precedent for this in other languages. Rust allows 
self.as and match.as because keywords after . are unambiguous. 
Even C#—hardly a radical language—has contextual keywords in 
specific positions.

The "trailing underscore" convention is a concession that keeps 
accumulating.

debug_, version_, align_, function_, immutable_... at what point 
do we acknowledge that the cure (universal keyword reservation) 
is worse than the disease (contextual parsing complexity)?

Editions exist precisely to make breaking improvements like this 
possible without fragmenting the ecosystem.

Let's do it.



More information about the Digitalmars-d mailing list