rikki cattermole rikki at cattermole.co.nz
Sat Oct 19 02:57:33 UTC 2019

On 19/10/2019 7:35 AM, Meta wrote:
> On Friday, 18 October 2019 at 17:09:55 UTC, jmh530 wrote:
>> On Friday, 18 October 2019 at 16:14:26 UTC, Meta wrote:
>>> [snip]
>>> I wrote that in response to Rikki's assertion:
>>> "This unfortunately still ties the implementation itself to the 
>>> interface. Which goes against DbI."
>>> Just some spitballing on how DbI could harmoniously co-exist with 
>>> Atila's concepts library.
>> I'm never quite sure whether I grok DbI or not...but all those static 
>> if's in phobos's MapResult are introspection to make sure that the 
>> range type has the appropriate functions and include the relevant text 
>> in MapResult.
> Exactly, making it very hard to use @implements from Atila's library, 
> because MapResult may or may not implement the necessary primitives to 
> be, say, a forward range, depending on whether the source range 
> implements them. Yes, of course you can just use `isInputRange` instead, 
> but we should aim to provide options, and I prefer the cleanliness of 
> the former.
>> So it seems to me that isInputRange in phobos is DbI-compatible, 
>> particularly when re-reading what Rikki wrote. He seems to be arguing 
>> that what you are doing is not DbI because you are using interfaces 
>> instead.
> I may be misunderstanding him, but I believe his main problem with using 
> interfaces is that the struct conforms to the interface, but does not 
> inherit its the behaviour (e.g., MapResult implements .save only if the 
> underlying range does, and forwards to its implementation, which is not 
> possible without extra boilerplate, were we to just allow structs to 
> implement interfaces as a solution).

So my problem is with the struct itself knowing about the "interface" 
(whatever definition you use doesn't matter).

Currently we are good with isInputRange. Because the implementation of 
an input range does not need to know about that "function" in any form 
including the InputRange class interface.

DbI works at the usage site, not at the declaration site of whatever is 
getting passed in. Its about limiting and adapting the user code to fit 
the types being passed in.

So it doesn't matter if you inherit a class interface from a struct, or 
use a UDA, you are telling the type about the interface.


auto map(Args)(Args arg) {
	static struct Map {
		@property {
			Something front() @nogc { ... }
			bool empty() @nogc { ... }

		void popFront() @nogc { ... }

	return Map(arg);

void myFunc(IR)(IR input) { ... }

What we want to do, is restrict the template parameter (IR) to an input 
range. But the input range interface that is being used (e.g. a variant 
like @nogc) may not have been known to the map function (doesn't matter 
why) and there is no reason for it to have known about it at all.

There may also be other restricting factors like the ElementType. Now 
for very simple cases this can be done as part of a template parameter, 
and more complex ones can go into template constraints like we do now 
(since its a more advanced use case).

Thing is, if all we want to do is to check if its an input range, we 
shouldn't need to use template constraints. They are a very advanced 
language feature involving CTFE and language based traits.

So if we were to look into rewriting Phobos, shouldn't we make something 
that is common and fairly advanced, into something that is simple to 
understand? Because that is what I'm arguing for.


auto:InputRange map(Args)(Args arg) { .. }

A function that returns a value whose type conforms to the InputRange 
specification. This would significantly improve the documentation (as it 
cannot be done right now and people have tried to find a solution).

More information about the Digitalmars-d mailing list