Jump to page: 1 212  
Page
Thread overview
TypeFunction example: ImplictConvTargets
Oct 05
jmh530
Oct 06
foobar
Oct 06
foobar
Oct 06
foobar
Oct 07
foobar
Oct 06
claptrap
Oct 06
Meta
Oct 07
foobar
Oct 06
claptrap
Oct 07
claptrap
Oct 07
claptrap
Oct 07
claptrap
Oct 06
claptrap
Oct 06
jmh530
Oct 06
foobar
Oct 06
jmh530
Oct 05
claptrap
Oct 05
claptrap
Oct 05
Meta
Oct 06
jmh530
Oct 06
Daniel K
Oct 06
Daniel K
Oct 06
claptrap
Oct 07
claptrap
Oct 07
Daniel K
Oct 07
claptrap
Oct 07
claptrap
Oct 07
claptrap
Oct 07
claptrap
Oct 07
claptrap
Oct 07
Daniel K
Oct 07
claptrap
Oct 07
Daniel K
Oct 07
claptrap
Oct 07
foobar
October 05
Hi,

I've posted an incomplete version of a semantic translation of ImplictConvTargets from a template into a type function.

After a few rather trivial fixes let me show you what the code looks like now.

---
alias type = alias;

// needed to avoid deeper changes ... in the future it may be unnecessary.
auto makeAliasArray(type[] types ...)
{
    return types;
}

enum basic_types = makeAliasArray(bool, ubyte, char, byte, ushort, wchar, short, uint, dchar, int, ulong, long);

type[] convTargets(type T)
{
    if (isBasicType(T))
        return basicTypeConvTargets(T);
    return null;
}

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

type[] basicTypeConvTargets(type T)
{
    type[] 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 targets[0 .. n];
}
// 42 lines including whitespace and comments

pragma(msg, convTargets(long)); // outputs [(ulong), (long)]
---

And again here is the part of the template that we just re-implemented:
---
    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);
    // part omitted because we don't have ucent and cent in our list
    else static if (is(T == char))
        alias ImplicitConversionTargets =
            AliasSeq!(wchar, dchar, byte, ubyte, short, ushort,
                       int, uint, long, ulong, CentTypeList, float, double, real);
    else static if (is(T == wchar))
        alias ImplicitConversionTargets =
            AliasSeq!(dchar, short, ushort, int, uint, long, ulong, CentTypeList,
                       float, double, real);
    else static if (is(T == dchar))
        alias ImplicitConversionTargets =
            AliasSeq!(int, uint, long, ulong, CentTypeList, float, double, real);
    // 41 lines including white-space and comments (only that there is no white-space or comments)
---

I leave it up to you to decide which version is more understandable and extendable (should we ever get another basic type :))

As noted previously please do discuss!
Maybe you like the template version more?
Let me know.
October 06
On 06/10/2020 12:44 AM, Stefan Koch wrote:
> I leave it up to you to decide which version is more understandable and extendable (should we ever get another basic type :))

You forgot ucent and cent ;)
October 05
On Monday, 5 October 2020 at 11:52:06 UTC, rikki cattermole wrote:
> On 06/10/2020 12:44 AM, Stefan Koch wrote:
>> I leave it up to you to decide which version is more understandable and extendable (should we ever get another basic type :))
>
> You forgot ucent and cent ;)

You can't write those without making dmd error out.
And complain about ucent and cent not being implemented.
At least that used to be the case.

I also didn't write the floating types since, there's still a bug in the type function implementation that prevents those being turned into type expressions.
October 05
On Monday, 5 October 2020 at 11:58:55 UTC, Stefan Koch wrote:
> On Monday, 5 October 2020 at 11:52:06 UTC, rikki cattermole wrote:
>> On 06/10/2020 12:44 AM, Stefan Koch wrote:
>>> I leave it up to you to decide which version is more understandable and extendable (should we ever get another basic type :))
>>
>> You forgot ucent and cent ;)
>
> You can't write those without making dmd error out.
> And complain about ucent and cent not being implemented.
> At least that used to be the case.
>
> I also didn't write the floating types since, there's still a bug in the type function implementation that prevents those being turned into type expressions.

Yep ... it's still a problem.

test_alias_implconv.d(9): Error: cent and ucent types not implemented
test_alias_implconv.d(13):        called from here: isBasicType(T)
test_alias_implconv.d(47):        called from here: convTargets(cast(alias)(long))
test_alias_implconv.d(47):        called from here: isEqual(convTargets(cast(alias)(long)), makeAliasArray([cast(alias)(ulong), cast(alias)(long)][]))
test_alias_implconv.d(47):        while evaluating: static assert(isEqual(convTargets(cast(alias)(long)), makeAliasArray([cast(alias)(ulong), cast(alias)(long)][])))


