I've just fixed UFCS for the experimental type function branch

Bruce Carneal bcarneal at gmail.com
Fri Sep 11 13:46:14 UTC 2020


On Friday, 11 September 2020 at 11:54:20 UTC, Paul Backus wrote:
> On Friday, 11 September 2020 at 02:24:07 UTC, H. S. Teoh wrote:
>> On Fri, Sep 11, 2020 at 01:07:55AM +0000, Paul Backus via 
>> Digitalmars-d wrote: [...]
>>> I think the main difficulty of scaling code bases the rely 
>>> heavily on templates (either D or C++), [...], is that 
>>> templates themselves--not the code they generate when you 
>>> instantiate them, but the actual *templates*--are essentially 
>>> dynamically typed. In general, there's no way to catch errors 
>>> in a template until you "run" it (that is, instantiate it) 
>>> and see what it does.
>> [...]
>>
>> This is why when I write template code, I try to write 
>> defensively in a way that makes as few assumptions as possible 
>> about the template arguments.  Ideally, every operation you'd 
>> do with that type should be tested in the sig constraints.
>>
>> Even better would be if the compiler enforced this: unless you 
>> tested for some operation in the sig constraints, that 
>> operation would be deemed illegal.  But in the past Walter & 
>> Andrei have shot down Concepts, which is very similar to this 
>> idea, so I don't know how likely this will ever make it into D.
>
> Yeah, that's basically the traits/typeclasses approach: you 
> commit to a particular set of constraints, and the compiler 
> checks your generic code against them *prior* to instantiation 
> with any particular type (or "monomorphization," as the 
> Rustaceans call it).
>
> The main downside is that you can't do design-by-introspection. 
> Once you commit to a typeclass, its interface is all you get. 
> If you want your algorithm to work differently for InputRange 
> and RandomAccessRange, you have to write two implementations. 
> And if you don't want to deal with the combinatorial blow-up, 
> you just use the least-restrictive typeclass possible, and miss 
> out on any opportunities for progressive enhancement.
>
> (Hypothesis: one consequence of this is that an optimizing 
> compiler backend has to work harder, on average, to get 
> efficient code out of a Rust iterator than it does for the 
> analogous range in D.)
>
> Theoretically, if you had something like a type-level version 
> of TypeScript's flow-based type analysis, you could combine the 
> two approaches. But I don't know of any language that's 
> actually implemented such a feature.

There is a lot of static type language design terrain to be 
explored on the way to the fully dynamic type border.  Scouting 
ahead, as Paul and H.S. are doing, informs our near term decision 
regarding type functions.

These are my summary questions regarding type functions:
1) Are they worth another 1000 LoC in the compiler? and
2) Do they preclude envisionable advances in the future?

My answer to 1) is : Yes, the compounding benefits over time of 
simpler user meta code outweighs the, reportedly, small increase 
in compiler code today.

My answer to 2) is : No, type functions do not preclude future 
advances on the type front.  They are self contained.






More information about the Digitalmars-d mailing list