What type functions mean on a language level

Max Haughton maxhaton at gmail.com
Fri Jan 1 23:52:58 UTC 2021


On Friday, 1 January 2021 at 23:26:58 UTC, Stefan Koch wrote:
> Good Evening and Happy new year to everyone.
>
> After a stressful move to the UK in uncertain times, I am now 
> free and able to enjoy the last day of my holiday.
>
> I am currently not working on DMD but on a different hobby 
> project instead.
>
> So with some distance between me and the implementation details 
> I think it's a good idea to talk about what type functions mean 
> for the language (regardless of all the architecture issues  in 
> DMD which make an implementation iffy)
>
> Specification wise type functions require two statements to be 
> added.
>
> "Under certain conditions a type may be implicitly converted to 
> a value of type __type__."
> and
> "Under certain conditions a value of type __type__ may be 
> converted to a type."
>
> That's it.
>
> Everything else is just working regularly with value and 
> expressions.
>
> let me give you an example.
>
> enum TK
> {
>   Integral,
>   Floating,
>   Other,
> }
>
> string ts(__type__ t)
> {
>   switch (t)
>   {
>      case ubyte, byte, ushort, short, int, uint, long, ulong:
>          return TK.Integral;
>      case double, float, real :
>          return TK.Floating;
>      default:
>          return TK.Other;
>   }
> }
>
>
> this looks like it would require a new construct right?
> infact it does not.
>
> since the types are used in a ctfe context where values are 
> expected they get implicitly converted to values.
>
> so what happens is:
> string ts(__type__ t)
> {
>      case cast(__type__)ubyte, cast(__type__)byte, 
> cast(__type__)ushort, cast(__type__)short, cast(__type__)int, 
> cast(__type__)uint, cast(__type__)long, cast(__type__)ulong:
>          return TK.Integral;
>      case cast(__type__)double, cast(__type__)float, 
> cast(__type__)real :
>          return TK.Floating;
>      default:
>          return TK.Other;
>   }
> }
>
> which converts the types into values, the same stuff as 
> integers :)
> and since a switch works with integers it works with types as 
> well.
>
> And that is precisely the reason why I was so excited about my 
> invention/discovery.
>
> It just fits in. And requires minimal changes to the spec.
>
> You will see that I've punted on the definition of the 
> circumstances in which the implicit conversion from type to 
> value and vice versa may occur.
> That's just to keep the post short and avoid many long and 
> boring words ;)
>
> I do hope you get as excited as me when reading this.
>
> Regards,
> Stefan

I like this idea quite a lot, some questions/points:

1. How far does this go? Are we just exposing the frontends 
concept of a type (i.e. the contents of dmd.mtype) or a 
abstraction over it? Can I (say) make an entirely new type like a 
struct like I would with a mixin?

2. I don't think avoiding spec changes is necessarily a good 
thing - D is already fairly murky in that regard so (wrt previous 
point) specifying exactly what typefunctions can do is probably a 
good thing.

3. I think a similar thing wouldn't be all that bad for the AST - 
read-only I should say (the only that worries me in the abstract 
about that is that dmd's AST isn't very consistent in its API) - 
i.e. Being able to access it as a regular (say) class at CTFE 
rather than adding more and more and more __traits.


More information about the Digitalmars-d mailing list