higher-order funcs for ranges (with usual interface)
spir
denis.spir at gmail.com
Thu Feb 3 10:11:04 PST 2011
On 02/03/2011 02:25 PM, Lars T. Kyllingstad wrote:
> On Thu, 03 Feb 2011 13:53:44 +0100, spir wrote:
>
>> On 02/03/2011 01:17 PM, Lars T. Kyllingstad wrote:
>>> Why the reluctance to use template constraints? They're so flexible!
>>> :)
>>
>> I cannot stand the "is()" idiom/syntax ;-) Dunno why. Would happily get
>> rid of it in favor of type-classes (built eg as an extension to current
>> interfaces). For instance, instead of:
>>
>> void func (T) (T t)
>> if (is(someConstraint1)&& is(someConstraint2))
>> {
>> ...
>> }
>>
>> use:
>>
>> void func (SomeTypeClass T) (T t)
>> {
>> ...
>> }
>>
>> For instance (untested):
>>
>> void func (T) (T t)
>> if (isInputRange(T)&& is(ElementType!T == E))
>> -->
>> void func (InputRange!E T) (T t)
>>
>> where InputRange is a (templated) interface / type-class.
>>
>> Type-class checks on /type/ /template/ parameters (as opposed to type
>> checks on regular value parameters) would be performed structurally (as
>> opposed to nominally). D knows how to do this, since that's what it
>> needs to perform when checking is() constraints.
>
> I agree that is() is rather ugly. Same with __traits. If you haven't
> already done so, I suggest you vote up this issue:
>
> http://d.puremagic.com/issues/show_bug.cgi?id=3702
Done!
(I did not get all the details 'cause no time for a deep look, but anything
impulsed by the motivation of getting rid of is() and __traits can hardly be a
Bad Thing ;-)
What do you think of type classes, as an alternative to Don's proposal in issue
#3702.
See also "Type Classes as Objects and Implicits":
http://ropas.snu.ac.kr/~bruno/papers/TypeClasses.pdf
> Anyway, you can hide is()'s ugliness in the most common cases, though, by
> defining new templates. For instance, I wouldn't mind having the
> following in std.range as an overload of isInputRange:
>
> template isInputRange(R, T)
> {
> enum isInputRange = isInputRange!R&& is(ElementType!R == T);
> }
>
> Then, you'd simply write
>
> void func(R)(R range) if (isInputRange!(R, E)) { ... }
>
> -Lars
A great improvement, indeed.
While we're at defining a set of constraints in a template, let us make it an
interface / type-class that the E must (structurally) satisfy, and just write:
void func(InputRange!E R)(R range) { ... }
What do you think?
Note: a template is not always required, I guess:
void writeElements (Iterable Elements) (Elements elements) {
foreach (element, elements) {
write(element,' ');
}
}
(In this case, because write is itself generic.)
Denis
--
_________________
vita es estrany
spir.wikidot.com
More information about the Digitalmars-d-learn
mailing list