This shows another advantage of type functions.
You get a call stack ;)
October 05
On Monday, 5 October 2020 at 11:44:34 UTC, Stefan Koch wrote:
> Hi,
>
> [snip]
>
> I leave it up to you to decide which version is more understandable and extendable (should we ever get another basic type :))
>
> As noted previously please do discuss!
> Maybe you like the template version more?
> Let me know.


It would be useful if these examples also include some kind of performance information as well.

Further, as far as I could tell from the previous thread, there were three potential approaches: type functions, templates, and reification.

October 05
On 10/5/20 7:44 AM, Stefan Koch wrote:
> Hi,
> 
> I've posted an incomplete version of a semantic translation of ImplictConvTargets from a template into a type function.
> 
> After a few rather trivial fixes let me show you what the code looks like now.
[snip]

The existing implementation is ancient (e.g. predates std.meta) and certainly deserves a redoing with Filter, which turns it into a 3-liner (untested):

alias Integrals = AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong, CentTypeList, float, double, real, char, wchar, dchar);
alias convertsTo(U) = is(T : U);
alias ImplicitConversionTargets(T) = Filter!(convertsTo, Integrals);

This would make for a nice refactoring PR and would provide a better baseline for comparison.

Things could be further simplified - I haven't looked in detail but it seems to me each integral converts to all integrals that are as large or larger. So if we keep a list of integrals sorted by size we could simply return slices from it instead of doing filtering.

Anyway, implementation size or difficulty is not the problem with ImplicitConversionTargets - it's completeness and correctness. Also the appropriate definition in the language, which now is scattered all over and probably less precise than it should. ImplicitConversionTargets currently doesn't handle alias this, functions and delegates wich co/contravariance, probably a few array conversions (I recall Per recently added or is about to add one), and some qualified structs.
October 05
On Monday, 5 October 2020 at 11:44:34 UTC, Stefan Koch wrote:
> Hi,
>
>
> I leave it up to you to decide which version is more understandable and extendable (should we ever get another basic type :))
>
> As noted previously please do discuss!
> Maybe you like the template version more?
> Let me know.

100% the type functions.

It's also worth nothing that the way the TF version is implemented you have a bunch of stuff that is reusable, you could argue that...

makeAliasArray
isBasicType

shouldn't be in the line count as they would be general library functions anyway.

And at the very least the decomposition into smaller more understandable and separately useful parts is as a big win as the "easy to explain to a newbie" syntax is.

October 05
On Monday, 5 October 2020 at 12:46:29 UTC, jmh530 wrote:
> On Monday, 5 October 2020 at 11:44:34 UTC, Stefan Koch wrote:
>> Hi,
>>
>> [snip]
>>
>> I leave it up to you to decide which version is more understandable and extendable (should we ever get another basic type :))
>>
>> As noted previously please do discuss!
>> Maybe you like the template version more?
>> Let me know.
>
>
> It would be useful if these examples also include some kind of performance information as well.
>
> Further, as far as I could tell from the previous thread, there were three potential approaches: type functions, templates, and reification.

Well type function _are_ transparent type reification. With nice syntax, that mirrors the one that's used in the rest of the language to query types.

As for the approach of explicitly reifying types using templates perhaps Andrei could present the example.
(A complete example please, that compiles standalone without importing a library.)


October 05
On Monday, 5 October 2020 at 12:50:39 UTC, Andrei Alexandrescu wrote:
> On 10/5/20 7:44 AM, Stefan Koch wrote:
>> Hi,
>> 
>> I've posted an incomplete version of a semantic translation of ImplictConvTargets from a template into a type function.
>> 
>> After a few rather trivial fixes let me show you what the code looks like now.
> [snip]
>
> The existing implementation is ancient (e.g. predates std.meta) and certainly deserves a redoing with Filter, which turns it into a 3-liner (untested):
>
> alias Integrals = AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong, CentTypeList, float, double, real, char, wchar, dchar);
> alias convertsTo(U) = is(T : U);
> alias ImplicitConversionTargets(T) = Filter!(convertsTo, Integrals);
>


Please post the complete version.
Which does not import the stdlib.
Thanks.
October 05
On Monday, 5 October 2020 at 12:50:39 UTC, Andrei Alexandrescu wrote:
>
> Anyway, implementation size or difficulty is not the problem with ImplicitConversionTargets

In the context of this example it is.
If you want to discuss it an another context please start a new thread.

« First   ‹ Prev
1 2 3 4 5 6 7 8 9 10 11