Compile time values & implicit conditional mixin, as an alternative to tertiary operator hell and one-compile-time functions.

Paul paultjeadriaanse at gmail.com
Sat Jan 16 03:36:23 UTC 2021


I've gotten slightly tangled up with tertiary operators inside 
mixins, and it feels like the language is actively working 
against me, mostly due to the inability to create compile time 
only variable and the removal of comma operators.
In some sense, this makes compile time evaluation in D feels 
slightly incomplete / rough, which feels like a waste as its 
potential seems very powerful to me.

Consider the following excerpts:

> enum string values= "value.x" ~ (L == 1 ? "" : ",value.y" ~ (L 
> == 2 ? "" : ",value.z" ~ (L == 3 ? "" : ",value.w")));
> enum string kind = is(S == uint) ? "ui" :  (is(S == int) ? "i" 
> :  (is(S == float) ? "f" : (assert(is(S == double)), "d"))); 
> //(ignore the comma operator for now)

> mixin("glUniform" ~ L.to!string ~ kind ~ "(uniformlocation, " ~ 
> values ~ ");");

Noticing two things:
1. Due to this being at compile time, I'm trying to use enums. 
Sadly however, due to these being enums I cannot change them 
after their definition, and am thus forced to use tertiary 
operators (which feels problematic and very confusing)
2. Due to the comma operator being depricated (and not 
replaced?!) I can no longer "neatly" assert things inside the 
enum creation, and I see the possibility of needing another other 
than solely the double type assert, in which case adding an 
assert on the next line is no longer a valid option, given some 
'special' value for the "kind" enum string would no longer be 
possible.
(I would make a case for the comma operator only being renamed, 
in the exact same way one wouldn't ban goto, but that's beside 
this post)

Ideally this would be solved with one of the following:
- implicit conditional mixin, as an alternative to tertiary 
operator hell.
> enum string values = "value.x" (L >= 2 ?) ~ ",value.y" (L == 2 
> ?) ~ ",value.z" (L == 3 ?)~ ",value.w";

- compile time only variables (or functions*), as manifest 
constants cant be modified and normal variables are not useable 
inside mixins:
> compile string waardes = "waarde.x";
> static if(L>=2) waardes ~= ",waarde.y";
> static if(L>=3) waardes ~= ",waarde.z";
> static if(L==4) waardes ~= ",waarde.w";

I realized creating a seperate function to return a string 
callable inside mixin is an option. However creating a seperate 
function purely to do compile time string creation seems like a 
design flaw, which additionally does not prevent its usage at 
runtime.
* (Hence the mention of compiletime only functions, although this 
feels like a partial fix on the actual issue)

My dearest apology if this post is unhelpful, or if either of 
these two is actually possible!
The expressive power of compile time evaluation just feels ever 
so slightly out of my grasp, and I'd like to know what opinion 
the rest of the community has regarding this topic.


More information about the Digitalmars-d mailing list