local enum

Mr.Bingo Bingo at Namo.com
Sat Jul 7 18:48:35 UTC 2018


static foreach and enum do not play nice together!

import std.meta, std.stdio;
import std.string : leftJustify, center, rightJustify;
alias functions = staticMap!(ApplyRight!(Instantiate, string),
                              leftJustify, center, rightJustify);

void main()
{
	string result = "|";
	static foreach (f; functions)
	{
		enum y = &f;
		// pragma(msg, y("hello", 17));
		mixin("enum z = &"~f~".stringof;");
		pragma(msg, z);
          	auto x = &f; // not a template, but a function 
instantiation
         	result ~= x("hello", 17);
         	result ~= "|";
	}
	writeln(result); // "hello  ; hello ;  hello;
}

Besides the issue of trying to print out information about f at 
compile time, which is what I was working on here, since the 
above is a cool way to aggregate similar functions at compile 
time, I run in to the notorious issue of using enum's in loops!

The enums are local in nature and are used to store intermediate 
results but the looping tries to redefine them, which gives an 
error.

Instead, how about having a new type or keyword such as __local 
than can create a temporary enum that is only valid inside the 
loop just like a local variable:

void main()
{
	string result = "|";
	static foreach (f; functions)
	{
		__local enum y = &f;
		// pragma(msg, y("hello", 17));
		mixin("__local enum z = &"~f~".stringof;");
		pragma(msg, z);
          	auto x = &f; // not a template, but a function 
instantiation
         	result ~= x("hello", 17);
         	result ~= "|";
	}
	writeln(result); // "hello  ; hello ;  hello;
}

here y and z then are local to the static for each and only exist 
within it's scope. The compiler then will not error out about 
redefinitions.

I know this is a trivial example that does not require __local 
enums but in many cases they are necessary or reduce complexity.


Because I'm nice, I will give a hack that can be used, but this 
hack should only be used by those who think the compiler 
shouldn't automatically do this type of stuff for us:

void main()
{
	static foreach (k, f; [113,22,13])
	{
		mixin("enum y"~to!string(k)~" = f;");		
		mixin("pragma(msg, y"~to!string(k)~");");
	}
}

The idea is simply to create a new enum per loop.  This is not an 
acceptable hack but the compiler could do this internally really 
simple, which is what __local would signify reducing all the 
overhead and the above is then represented as


void main()
{
	static foreach (f; [113,22,13])
	{
		__local enum y = f;		
                 pragma(msg, y);
	}
}

Much nicer and one can imagine how this would simplify a lot of 
code.

Another, probably better idea is to simply allow enums to be 
overwritten at compile time:

void main()
{
         venum y;
	static foreach (f; [113,22,13])
	{
		y = f;		
                 pragma(msg, y);
	}
}




More information about the Digitalmars-d mailing list