Re: Template method and type resolution of return type

2014-04-20 Thread matovitch via Digitalmars-d-learn

On Sunday, 20 April 2014 at 00:55:31 UTC, David Held wrote:
On 4/19/2014 3:31 PM, Andrej Mitrovic via Digitalmars-d-learn 
wrote:

[...]
struct S
{
int get()  { return 0; }
T get(T)() { return T.init; }
}

void main()
{
S s;
float x = s.get();  // which overload? (currently int 
get())

}


Isn't this just because concrete methods are better overload 
candidates than method templates?


Dave


struct S
{
   ubyte get()  { return 0 ; }
   float get()  { return 0.; }
}

void main()
{
   S s;
   float x = s.get();  // does'nt know which overload, does'nt 
compile.

}


Re: Template method and type resolution of return type

2014-04-20 Thread monarch_dodra via Digitalmars-d-learn

On Sunday, 20 April 2014 at 07:52:08 UTC, matovitch wrote:


struct S
{
   ubyte get()  { return 0 ; }
   float get()  { return 0.; }
}

void main()
{
   S s;
   float x = s.get();  // does'nt know which overload, does'nt 
compile.

}


What I do find interesting though, is that you are allowed to 
write the overload, whereas C++ would outright block you for 
ambiguity at the source.


This means that with proper meta magic eg 
`__traits(getOverloadSet, S, get)`, you could, *manually* 
resolve the ambiguity yourself.


Re: Template method and type resolution of return type

2014-04-20 Thread matovitch via Digitalmars-d-learn

On Sunday, 20 April 2014 at 08:28:07 UTC, monarch_dodra wrote:

On Sunday, 20 April 2014 at 07:52:08 UTC, matovitch wrote:


struct S
{
  ubyte get()  { return 0 ; }
  float get()  { return 0.; }
}

void main()
{
  S s;
  float x = s.get();  // does'nt know which overload, does'nt 
compile.

}


What I do find interesting though, is that you are allowed to 
write the overload, whereas C++ would outright block you for 
ambiguity at the source.


This means that with proper meta magic eg 
`__traits(getOverloadSet, S, get)`, you could, *manually* 
resolve the ambiguity yourself.


