Jump to page: 1 2
Thread overview
Showing TypeFunction style
Oct 02, 2020
Stefan Koch
Oct 03, 2020
Jacob Carlborg
Oct 03, 2020
Stefan Koch
Oct 03, 2020
Basile B.
Oct 03, 2020
Stefan Koch
Oct 03, 2020
Basile B.
Oct 03, 2020
Basile B.
Oct 03, 2020
Stefan Koch
Oct 04, 2020
Basile B.
Oct 04, 2020
Timon Gehr
Oct 04, 2020
Stefan Koch
Oct 04, 2020
Stefan Koch
October 02, 2020
Hi there,

This evening I played with a partial translation of implicitConversionTargets help in phobos.

Here is what I have so far.
Note that this is not true transliteration because I wanted to show some of the more unknown type function features.
---
alias Bool = bool;
alias Ubyte = ubyte;
alias Byte = byte;
alias Ushort = ushort;
alias Short = short;
alias Uint = uint;
alias Int = int;
alias Ulong = ulong;
alias Long = long;

// for those ty.isFloating is true, which takes a diffrent path than all other types ;)
// therefore we can't use it as of now
//alias Double = double;
//alias Float = float;

enum basic_types = makeAliasArray(Bool, Ubyte, Byte, Short, Ushort, Uint, Int, Long, Ulong, /*Double, Float*/);

// temporarly needed because parser issues ....
auto makeAliasArray(alias[] types ...)
{
    return types;
}

auto convTargets(alias T)
{
    if (isBasicType(T))
        return basicTypeConvTargets(T);
    return S.init;
}

bool isBasicType(alias T)
{
    foreach(t;basic_types)
    {
        if (is(T == t))
            return true;
    }
    return false;
}

// just showing off that you can store type arrays in structs
struct S
{
    typeof(makeAliasArray()) result;
    size_t n;
    alias type;
}

auto basicTypeConvTargets(alias T)
{
    typeof(makeAliasArray()) targets;
    targets.length = basic_types.length;
    assert(isBasicType(T), "You may not call this function when you don't have a basic type ... (given: " ~ T.stringof ~ ")");
    size_t n = 0;
    foreach(t;basic_types)
    {
        if (is(T : t))
        {
            targets[n++] = t;
        }
    }
    return S(targets[0 .. n], n, T);
}

pragma(msg, convTargets(Long));  // S([(long), (ulong)], 2LU, (long))
pragma(msg, convTargets(Short)); // S([(short), (ushort), (uint), (int), (long), (ulong)], 6LU, (short))

---

I hope that this code will be nice and readable.

As a comparison, here is a piece from the template I translated which should be equivalent.

---

    static if (is(T == bool))
        alias ImplicitConversionTargets =
            AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong, CentTypeList,
                       float, double, real, char, wchar, dchar);
    else static if (is(T == byte))
        alias ImplicitConversionTargets =
            AliasSeq!(short, ushort, int, uint, long, ulong, CentTypeList,
                       float, double, real, char, wchar, dchar);
    else static if (is(T == ubyte))
        alias ImplicitConversionTargets =
            AliasSeq!(short, ushort, int, uint, long, ulong, CentTypeList,
                       float, double, real, char, wchar, dchar);
    else static if (is(T == short))
        alias ImplicitConversionTargets =
            AliasSeq!(int, uint, long, ulong, CentTypeList, float, double, real);
    else static if (is(T == ushort))
        alias ImplicitConversionTargets =
            AliasSeq!(int, uint, long, ulong, CentTypeList, float, double, real);
    else static if (is(T == int))
        alias ImplicitConversionTargets =
            AliasSeq!(long, ulong, CentTypeList, float, double, real);
    else static if (is(T == uint))
        alias ImplicitConversionTargets =
            AliasSeq!(long, ulong, CentTypeList, float, double, real);
    else static if (is(T == long))
        alias ImplicitConversionTargets = AliasSeq!(float, double, real);
    else static if (is(T == ulong))
        alias ImplicitConversionTargets = AliasSeq!(float, double, real);
---

The behavior is not 100% equivalent as the hand-written target list does not include signed conversions in the same size class. (I assume this is an omission).


Please leave comments and suggestions.

October 03, 2020
On 2020-10-03 00:24, Stefan Koch wrote:

> // temporarly needed because parser issues ....
> auto makeAliasArray(alias[] types ...)
> {
>      return types;
> }

Not sure if other cares, but your examples will look more appealing if you fix the parser.

-- 
/Jacob Carlborg
October 03, 2020
On Saturday, 3 October 2020 at 07:36:17 UTC, Jacob Carlborg wrote:
> On 2020-10-03 00:24, Stefan Koch wrote:
>
>> // temporarly needed because parser issues ....
>> auto makeAliasArray(alias[] types ...)
>> {
>>      return types;
>> }
>
> Not sure if other cares, but your examples will look more appealing if you fix the parser.

