Re: Why does templated interface function return something different than final function?

2018-08-08 Thread Timoses via Digitalmars-d-learn

On Monday, 6 August 2018 at 14:27:01 UTC, Timoses wrote:
On Thursday, 2 August 2018 at 20:35:57 UTC, Steven 
Schveighoffer wrote:


Looking at the AST, it appears that toImpl doesn't recognize 
what inout(iface) is:


toImpl!(string, inout(iface))
{
@system string toImpl(ref inout(iface) value)
{
import std.array : appender;
import std.format : FormatSpec, formatValue;
Appender!string w = appender();
FormatSpec!char f = FormatSpec;
formatValue(w, value, f);
return w.data();
}

}

Vs. the nice neat call for const(iface)

toImpl!(string, const(iface))
{
@system string toImpl(const(iface) value)
{
return toStr(value);
}

}

Note the ref there, too. This means it can't cast to const. I 
wonder if that's an issue.


-Steve


Thanks for the insight. To me it sounds like std.conv `toImpl` 
doesn't properly handle inout types in this case.


Well, my "workaround" now is to simply cast the inout type to 
const before passing to std.conv.to ...



I've experimented a bit more and compiled it a bit together.

import std.stdio;
import std.conv : to;

interface I
{
void toString(scope void delegate(const(char)[]) sink) 
const;


final void printI()
{
writeln(this.to!string); // this is class A
}
final void printIinout() inout
{
writeln(this.to!string); // app.A
}
}

class A : I
{
void print()
{
writeln(this.to!string); // this is class A
}
// Compilation error
// std\format.d(3890,13): Error: template instance 
`std.format.formatObject!(Appender!string, inout(A), char)` does 
not match template declaration `formatObject(Writer, T, Char)(ref 
Writer w, ref T val, ref const FormatSpec!Char f) if 
(hasToString!(T, Char))`

/*void printinout() inout
{
writeln(this.to!string);
}*/
override void toString(scope void delegate(const(char)[]) 
sink) const

{
sink("this is class A");
}
}

unittest
{
I i = new A();
i.printI();
i.printIinout();

A a = new A();
a.print();
//a.printinout();
}

It seems inconsistent to me. What do you think? Should I open a 
bug report for this?

Also the compilation error should not occur, should it?


Re: Why does templated interface function return something different than final function?

2018-08-06 Thread Timoses via Digitalmars-d-learn
On Thursday, 2 August 2018 at 20:35:57 UTC, Steven Schveighoffer 
wrote:


Looking at the AST, it appears that toImpl doesn't recognize 
what inout(iface) is:


toImpl!(string, inout(iface))
{
@system string toImpl(ref inout(iface) value)
{
import std.array : appender;
import std.format : FormatSpec, formatValue;
Appender!string w = appender();
FormatSpec!char f = FormatSpec;
formatValue(w, value, f);
return w.data();
}

}

Vs. the nice neat call for const(iface)

toImpl!(string, const(iface))
{
@system string toImpl(const(iface) value)
{
return toStr(value);
}

}

Note the ref there, too. This means it can't cast to const. I 
wonder if that's an issue.


-Steve


Thanks for the insight. To me it sounds like std.conv `toImpl` 
doesn't properly handle inout types in this case.


Re: Why does templated interface function return something different than final function?

2018-08-02 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/18/18 7:09 AM, Timoses wrote:
Why is the interface templated function not also returning the class C 
toString return value "in C"??


 interface iface
 {
     void toString(scope void delegate(const(char)[]) sink) const;

     final string convert() inout
     {
     import std.conv;
     // assert(std.conv.to!string(this) == "in C"); // fails!
     return std.conv.to!string(this);
     }

     final string convert2() const
     {
     import std.conv;
     assert(std.conv.to!string(this) == "in C");
     return std.conv.to!string(this);
     }
 }

 class C : iface
 {
     void toString(scope void delegate(const(char)[]) sink) const
     {
     sink("in C");
     }
 }

 void main ()
 {
     iface i = new C();
     import std.stdio;
     writeln(i.convert); // "app.C"
     writeln(i.convert2()); // "in C"
 }

It seems like `inout` triggers some odd behaviour??


Looking at the AST, it appears that toImpl doesn't recognize what 
inout(iface) is:


toImpl!(string, inout(iface))
{
@system string toImpl(ref inout(iface) value)
{
import std.array : appender;
import std.format : FormatSpec, formatValue;
Appender!string w = appender();
FormatSpec!char f = FormatSpec;
formatValue(w, value, f);
return w.data();
}

}

Vs. the nice neat call for const(iface)

toImpl!(string, const(iface))
{
@system string toImpl(const(iface) value)
{
return toStr(value);
}

}

Note the ref there, too. This means it can't cast to const. I wonder if 
that's an issue.


-Steve


Re: Why does templated interface function return something different than final function?

2018-07-18 Thread Timoses via Digitalmars-d-learn

On Wednesday, 18 July 2018 at 11:09:12 UTC, Timoses wrote:
Why is the interface templated function not also returning the 
class C toString return value "in C"??


interface iface
{
void toString(scope void delegate(const(char)[]) sink) const;

final string convert() inout
{
import std.conv;
// assert(std.conv.to!string(this) == "in C"); // fails!
return std.conv.to!string(this);
}

final string convert2() const
{
import std.conv;
assert(std.conv.to!string(this) == "in C");
return std.conv.to!string(this);
}
}

class C : iface
{
void toString(scope void delegate(const(char)[]) sink) const
{
sink("in C");
}
}

void main ()
{
iface i = new C();
import std.stdio;
writeln(i.convert); // "app.C"
writeln(i.convert2()); // "in C"
}

It seems like `inout` triggers some odd behaviour??


Sorry, I experimented a bit and forgot to change the topic to 
something more fitting, e.g.

"Why does inout struct function return different results?"


Why does templated interface function return something different than final function?

2018-07-18 Thread Timoses via Digitalmars-d-learn
Why is the interface templated function not also returning the 
class C toString return value "in C"??


interface iface
{
void toString(scope void delegate(const(char)[]) sink) const;

final string convert() inout
{
import std.conv;
// assert(std.conv.to!string(this) == "in C"); // fails!
return std.conv.to!string(this);
}

final string convert2() const
{
import std.conv;
assert(std.conv.to!string(this) == "in C");
return std.conv.to!string(this);
}
}

class C : iface
{
void toString(scope void delegate(const(char)[]) sink) const
{
sink("in C");
}
}

void main ()
{
iface i = new C();
import std.stdio;
writeln(i.convert); // "app.C"
writeln(i.convert2()); // "in C"
}

It seems like `inout` triggers some odd behaviour??