On Friday, 21 July 2023 at 08:52:47 UTC, Quirin Schroll wrote:
> On Thursday, 20 July 2023 at 13:44:15 UTC, Commander Zot wrote:
> wouldn't it be possible to have something like first class types (at compile time) to replace tamplates for type logic with regular functions executed at CTFE?
Of course, that’s possible. You’d have a type called Type
that represents types. Of course, Type
does not actually exist, a function that takes Type
parameters or returns Type
cannot end up in the object file. But for CTFE, the compiler can pretend that Type
is just a type like Object
.
In my imagination, you’d have a transformation from “actual” types (as per D’s grammar) to Type
objects. For built-in types, object.d could provide predefined variables, like Int
for int
: Int
is an object of type Type
that represents int
. It could be a built-in pseudo-template type!T()
that returns the Type
for T
or maybe the transformation can be applied even implicitly; object.d would contain enum Int = type!int;
and friends.
The Type
objects can be manipulated with regular functions and function templates. At CTFE, Type
is just a type.
we already have TypeInfo, which should be used for this too. i'd just add a alias type_t or something.
> To get “actual” types back from a Type
object at compile time, you need another mechanism, ideally I’d say, use mixin
.
Instead of int x;
you could mixin(Int) x;
.
I don't see how that would be useful. it's like restricting an int parameter to specific values. it can be done in the function body.
> D’s templates are expressive enough to implement every function you could use Type
, so it’s technically redundant, and not everything that can be expressed using templates can (or should) be done by (CTFE-only) functions with Type
; essentially every non-alias template is an example. On the other hand, in the current state, every algorithm that could be applied to types (like sorting a bunch of types) must be implemented in templates because the value algorithm cannot be used. That I call redundancy.
As a rule of thumb, if you want to manipulate types like a puppet master, you’d use a Type
function; if you’re interested in using the types, e.g. handling objects that have that type, you’d use good old templates.
excatly. and i'm really tired of writing recursive functions for those things.