You mean getOverloads ? (yes it's interesting)

How about this :

class S
{
public
{
this() {}

union other {
SFloat u_float;
SUbyte u_ubyte;
}

alias other this;
}
}

struct SFloat
{
float data;
alias data this;
}

struct SUbyte
{
ubyte data;
alias data this;
}

void main()
{
   S s;
   s.other.u_float.data = 0.5;
   //float x = s;
}

This gives :

main.d(31): Error: need 'this' for 'data' of type 'float'



Template method and type resolution of return type

2014-04-19 Thread matovitch via Digitalmars-d-learn

Hi everyone !

Let's say I have a struct :

struct Test
{
immutable (ubyte)[] data;

T get(T)()
{
return *(cast(T*)((data[0])));
}
}

This code will work :

import std.stdio;

void main()
{
Test t;
t.data = [152, 32, 64, 28, 95];
float b = t.get!float;
writefln(%s, b);
}

This won't compile :

import std.stdio;

void main()
{
Test t;
t.data = [152, 32, 64, 28, 95];
float b = t.get;
writefln(%s, b);
}

This neither:

import std.stdio;

void main()
{
Test t;
t.data = [152, 32, 64, 28, 95];
float b = t.get!(typeof(b));
writefln(%s, b);
}

And this will work:

import std.stdio;

void main()
{
Test t;
t.data = [152, 32, 64, 28, 95];
float b;
b = t.get!(typeof(b));
writefln(%s, b);
}

Why can't dmd infere the type 'float' ? In fact this would allow 
a nicer syntax for the Json struct in vibe.d for example.


Re: Template method and type resolution of return type

2014-04-19 Thread bearophile via Digitalmars-d-learn

matovitch:


struct Test
{
immutable (ubyte)[] data;

T get(T)()
{
return *(cast(T*)((data[0])));
}


It's better to return const/immutable data. Otherwise the program 
gives undefined results. In alternative use mutable ubytes for 
data.


Also data[0] is probably data.ptr.



This won't compile :

import std.stdio;

void main()
{
Test t;
t.data = [152, 32, 64, 28, 95];
float b = t.get;
writefln(%s, b);


D doesn't perform inference on the return type.



This neither:
...
Test t;
t.data = [152, 32, 64, 28, 95];
float b = t.get!(typeof(b));
writefln(%s, b);


I don't know. Perhaps b is not yet defined. This in theory could 
work.



In fact this would allow a nicer syntax for the Json struct in 
vibe.d for example.


I don't think in future D will behave differently on this code.

Bye,
bearophile


Re: Template method and type resolution of return type

2014-04-19 Thread matovitch via Digitalmars-d-learn

On Saturday, 19 April 2014 at 17:49:54 UTC, bearophile wrote:

matovitch:


struct Test
{
immutable (ubyte)[] data;

T get(T)()
{
return *(cast(T*)((data[0])));
}


It's better to return const/immutable data. Otherwise the 
program gives undefined results. In alternative use mutable 
ubytes for data.


Also data[0] is probably data.ptr.


I did'nt know that one.





This won't compile :

import std.stdio;

void main()
{
Test t;
t.data = [152, 32, 64, 28, 95];
float b = t.get;
writefln(%s, b);


D doesn't perform inference on the return type.


I see. But why ?

It's seems it exits a workaround overloading cast operators in 
c++ :

http://programmaticallyspeaking.blogspot.se/2012/09/infer-return-type-for-templated.html


However I think it would only work with opImplicitCast in D. The 
code given in vibe.d doc could became :


void manipulateJson(Json j)
{
j = Json.emptyObject;
j.name = Example;
j.id = 1;

// retrieving the values is done using get()
assert(j[name] == Example);
assert(j[id] == 1);

// print out as JSON: {name: Example, id: 1}
writefln(JSON: %s, j.toString());
}


ps : Thank you for all your great examples on Rosetta code (or 
the last one about the rubik's cube).


Re: Template method and type resolution of return type

2014-04-19 Thread matovitch via Digitalmars-d-learn

On Saturday, 19 April 2014 at 18:46:28 UTC, matovitch wrote:

On Saturday, 19 April 2014 at 17:49:54 UTC, bearophile wrote:

matovitch:




I did'nt know that one.



This last sentence is misleading, let be clear : I know almost 
nothing when it comes to D...but I'm willing to learn ! ;-)




Re: Template method and type resolution of return type

2014-04-19 Thread matovitch via Digitalmars-d-learn

On Saturday, 19 April 2014 at 18:46:28 UTC, matovitch wrote:

On Saturday, 19 April 2014 at 17:49:54 UTC, bearophile wrote:

matovitch:


struct Test
{
immutable (ubyte)[] data;

T get(T)()
{
return *(cast(T*)((data[0])));
}


It's better to return const/immutable data. Otherwise the 
program gives undefined results. In alternative use mutable 
ubytes for data.


Also data[0] is probably data.ptr.


I did'nt know that one.





This won't compile :

import std.stdio;

void main()
{
Test t;
t.data = [152, 32, 64, 28, 95];
float b = t.get;
writefln(%s, b);


D doesn't perform inference on the return type.


I see. But why ?

It's seems it exits a workaround overloading cast operators in 
c++ :

http://programmaticallyspeaking.blogspot.se/2012/09/infer-return-type-for-templated.html


However I think it would only work with opImplicitCast in D. 
The code given in vibe.d doc could became :


void manipulateJson(Json j)
{
j = Json.emptyObject;
j.name = Example;
j.id = 1;

// retrieving the values is done using get()
assert(j[name] == Example);
assert(j[id] == 1);

// print out as JSON: {name: Example, id: 1}
writefln(JSON: %s, j.toString());
}


ps : Thank you for all your great examples on Rosetta code (or 
the last one about the rubik's cube).


Or even :

void manipulateJson(Json j)
{
j = Json.emptyObject;
j.name = Example;
j.id = 1;

assert(j.name == Example);
assert(j.id == 1);

// print out as JSON: {name: Example, id: 1}
writefln(JSON: %s, j.toString());
}

Or at least this will work :

void manipulateJson(Json j)
{
j = Json.emptyObject;
j.name = Example;
j.id = 1;

string s = j.name;
assert(s == Example);


// print out as JSON: {name: Example, id: 1}
writefln(JSON: %s, j.toString());
}

Ok I stop fooding.


Re: Template method and type resolution of return type

2014-04-19 Thread Andrej Mitrovic via Digitalmars-d-learn
On 4/19/14, matovitch via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:
 This won't compile :

 import std.stdio;

 void main()
 {
   Test t;
   t.data = [152, 32, 64, 28, 95];
   float b = t.get;
   writefln(%s, b);
 }

Because it's probably overkill. At some point it becomes too much
magic. The following currently works but it might be considered an
ambiguity with return type inference:

-
struct S
{
int get()  { return 0; }
T get(T)() { return T.init; }
}

void main()
{
S s;
float x = s.get();  // which overload? (currently int get())
}
-


Re: Template method and type resolution of return type

2014-04-19 Thread David Held via Digitalmars-d-learn

On 4/19/2014 3:31 PM, Andrej Mitrovic via Digitalmars-d-learn wrote:

[...]
struct S
{
 int get()  { return 0; }
 T get(T)() { return T.init; }
}

void main()
{
 S s;
 float x = s.get();  // which overload? (currently int get())
}


Isn't this just because concrete methods are better overload candidates 
than method templates?


Dave