Constraints

Ibrahim Gokhan YANIKLAR yanikibo at gmail.com
Thu May 10 13:44:14 PDT 2012


On Thursday, 10 May 2012 at 14:44:00 UTC, Chris Cain wrote:
> I do kind of like your way better, as it's more succinct and 
> clear. As of right now I rarely use classes in D because they 
> just aren't necessary in most cases, and using structs with 
> templates is nearly as powerful and (probably) generates faster 
> code (although, probably fatter code as well as it has to make 
> several versions of the same functions depending on the types).
>
> With your idea, it seems like I would have even less need for 
> classes because you can specify "interfaces" to that generic 
> code.
>
> That all said, I think your code is tiny bit unrealistic in 
> terms of usage for these things which make them look far more 
> useful than they really would be. Take, for instance, some 
> actual code:
>
> https://gist.github.com/2d32de50d2e856c00e9d#file_insert_back.d
>
> So, in this case, I see no potential savings at all. I'd still 
> have to have "isImplicitlyConvertible" in there and therefore 
> I'd still need the current constraint on the method. My 
> insertFront method is more complicated:
>
> https://gist.github.com/2d32de50d2e856c00e9d#file_insert_front.d

isImplicitlyConvertible have to be there because it belongs to a 
template parameter out of the member function template parameters.

> But even though it's more complicated, I'd also like to see how 
> your method would simplify this as well.


void insertFront(U : T)(U item) { ... }

void insertFront(Range : CBidirectionalRange)(Range r)
	if(isImplicitlyConvertible!(ElementType!Range, T)) { ... }

void insertFront(Range : CInputRange)(Range r)
	if(isImplicitlyConvertible!(ElementType!Range, T)) { ... }



> Overall, I think it sounds nice in theory, but I'm just not 
> sure how effective it will be in practice.
>
> I hope I'm not asking too much of you... I'm not trying to 
> discourage you, I'm asking genuine questions about how this 
> will work on more realistic code.
>
> On Thursday, 10 May 2012 at 09:43:00 UTC, İbrahim Gökhan 
> YANIKLAR wrote:
>> concept CInputRange(R)
>> {
>> 	static assert (isDefinable!R);
>> 	static assert (isRange!R);
>> 	bool empty();
>> 	void popFront();
>> 	ElementType!R front();
>> }
>
> Also, something that would _have_ to be solved is ElementType!R 
> ... as of right now, ElementType!R figures out what a range 
> holds by what its front() property returns. So, I think this 
> definition would be invalid.
>

It can be fixed like that:

concept CInputRange(R, E)
{
	static assert (isDefinable!R);
	static assert (isRange!R);
	bool empty();
	void popFront();
	E front();
}

concept CForwardRange(R, E) : CInputRange!(R, E)
{
	R save();
}

concept CBidirectionalRange(R, E) : CForwardRange!(R, E)
{
	void popBack();
	E back();
}

concept CRandomAccessRange(R, E) : CBidirectionalRange!(R, E)
	if (!isInfinite!R)
{
	static assert (is(typeof(R.init[1])));
	static assert(hasLength!R);
	static assert(!isNarrowString!R);
}

concept CRandomAccessRange(R, E) : CForwardRange!(R, E)
	if (isInfinite!R)
{
	static assert (is(typeof(R.init[1])));
}


The first template parameter is reserved for "typeof(this)",
the others are deduced automatically.

> However, once we can show that this will improve things on real 
> code and these things are sorted out, I wouldn't mind seeing 
> this in the language.

When we prefer generic programming rather than oop (where oop is 
applicable), we will absolutely need an interface to make things 
as simple and practical as oop.
Interfaces are not used always for polymorphism, sometimes we 
need only an interface to satisfy common needs. Sometimes the 
current status of D canalizes us to use classes and interfaces 
although it is not effective.
The concept concept may meet these needs. :)


More information about the Digitalmars-d mailing list