Yeah ... I know. It's one of these things I keep putting off.

You could remove all the aliases from my example if I did fix the parser.

October 03, 2020
On Saturday, 3 October 2020 at 08:44:53 UTC, Stefan Koch wrote:
> On Saturday, 3 October 2020 at 07:36:17 UTC, Jacob Carlborg wrote:
>> On 2020-10-03 00:24, Stefan Koch wrote:
>>
>>> // temporarly needed because parser issues ....
>>> auto makeAliasArray(alias[] types ...)
>>> {
>>>      return types;
>>> }
>>
>> Not sure if other cares, but your examples will look more appealing if you fix the parser.
>
> Yeah ... I know. It's one of these things I keep putting off.
>
> You could remove all the aliases from my example if I did fix the parser.

a DIP for TypeFunction requires the parser change. There are two possibilities

1. a new keyword
2. use a symbol, e.g like template instanciation with a bang

The first soltion is absolutly aweful. It leads to deprecate an identifier, which will delay the feature.

The second is more likely what should be adopted. At first glance I'd propose a double bang.

    string templateStuff = instance!stuff();
    string typefuncstuff = callAtCompileTime!!stuff()

so after the double bang, the parser can parse a TypeFuntionCallExpr call instead of a CallExpr.


October 03, 2020
On Saturday, 3 October 2020 at 10:05:23 UTC, Basile B. wrote:
> On Saturday, 3 October 2020 at 08:44:53 UTC, Stefan Koch wrote:
>> On Saturday, 3 October 2020 at 07:36:17 UTC, Jacob Carlborg wrote:
>>> On 2020-10-03 00:24, Stefan Koch wrote:
>>>
>>>> // temporarly needed because parser issues ....
>>>> auto makeAliasArray(alias[] types ...)
>>>> {
>>>>      return types;
>>>> }
>>>
>>> Not sure if other cares, but your examples will look more appealing if you fix the parser.
>>
>> Yeah ... I know. It's one of these things I keep putting off.
>>
>> You could remove all the aliases from my example if I did fix the parser.
>
> a DIP for TypeFunction requires the parser change. There are two possibilities
>
> 1. a new keyword
> 2. use a symbol, e.g like template instanciation with a bang
>
> The first soltion is absolutly aweful. It leads to deprecate an identifier, which will delay the feature.
>
> The second is more likely what should be adopted. At first glance I'd propose a double bang.
>
>     string templateStuff = instance!stuff();
>     string typefuncstuff = callAtCompileTime!!stuff()
>
> so after the double bang, the parser can parse a TypeFuntionCallExpr call instead of a CallExpr.

Actually, no.
You can just have a rule which goes like this.
Function calls may accept types.
It doesn't change much, since just builtin types are rejected by the parser.
Anything else is an unresolved Identifier as far as the parser is concerned.
October 03, 2020
On Saturday, 3 October 2020 at 10:47:47 UTC, Stefan Koch wrote:
> On Saturday, 3 October 2020 at 10:05:23 UTC, Basile B. wrote:
>> On Saturday, 3 October 2020 at 08:44:53 UTC, Stefan Koch wrote:
>>> On Saturday, 3 October 2020 at 07:36:17 UTC, Jacob Carlborg wrote:
>>>> On 2020-10-03 00:24, Stefan Koch wrote:
>>>>
>>>>> // temporarly needed because parser issues ....
>>>>> auto makeAliasArray(alias[] types ...)
>>>>> {
>>>>>      return types;
>>>>> }
>>>>
>>>> Not sure if other cares, but your examples will look more appealing if you fix the parser.
>>>
>>> Yeah ... I know. It's one of these things I keep putting off.
>>>
>>> You could remove all the aliases from my example if I did fix the parser.
>>
>> a DIP for TypeFunction requires the parser change. There are two possibilities
>>
>> 1. a new keyword
>> 2. use a symbol, e.g like template instanciation with a bang
>>
>> The first soltion is absolutly aweful. It leads to deprecate an identifier, which will delay the feature.
>>
>> The second is more likely what should be adopted. At first glance I'd propose a double bang.
>>
>>     string templateStuff = instance!stuff();
>>     string typefuncstuff = callAtCompileTime!!stuff()
>>
>> so after the double bang, the parser can parse a TypeFuntionCallExpr call instead of a CallExpr.
>
> Actually, no.
> You can just have a rule which goes like this.
> Function calls may accept types.
> It doesn't change much, since just builtin types are rejected by the parser.
> Anything else is an unresolved Identifier as far as the parser is concerned.

