Re: D's type classes pattern ?

2015-03-25 Thread matovitch via Digitalmars-d-learn

Thanks for the precisions on template constraint and template
specialization...Indeed wath I want to do look like isInputRange
constraint. Haskell have something like :

//(Pseudo D-Haskell)

void foo(InputRange R)(R r);

//D equivalent

void foo(R)(R r) if (isInputRange(R));

Except they call them type classes instead of template constraint
and it is check at runtime instead of compile time for D.

I am curious to know how isInputRange is implemented since I
wanted to do kind of the same but I am afraid it's full of (ugly)
traits and template trickeries where haskell type classes are
quite neat and essentially a declaration of an interface.

Let say I want to be able to add the type my algo deal with...I
could do an isAddable wich looks if a+b compiles with traits...I
wondered if you could check statically that the type could
implement an interface *if it wanted to* that is, without
inheriting it...





Re: D's type classes pattern ?

2015-03-25 Thread bearophile via Digitalmars-d-learn

matovitch:


I am curious to know how isInputRange is implemented since I
wanted to do kind of the same but I am afraid it's full of 
(ugly)

traits and template trickeries where haskell type classes are
quite neat and essentially a declaration of an interface.


Take a look at the sources and learn. They are sometimes tricky 
to get right, but it's not a problem of ugly syntax.




I wondered if you could check statically that the type could
implement an interface *if it wanted to* that is, without
inheriting it...


Template constraints don't require inheritance.

Bye,
bearophile


Re: D's type classes pattern ?

2015-03-25 Thread matovitch via Digitalmars-d-learn

On Wednesday, 25 March 2015 at 08:55:14 UTC, bearophile wrote:

matovitch:


I am curious to know how isInputRange is implemented since I
wanted to do kind of the same but I am afraid it's full of 
(ugly)

traits and template trickeries where haskell type classes are
quite neat and essentially a declaration of an interface.


Take a look at the sources and learn. They are sometimes tricky 
to get right, but it's not a problem of ugly syntax.




I wondered if you could check statically that the type could
implement an interface *if it wanted to* that is, without
inheriting it...


Template constraints don't require inheritance.

Bye,
bearophile


Yes I know that you don't need to inherit some InputRange 
interface to be able to check a user defined type is an input 
range. And template constraints are more powerful/general than 
type classes but it's harder to get right for the beginner. I 
will definetly look at the code anyway.


I was looking at :

interface IInputRange(InputRange) {...}

class TypeClass(T,I) : I!T
{
alias t this;
T t;
}

void foo(InputRange) (InputRange inputRange) if 
(isInstanciable(TypeClass!(InputRange, IInputRange)));


Re: D's type classes pattern ?

2015-03-24 Thread anonymous via Digitalmars-d-learn

On Tuesday, 24 March 2015 at 16:56:13 UTC, matovitch wrote:

Thanks, just to be clear :

void Bar(T : Foo)(T t){
}

is the same as

void Bar(T)(T t) if (is(T == Foo)){
}

and it is checked only at compile time ? (for the runtime I 
know that what interface were meant for ;)).


Ali already mentioned the difference between == and :.

In addition to that, template specializations (like `Bar(T : 
Foo)(T t)`) and template constraints (like `Bar(T)(T t) if(is(T : 
Foo))`) are similar but generally not interchangeable.


A template with a specialization is considered a better match 
than one without. Whereas a template constraint doesn't add to 
the quality of the match.


An example:

module test;
import std.stdio;

void f(T)(T t) {writeln(generic);}
void f(T : int)(T t) {writeln(with specialization);}
void f(T)(T t) if(is(T : Object)) {writeln(with constraint);}

void main()
{
f(some string); /* - generic */
f(42); /* - with specialization */
version(none) f(new Object); /* Doesn't compile, because it 
matches both the generic version and the one with the constraint. 
*/

}


Re: D's type classes pattern ?

2015-03-24 Thread Ali Çehreli via Digitalmars-d-learn

On 03/24/2015 08:50 AM, matovitch wrote:

 Lets say I want to implement some generic algorithm. I would like
 to checks the types passed to my algorithm implements a specific
 interface.

I think you are looking for template constraints. Look at isInputRange's 
implementation:



https://github.com/D-Programming-Language/phobos/blob/master/std/range/primitives.d#L143

Then you can do:

void foo(Range)(Range range)
   if (isInputRange!Range)// --
{
// ...
}

I have some explanation and examples here:


http://ddili.org/ders/d.en/templates_more.html#ix_templates_more.named%20template%20constraint

Ali



Re: D's type classes pattern ?

2015-03-24 Thread Ali Çehreli via Digitalmars-d-learn

On 03/24/2015 09:56 AM, matovitch wrote:

 just to be clear :

 void Bar(T : Foo)(T t){
 }

That means if T can implicitly be converted to Foo.


 is the same as

 void Bar(T)(T t) if (is(T == Foo)){
 }

