October 06, 2020
On Tuesday, 6 October 2020 at 10:22:44 UTC, Stefan Koch wrote:
> On Tuesday, 6 October 2020 at 01:12:01 UTC, Walter Bright wrote:
>> [...]
>
> Okay let me show you the transitive dependencies of the "3 liner" suggested by Andrei and executed by Paul Backus.
>
> [...]

That implementation was *definitely* (and very obviously) not created for simplicity. It can be done in way fewer lines than that (and you know that, obviously).

The argument to be made is "look how ridiculous this code has to be to avoid some of the worst performance problems, look how simple the type functions approach is and how much faster it is", yes?
October 06, 2020
On Tuesday, 6 October 2020 at 12:07:40 UTC, John Colvin wrote:
> On Tuesday, 6 October 2020 at 10:22:44 UTC, Stefan Koch wrote:
>> On Tuesday, 6 October 2020 at 01:12:01 UTC, Walter Bright wrote:
>>> [...]
>>
>> Okay let me show you the transitive dependencies of the "3 liner" suggested by Andrei and executed by Paul Backus.
>>
>> [...]
>
> That implementation was *definitely* (and very obviously) not created for simplicity. It can be done in way fewer lines than that (and you know that, obviously).
>
> The argument to be made is "look how ridiculous this code has to be to avoid some of the worst performance problems, look how simple the type functions approach is and how much faster it is", yes?

Yes that sums it up very well actually.
I am not good enough with recursive templates to simplify the implementation  without the risk of introducing bugs unfortunately.
Which is why I asked for others to provide code to compare this to.
October 06, 2020
On Tuesday, 6 October 2020 at 08:35:20 UTC, claptrap wrote:
> Because Stefan didnt rely on external code, he showed *all* the code needed, so a counter example should have been the same. Since the point is to compare the two *language* features, not compare library calls.

Language features are a means to an end.

If the Phobos version compiles faster, uses less memory, and has the same result in the binary, it is a victory, even if it as significantly more code.

I'm skeptical of the type functions, but interested. They might help with a real problem. But they need to actually win on the end results, not against artificial strawmen.
October 06, 2020
On Tuesday, 6 October 2020 at 12:07:40 UTC, John Colvin wrote:
> On Tuesday, 6 October 2020 at 10:22:44 UTC, Stefan Koch wrote:
>> On Tuesday, 6 October 2020 at 01:12:01 UTC, Walter Bright wrote:
>>> [...]
>>
>> Okay let me show you the transitive dependencies of the "3 liner" suggested by Andrei and executed by Paul Backus.
>>
>> [...]
>
> That implementation was *definitely* (and very obviously) not created for simplicity. It can be done in way fewer lines than that (and you know that, obviously).

Maybe "simple and concise" takes a lot more work to extract from templates. I mean the type function version is so obvious it's probably what a newbie would write, the simple concise solution is the obvious one. Is the same true of the template / mixin versions?  Or do you have to be a D sage to make it palatable?




October 06, 2020
On Tuesday, 6 October 2020 at 11:34:10 UTC, foobar wrote:
> On Tuesday, 6 October 2020 at 03:50:11 UTC, Stefan Koch wrote:
>> On Tuesday, 6 October 2020 at 00:25:40 UTC, foobar wrote:
>>> On Monday, 5 October 2020 at 21:20:36 UTC, Stefan Koch wrote:
>>>> On Monday, 5 October 2020 at 21:13:09 UTC, Paul Backus wrote:
>>>>> On Monday, 5 October 2020 at 20:57:04 UTC, Stefan Koch wrote:
>>>>>> On Monday, 5 October 2020 at 12:50:39 UTC, Andrei Alexandrescu wrote:
>>>>>>
>>>>>>> [...]
>>>>>>
>>>>>> This code does not work.
>>>>>> I don't even need to compile it to see that.
>>>>>
>>>>> It has some simple mistakes, but the fundamental idea is sound. Here's a version that actually compiles:
>>>>>
>>>>> import std.meta;
>>>>>
>>>>> alias Numerics = AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong, float, double, real, char, wchar, dchar);
>>>>> enum convertsTo(T, U) = is(T : U);
>>>>> alias ImplicitConversionTargets(T) = Filter!(ApplyLeft!(convertsTo, T), Numerics);
>>>>>
>>>>> // prints: (int, uint, long, ulong, float, double, real, dchar)
>>>>> pragma(msg, ImplicitConversionTargets!int);
>>>>> // prints: (float, double, real)
>>>>> pragma(msg, ImplicitConversionTargets!double);
>>>>
>>>> Now post it with all transitive dependencies.
>>>> And we have a fair comparison.
>>>
>>> Post your code with all changes to the language and compiler. Then we have a fair comparison.
>>
>> Actually no.
>> The compiler changes don't affect the user.
>> They're for a small number of people to know about and support.
>> Typefunctions and CTFE are together still much less complicated than the template system is.
>>
>> I have nothing to hide though here it is
>> https://github.com/dlang/dmd/compare/master...UplinkCoder:talias_master
>>
>> 650 lines of rather clean code which can in the future be factored with the respective semantic routines.
>
> Actuallly yes.
> The language changes affect the user. This is a large change to the language which puts back in the compiler what we do in libraries. Whoop-de-do.
> Do type functions do anything new?