calls to type functions have to accept basic types, i.e keywords.
Even if you've made the biggest part of semantic, you still need to specify this.
October 03, 2020
On Saturday, 3 October 2020 at 12:28:47 UTC, Basile B. wrote:
> On Saturday, 3 October 2020 at 10:47:47 UTC, Stefan Koch wrote:
>> On Saturday, 3 October 2020 at 10:05:23 UTC, Basile B. wrote:
>>> On Saturday, 3 October 2020 at 08:44:53 UTC, Stefan Koch wrote:
>>>> On Saturday, 3 October 2020 at 07:36:17 UTC, Jacob Carlborg wrote:
>>>>> On 2020-10-03 00:24, Stefan Koch wrote:
>>>>>
>>>>>> // temporarly needed because parser issues ....
>>>>>> auto makeAliasArray(alias[] types ...)
>>>>>> {
>>>>>>      return types;
>>>>>> }
>>>>>
>>>>> Not sure if other cares, but your examples will look more appealing if you fix the parser.
>>>>
>>>> Yeah ... I know. It's one of these things I keep putting off.
>>>>
>>>> You could remove all the aliases from my example if I did fix the parser.
>>>
>>> a DIP for TypeFunction requires the parser change. There are two possibilities
>>>
>>> 1. a new keyword
>>> 2. use a symbol, e.g like template instanciation with a bang
>>>
>>> The first soltion is absolutly aweful. It leads to deprecate an identifier, which will delay the feature.
>>>
>>> The second is more likely what should be adopted. At first glance I'd propose a double bang.
>>>
>>>     string templateStuff = instance!stuff();
>>>     string typefuncstuff = callAtCompileTime!!stuff()
>>>
>>> so after the double bang, the parser can parse a TypeFuntionCallExpr call instead of a CallExpr.
>>
>> Actually, no.
>> You can just have a rule which goes like this.
>> Function calls may accept types.
>> It doesn't change much, since just builtin types are rejected by the parser.
>> Anything else is an unresolved Identifier as far as the parser is concerned.
>
> calls to type functions have to accept basic types, i.e keywords.
> Even if you've made the biggest part of semantic, you still need to specify this.

not to have a special syntax will make the compiler slower. The expression semantic for a call is already complex, it's better to have a dedicated call with a dedicated syntax for type functions.
October 03, 2020
On Saturday, 3 October 2020 at 14:16:09 UTC, Basile B. wrote:
> On Saturday, 3 October 2020 at 12:28:47 UTC, Basile B. wrote:
>>
>> calls to type functions have to accept basic types, i.e keywords.
>> Even if you've made the biggest part of semantic, you still need to specify this.
>
> not to have a special syntax will make the compiler slower. The expression semantic for a call is already complex, it's better to have a dedicated call with a dedicated syntax for type functions.

type functions are supposed to support UFCS.
How would I do that with the calling syntax you propose?
October 04, 2020
On Saturday, 3 October 2020 at 21:36:20 UTC, Stefan Koch wrote:
> On Saturday, 3 October 2020 at 14:16:09 UTC, Basile B. wrote:
>> On Saturday, 3 October 2020 at 12:28:47 UTC, Basile B. wrote:
>>>
>>> calls to type functions have to accept basic types, i.e keywords.
>>> Even if you've made the biggest part of semantic, you still need to specify this.
>>
>> not to have a special syntax will make the compiler slower. The expression semantic for a call is already complex, it's better to have a dedicated call with a dedicated syntax for type functions.
>
> type functions are supposed to support UFCS.
> How would I do that with the calling syntax you propose?

UFCS style still works:

  size_t SizeOf(alias T){ return T.sizeof; }

  static assert (SizeOf!!(ubyte) == 1);
  static assert (ubyte!!SizeOf() == 1);
  static assert (ubyte!!SizeOf == 1);

although you clearly loose the feel that it's like a builtin property.
October 04, 2020
On 04.10.20 07:04, Basile B. wrote:
> On Saturday, 3 October 2020 at 21:36:20 UTC, Stefan Koch wrote:
>> On Saturday, 3 October 2020 at 14:16:09 UTC, Basile B. wrote:
>>> On Saturday, 3 October 2020 at 12:28:47 UTC, Basile B. wrote:
>>>>
>>>> calls to type functions have to accept basic types, i.e keywords.
>>>> Even if you've made the biggest part of semantic, you still need to specify this.
>>>
>>> not to have a special syntax will make the compiler slower. The expression semantic for a call is already complex, it's better to have a dedicated call with a dedicated syntax for type functions.
>>
>> type functions are supposed to support UFCS.
>> How would I do that with the calling syntax you propose?
> 
> UFCS style still works:
> 
>    size_t SizeOf(alias T){ return T.sizeof; }
> 
>    static assert (SizeOf!!(ubyte) == 1);
>    static assert (ubyte!!SizeOf() == 1);
>    static assert (ubyte!!SizeOf == 1);
> 
> although you clearly loose the feel that it's like a builtin property.

IMO this is ugly and unnecessary. The distinction between types and expressions in the parser is pointless anyway.
« First   ‹ Prev
1 2