That means if T is exactly Foo.

 and it is checked only at compile time ?

Yes to both.

Ali



D's type classes pattern ?

2015-03-24 Thread matovitch via Digitalmars-d-learn

Hi,

It's been a long time since I coded some d code... sorry I take
the lazy way asking for advices. :D

Lets say I want to implement some generic algorithm. I would like
to checks the types passed to my algorithm implements a specific
interface.

interface IStuff(Stuff)
{
 void foo();
}

class TypeClass(T, I) : I(T)
{
 alias this T;
}

void myAwesomeAlgo(Stuff) (TypeClass!(Stuff, IStuff) stuff)
{
 stuff.foo();
}


Well it seems that I have worked out my question in trying to
formulate it...Would something like this work ?


Re: D's type classes pattern ?

2015-03-24 Thread matovitch via Digitalmars-d-learn

More like :

import std.stdio;

interface IStuff(Stuff)
{
 void foo();
}

class TypeClass(T, I) : I(T)
{
 alias this stuff;
 T stuff;
}

void myAwesomeAlgo(Stuff) (TypeClass!(Stuff, IStuff) stuff)
{
 stuff.foo();
}

struct MyStuff
{
void foo()
{
writeln(Hello World !);
}
}

void main()
{
alias TypeStuff = TypeClass!(MyStuff, IStuff);
TypeStuff stuff;
myAwesomeAlgo(stuff);
}

Doesn't compile btw :

kmeans.d(8): Error: members expected
kmeans.d(8): Error: { } expected following aggregate declaration
kmeans.d(8): Error: Declaration expected, not '('
kmeans.d(12): Error: unrecognized declaration


Re: D's type classes pattern ?

2015-03-24 Thread matovitch via Digitalmars-d-learn
Well, just follow that link to the code...it almost compile : 
http://dpaste.com/3JNP0QD.


Re: D's type classes pattern ?

2015-03-24 Thread matovitch via Digitalmars-d-learn
Wait no ! In that case my type will have to inherit the 
interface...I don't want that, checking without inheriting...I 
know thats weird.


Re: D's type classes pattern ?

2015-03-24 Thread matovitch via Digitalmars-d-learn

On Tuesday, 24 March 2015 at 16:44:54 UTC, weaselcat wrote:

On Tuesday, 24 March 2015 at 15:51:00 UTC, matovitch wrote:

Hi,

It's been a long time since I coded some d code... sorry I take
the lazy way asking for advices. :D

Lets say I want to implement some generic algorithm. I would 
like
to checks the types passed to my algorithm implements a 
specific

interface.

interface IStuff(Stuff)
{
void foo();
}

class TypeClass(T, I) : I(T)
{
alias this T;
}

void myAwesomeAlgo(Stuff) (TypeClass!(Stuff, IStuff) stuff)
{
stuff.foo();
}


Well it seems that I have worked out my question in trying to
formulate it...Would something like this work ?


interface Foo{
}
void Bar(T : Foo)(T t){
}

but interfaces enable runtime polymorphism, you can just accept 
the interface itself

void Fun(Foo foo){
}



Thanks, just to be clear :

void Bar(T : Foo)(T t){
}

is the same as

void Bar(T)(T t) if (is(T == Foo)){
}

and it is checked only at compile time ? (for the runtime I know 
that what interface were meant for ;)).





Re: D's type classes pattern ?

2015-03-24 Thread matovitch via Digitalmars-d-learn
To resume my goal (last lonely message I promise), how can you 
statically check a type implement an interface without making 
this type inherit the interface (otherwise std.traits would do 
it) ?


ps : it seems to me that this is exactly what the haskell 
compiler do with type classes - layman opinion


Re: D's type classes pattern ?

2015-03-24 Thread matovitch via Digitalmars-d-learn

well, alias this is the issue here.

interface I
{
void foo();
}

struct S
{
void foo() {}
}

class C : I
{
S s;
alias this s;
}

don't compile...if you have any idea to do otherwise I am greatly 
interested. Thanks !


Re: D's type classes pattern ?

2015-03-24 Thread weaselcat via Digitalmars-d-learn

On Tuesday, 24 March 2015 at 15:51:00 UTC, matovitch wrote:

Hi,

It's been a long time since I coded some d code... sorry I take
the lazy way asking for advices. :D

Lets say I want to implement some generic algorithm. I would 
like

to checks the types passed to my algorithm implements a specific
interface.

interface IStuff(Stuff)
{
 void foo();
}

class TypeClass(T, I) : I(T)
{
 alias this T;
}

void myAwesomeAlgo(Stuff) (TypeClass!(Stuff, IStuff) stuff)
{
 stuff.foo();
}


Well it seems that I have worked out my question in trying to
formulate it...Would something like this work ?


interface Foo{
}
void Bar(T : Foo)(T t){
}

but interfaces enable runtime polymorphism, you can just accept 
the interface itself

void Fun(Foo foo){
}