Ranges

Yigal Chripun yigal100 at gmail.com
Sat Jun 20 04:42:30 PDT 2009


Lutger wrote:
> Not sure what that would do, but C++ concepts are not exactly compile time 
> interfaces. This is very important: in C++0X, a type T which satisfies the 
> concept Comparable<T> does not implement the concept explicitly, whereas 
> languages with explicit constraints on generics do require T to be inherited 
> from IComparable. The consequence is a bit of bloat and more rigid demands 
> on what is supposed to relax the inflexible regime of the static type 
> system. This bloat and rigidity is also a cognitive burden in it's own 
> right, for example when it requires workarounds when the system is not 
> expressive enough. 

regarding the consequences - i agree that this is a bit more rigid. I 
don't see the bloat though. can you provide an example? can you also 
explain what kinds of workarounds are you talking about that would be 
required?

> 
> Concepts provide two benefits in this context: documentation and extra type 
> checking for templates. But they do retain structural typing. In D, we 
> already have this covered with template constraints.* If you look at 
> std.range, this is exactly what you see: all the interfaces (and even 
> semantics) are nicely named and documented explicitly. So would we have had 
> compile time interfaces, they would add next to nothing about the 
> documentation or understanding of ranges.
>  

there are several problems with the template constraints currently used.
1. the constraints are specified on the client code which means you need 
to either duplicate those constraints everywhere or call some template 
like isForwardRange manually to check that you got the correct type.
2. The syntax for this is completely alien and unreadable, at least for me.

documentations and type-checking are indeed the two main benefits I'd 
like to get.
the current way it is done with is() expression is unreadable. this 
needs to be specified IMO with the same (or almost the same) syntax as 
interfaces. I don't get why D needs two completely different syntaxes 
for the same thing (specifying an interface). this will give us a more 
readable documentation aspect.
the type-checking aspect of this is that the checks will be done on the 
template definition instead of the instantiation in the client code 
which will also prevent cases when bugs in a library template only 
manifest when the client programmer compiles *his* code. this happened 
to tango in the past.

>> templates are hard for users to understand and one of the main reasons
>> for this is that templates are essentially a completely different
>> language with different syntax and semantics which to me looks like
>> mis-design.
> 
> I don't think it is hard to understand because of structural typing.  
> Generics are inherently somewhat difficult in a static typing language, 
> because of it's abstract nature. You don't have this problem in dynamic 
> languages. (or you can't escape it, depending on your POV)
> 
> I don't agree that templates are a completely different language though. 
> When used purely for parametric polymorphism, it does integrate nicely in 
> the normal type system. When you do use it for meta-programming, which is 
> relatively rare, then the above also applies: this is an inherently 
> difficult way of programming. Just look at something like lisp where you can 
> metaprogram in the same language. Does that make it easy to understand? Or 
> CTFE and string mixins in D, same language, but it's also difficult. Adding 
> more constraints can never solve the fact that humans don't easily grok 
> programs which generate programs. 
> 
I was talking mostly about meta-programming and not parametric 
polymorphism.
I agree that it is harder to grok programs that generate programs. this 
is why it is so important IMO to make this as readable as possible.
to answer your question, lisp does make this _easier_ to understand 
compared to templates. D CTFE functions are much more readable than D 
templates.
while I agree that this is never trivial, it should not be made near 
impossible like it is in C++. an experienced user should be able to read 
the source of libs like Boost and STL and understand without much 
trouble what it does without being a C++ guru.

> * I don't think the extra type checking is done, but perhaps it could be.
> 

the distinction you make between generics with explicit constraints that 
require explicit inheritance and concepts is more of an implementation 
detail IMO.
the first uses run-time inheritance for this type checking.
what I'd prefer is the second implementation where the type-check is 
done at compile-time by means of structural typing but unlike C++ where 
it's optional I want it to be required so that the type-checking is 
performed on the definition and not on the instantiations.
does that make sense?



More information about the Digitalmars-d mailing list