Thread overview | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
December 04, 2013 Using "cast(enum)" for explicit request of ctfe | ||||
---|---|---|---|---|
| ||||
I love D's ctfe capabilities. They allow using complex values, with no run-time cost, and at a very low "code" cost. One thing that does kind of get on my nerves is how you *always* have to declare an actual enum to do that. You can't do CTFE on the fly. This ranges from mildly annoying, typically: //Declare a CTFE message enum message = format("Some message: %s", some_static_args); //Use the CTFE message enforce(pointer, message); Or, also, enum fib5 = fib(5); //CTFE calculate writeln(fib5); //use To, sometimes, downright *impossible*. If you ever need to do CTFE inside the body of a static foreach, dmd will block you due to "redeclaration": foreach(T; Types) { enum message = format("This type is %s.", T.stringof); //Error! Redaclaration writeln(message); } Fixing this one requies an external template that will create your enum on the fly. ---------------- I'm thinking: While this is all surmountable, I'm pretty sure the language could give us a easier time of this. We have the possibility to declare and call a lambda both in one line. Why not be able to declare a ctfe value as a 1-liner too? I'm thinking, a simple cast: A cast to the "enum" type, which explicitly means "this value needs to be compile time known". Usage would look like: enforce(pointer, cast(enum)format("Some message: %s", some_static_args)); writeln(cast(enum)fib(5)); foreach(T; Types) writeln(cast(enum)format("This type is %s.", T.stringof)); Here, we have some very simple code, no redundant variables, and no run-time overhead. I'm just throwing this out there to get some quick feedback before filling an ER, or maybe a DIP. Or, if somebody has an idea of how to do this via a library solution? Thoughts? |
December 04, 2013 Re: Using "cast(enum)" for explicit request of ctfe | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Wednesday, 4 December 2013 at 11:12:54 UTC, monarch_dodra wrote:
> Or, if somebody has an idea of how to do this via a library solution?
alias eval(alias exp) = exp;
|
December 04, 2013 Re: Using "cast(enum)" for explicit request of ctfe | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On 4.12.2013. 12:12, monarch_dodra wrote:
> I love D's ctfe capabilities. They allow using complex values, with no run-time cost, and at a very low "code" cost.
>
> One thing that does kind of get on my nerves is how you *always* have to declare an actual enum to do that. You can't do CTFE on the fly.
>
> This ranges from mildly annoying, typically:
>
> //Declare a CTFE message
> enum message = format("Some message: %s", some_static_args);
> //Use the CTFE message
> enforce(pointer, message);
>
> Or, also,
> enum fib5 = fib(5); //CTFE calculate
> writeln(fib5); //use
>
> To, sometimes, downright *impossible*. If you ever need to do CTFE inside the body of a static foreach, dmd will block you due to "redeclaration":
>
> foreach(T; Types)
> {
> enum message = format("This type is %s.", T.stringof); //Error!
> Redaclaration
> writeln(message);
> }
>
> Fixing this one requies an external template that will create your enum on the fly.
>
> ----------------
>
> I'm thinking: While this is all surmountable, I'm pretty sure the language could give us a easier time of this. We have the possibility to declare and call a lambda both in one line. Why not be able to declare a ctfe value as a 1-liner too?
>
> I'm thinking, a simple cast: A cast to the "enum" type, which explicitly means "this value needs to be compile time known". Usage would look like:
>
> enforce(pointer, cast(enum)format("Some message: %s", some_static_args));
> writeln(cast(enum)fib(5));
> foreach(T; Types)
> writeln(cast(enum)format("This type is %s.", T.stringof));
>
> Here, we have some very simple code, no redundant variables, and no run-time overhead.
>
> I'm just throwing this out there to get some quick feedback before filling an ER, or maybe a DIP.
>
> Or, if somebody has an idea of how to do this via a library solution?
>
> Thoughts?
You can use Eval template:
template Eval (alias value) {
alias value Eval;
}
writeln(Eval!(1 + 1));
enforce(pointer, Eval!(format("Some message: %s", some_static_args)));
Does this answer your question?
|
December 04, 2013 Re: Using "cast(enum)" for explicit request of ctfe | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jakob Ovrum | On Wednesday, 4 December 2013 at 11:32:40 UTC, Jakob Ovrum wrote:
> On Wednesday, 4 December 2013 at 11:12:54 UTC, monarch_dodra wrote:
>> Or, if somebody has an idea of how to do this via a library solution?
>
> alias eval(alias exp) = exp;
Nice :D
Very very nice. Though that should be "enum" I think.
I think having this somewhere in Phobos would be a great addition.
Not sure "eval" would be correct though, as "eval" tends to imply parsing.
I'll just file a simple ER then. Where would we put such an addition?
|
December 04, 2013 Re: Using "cast(enum)" for explicit request of ctfe | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Wednesday, 4 December 2013 at 11:41:53 UTC, monarch_dodra wrote:
> On Wednesday, 4 December 2013 at 11:32:40 UTC, Jakob Ovrum wrote:
>> On Wednesday, 4 December 2013 at 11:12:54 UTC, monarch_dodra wrote:
>>> Or, if somebody has an idea of how to do this via a library solution?
>>
>> alias eval(alias exp) = exp;
>
> Nice :D
>
> Very very nice. Though that should be "enum" I think.
>
> I think having this somewhere in Phobos would be a great addition.
>
> Not sure "eval" would be correct though, as "eval" tends to imply parsing.
>
> I'll just file a simple ER then. Where would we put such an addition?
Right, maybe it should be (substitute the name `eval`):
---
template eval(alias exp) if(isExpressionTuple!exp)
{
static immutable eval = exp;
}
---
Which might make it avoid the pitfalls of using enum. Not sure if the `static` actually does something in this context, IIRC it does not.
No idea where to put it. I've experimented with such a template before but I haven't used it in any real code. object.d and std.typecons come to mind, but I don't particularly like the prospect of putting it in either.
|
December 04, 2013 Re: Using "cast(enum)" for explicit request of ctfe | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On 4.12.2013. 12:41, monarch_dodra wrote: > On Wednesday, 4 December 2013 at 11:32:40 UTC, Jakob Ovrum wrote: >> On Wednesday, 4 December 2013 at 11:12:54 UTC, monarch_dodra wrote: >>> Or, if somebody has an idea of how to do this via a library solution? >> >> alias eval(alias exp) = exp; > > Nice :D > > Very very nice. Though that should be "enum" I think. > > I think having this somewhere in Phobos would be a great addition. > > Not sure "eval" would be correct though, as "eval" tends to imply parsing. > > I'll just file a simple ER then. Where would we put such an addition? Eval comes from examples of http://dlang.org/function.html#interpretation |
December 04, 2013 Re: Using "cast(enum)" for explicit request of ctfe | ||||
---|---|---|---|---|
| ||||
Posted in reply to luka8088 | On Wednesday, 4 December 2013 at 11:54:08 UTC, luka8088 wrote:
> Eval comes from examples of http://dlang.org/function.html#interpretation
A couple of notes:
The use of a variadic template parameter instead of an alias parameter is misleading because the template does not need to support types in the first place (and the proposed implementation would fail when given a type).
The name used on dlang.org is correctly using a lowercase `e`, according to the naming convention for templates that always evaluate to values/variables as opposed to types.
|
December 04, 2013 Re: Using "cast(enum)" for explicit request of ctfe | ||||
---|---|---|---|---|
| ||||
Posted in reply to luka8088 | On Wednesday, 4 December 2013 at 11:54:08 UTC, luka8088 wrote:
> On 4.12.2013. 12:41, monarch_dodra wrote:
>> On Wednesday, 4 December 2013 at 11:32:40 UTC, Jakob Ovrum wrote:
>>> On Wednesday, 4 December 2013 at 11:12:54 UTC, monarch_dodra wrote:
>>>> Or, if somebody has an idea of how to do this via a library solution?
>>>
>>> alias eval(alias exp) = exp;
>>
>> Nice :D
>>
>> Very very nice. Though that should be "enum" I think.
>>
>> I think having this somewhere in Phobos would be a great addition.
>>
>> Not sure "eval" would be correct though, as "eval" tends to imply parsing.
>>
>> I'll just file a simple ER then. Where would we put such an addition?
>
> Eval comes from examples of http://dlang.org/function.html#interpretation
Alright, then eval is fine.
|
December 04, 2013 Re: Using "cast(enum)" for explicit request of ctfe | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jakob Ovrum | On Wednesday, 4 December 2013 at 11:51:11 UTC, Jakob Ovrum wrote: > Right, maybe it should be (substitute the name `eval`): > > --- > template eval(alias exp) if(isExpressionTuple!exp) > { > static immutable eval = exp; > } > --- > > Which might make it avoid the pitfalls of using enum. Not sure if the `static` actually does something in this context, IIRC it does not. Problem is that doing this returns an immutable type, which isn't quite the same as a ctfe variable (which was the initial goal, as far as I'm concerned) > No idea where to put it. I've experimented with such a template before but I haven't used it in any real code. object.d and std.typecons come to mind, but I don't particularly like the prospect of putting it in either. Yeah... I wouldn't want to import all of typecons just for this, but if we split it into packages, it would perfectly fit in its own little package (IMO). |
December 04, 2013 Re: Using "cast(enum)" for explicit request of ctfe | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Wednesday, 4 December 2013 at 13:16:35 UTC, monarch_dodra wrote: > Problem is that doing this returns an immutable type, which isn't quite the same as a ctfe variable (which was the initial goal, as far as I'm concerned) Immutable "global" variables with initializers are readable at compile-time (as the initializers are required to be readable at compile-time). I don't know what you mean by "CTFE variable". It's probably better to use const over immutable though, so that it can accept values of a type with mutable indirection. Using enum has issues, as elaborated upon by Don in this enhancement request[1] (for reference; I'm sure you remember them). [1] http://d.puremagic.com/issues/show_bug.cgi?id=10950 |
Copyright © 1999-2021 by the D Language Foundation