How about a special null template parameter?

Engine Machine via Digitalmars-d digitalmars-d at puremagic.com
Fri Aug 19 14:51:38 PDT 2016


On Friday, 19 August 2016 at 19:19:35 UTC, Lodovico Giaretta 
wrote:
> On Friday, 19 August 2016 at 18:25:06 UTC, Engine Machine wrote:
>> So we can create types relationships easier:
>>
>> class Type(T) : Type!null
>> {
>>    int x;
>>    static if (T is Dog)
>>        int y;
>> }
>>
>> Type == Type!null (!null implicit, only if defined in the 
>> above way. Essentially an alias is created for us 
>> automatically)
>>
>> Type(T) : Type!nullinherits only if T is not null(or a type 
>> that inherits from itself,  which would then be valid).
>>
>> Type!Dog inherits from Type/Type!null.
>>
>> Type!T inherits from Type/Type!null as long as T != null.
>>
>> Members in base(null) are not re-included in derived(e.g., int 
>> x; isn't include in Type!Dog because it's already there from 
>> base).
>>
>> This simple syntactic sugar allows us to create multiple 
>> classes to create simple inheritance hierarchy.
>>
>> It replaces the current method of having to define a 
>> non-templated class and a templated class.
>>
>> e.g.,
>>
>> class Type
>> {
>>    int x;
>> }
>>
>> class Type(T) : Type
>> {
>>    static if (T is Dog)
>>       int y;
>> }
>>
>>
>>
>> vs
>>
>>
>>
>> class Type(T) : Type!null
>> {
>>    int x;
>>    static if (T is Dog)
>>        int y;
>> }
>
> 1) `null` has a very precise meaning: it is the only valid 
> value of an unnamed type only known as `typeof(null)`, which 
> implicitly converts to any class/pointer/dynamic 
> array/associative array type. Thus this thing should have a 
> different name.

null as many interpretations. It is ok to expand the meaning. It 
is done all the time. If it confuses you are creates a semantic 
difficulty, I don't mind what it is called. It could be called 
Boomfurkasufasdf.

In this case, defining it to be null fits in semantically though. 
If it creates some compiler issue then, again, anything else 
could be used. I'd prefer Null or NULL or Aleph or something 
short and meaningless.



> 2) What about this case:
> ```
> class Type(T): Type
> {
>     static if (T is Dog)
>         int y;
>     else
>         float z;
> }
> ```
> What should be inside the base?

z.


> 3) I guess that you may find this useful to write functions 
> that accept any type this way:
> ```
> void myFunction(Type val)
> {
>     // only use fields in common between all Type instantiations
> }
> ```
> But you can already do that this way, which is way more 
> flexible:
> ```
> void myFunction(T)(Type!T val)
> {
>     // use fields in common between all instantiation,
>     // but also fields specific to a certain instantiation,
>     // using static if
> }
> ```

Well, that is not really what I'm after. I am after simplifying 
class design.

> 4) I think that the value of this addition is little wrt. the 
> amount of work the compiler should do to implement it (which at 
> first sight would be a lot). But this is of course just my 
> opinion.

It is just syntactic sugar and requires no complex compiler 
modifications. The benefit is reduced visual complexity and that 
is always a bonus. That is the point we don't write in 0's and 
1's... everything else is just syntactic sugar. In this case, it 
is a very simple rewrite rule. A few lines of code would be all 
that is required.





More information about the Digitalmars-d mailing list