It only gives access to what the compiler has to do anyway.
It gives you an interface to what must exist within.
You could even say this makes it easier to provide a library implementation by using the compiler as a built-in library.
No, type functions don't do anything original they mirror how type manipulation works within templates providing a familiar and usable interface.
It is an explicit goal of mine to have type functions look just like any other D code.


October 06, 2020
On Tuesday, 6 October 2020 at 12:32:17 UTC, claptrap wrote:
> On Tuesday, 6 October 2020 at 12:07:40 UTC, John Colvin wrote:
>> On Tuesday, 6 October 2020 at 10:22:44 UTC, Stefan Koch wrote:
>>> On Tuesday, 6 October 2020 at 01:12:01 UTC, Walter Bright wrote:
>>>> [...]
>>>
>>> Okay let me show you the transitive dependencies of the "3 liner" suggested by Andrei and executed by Paul Backus.
>>>
>>> [...]
>>
>> That implementation was *definitely* (and very obviously) not created for simplicity. It can be done in way fewer lines than that (and you know that, obviously).
>
> Maybe "simple and concise" takes a lot more work to extract from templates. I mean the type function version is so obvious it's probably what a newbie would write, the simple concise solution is the obvious one. Is the same true of the template / mixin versions?  Or do you have to be a D sage to make it palatable?

If you look at the history of std.meta you'll see it was me who recently made Filter so ugly, the previous version was simple but too slow.
October 06, 2020
On Tuesday, 6 October 2020 at 13:20:43 UTC, John Colvin wrote:
> [snip]
>
> If you look at the history of std.meta you'll see it was me who recently made Filter so ugly, the previous version was simple but too slow.

To get Filter/staticMap to have improved performance (and it looks to me like Stefan copied the phobos version in his example), you were forced to make them uglier. But, isn't Stefan's point that his version has even better performance than your ugly version? Is your argument that the simple version would have better performance in this case?
October 06, 2020
On Tuesday, 6 October 2020 at 13:35:25 UTC, jmh530 wrote:
> On Tuesday, 6 October 2020 at 13:20:43 UTC, John Colvin wrote:
>> [snip]
>>
>> If you look at the history of std.meta you'll see it was me who recently made Filter so ugly, the previous version was simple but too slow.
>
> To get Filter/staticMap to have improved performance (and it looks to me like Stefan copied the phobos version in his example), you were forced to make them uglier. But, isn't Stefan's point that his version has even better performance than your ugly version? Is your argument that the simple version would have better performance in this case?

I'm not really trying to argue anything, just trying to inform/clarify a little
October 06, 2020
On Tuesday, 6 October 2020 at 12:28:55 UTC, Adam D. Ruppe wrote:
> On Tuesday, 6 October 2020 at 08:35:20 UTC, claptrap wrote:
>> Because Stefan didnt rely on external code, he showed *all* the code needed, so a counter example should have been the same. Since the point is to compare the two *language* features, not compare library calls.
>
> Language features are a means to an end.
>
> If the Phobos version compiles faster, uses less memory, and has the same result in the binary, it is a victory, even if it as significantly more code.

I disagree.  I believe we should aim for the simplest code that admits the desired performance.  Simplicity is especially important at lower levels where the benefits compound.  We're working to factor out complexity for today's programmers and tomorrows.

>
> I'm skeptical of the type functions, but interested. They might help with a real problem.

Well, what is a "real problem"?  If you mean "something that can not be done outside the compiler" then nothing is a real problem (note CTFE and mixins).  If you mean "something that can not be done near optimally outside the compiler" then we're in violent agreement.

> But they need to actually win on the end results, not against artificial strawmen.

Agree.

Note that performance is relatively easy to test whereas it's harder to compare aggregate debugability over time.  My proxies include readability, teachability, independence (fewer layers, fewer dependencies), and the amount of the correctness "proof" (debugging) handled automatically.

If performance is similar we should opt for better aggregate debugability as we, the community, understand it.  My current understanding is that type functions are significantly better in this regard.

Finally, please note that while I disagree with you on some particulars here I am a big fan.  I enjoyed your book, and admire the tremendous amount of cheerful quality help that you offer in the forums and discord.











October 06, 2020
On Tuesday, 6 October 2020 at 11:25:41 UTC, jmh530 wrote:
> On Tuesday, 6 October 2020 at 11:14:05 UTC, Stefan Koch wrote:
>> [snip]
>> The source code can be found here:
>>
>> https://gist.github.com/UplinkCoder/d29dd143b352d28390426a3ffedf9521
>>
>> So can the benchmark results.
>> Note: not importing std.meta gives the template version (xx.d) a speed boost of 3 milliseconds.
>
> Thanks for providing these results.
>
> You had previously provided some evidence of a significant reduction in memory consumption. You might consider adding that information (using these examples) to this gist to bolster your argument.

I've just added the gist: https://gist.github.com/UplinkCoder/d29dd143b352d28390426a3ffedf9521#file-benchmark-results-txt

Perhaps there is a better way than /usr/bin/time ?