digitalmars.D.learn - Make all functions from std.typecons "Proxy" inout
- Namespace (5/5) May 08 2012 In my development of the Ref / NotNull structure, I came across a
- Kenji Hara (23/29) May 08 2012 It is necessary. See following conceptual code:
- Namespace (7/38) May 08 2012 I thought, "inout" is evaluated by the compiler and make the
- Kenji Hara (41/83) May 09 2012 Yes. *In this case*, we should define two member function 'f' in
- Namespace (2/2) May 10 2012 Can you explain me how TemplateThisParameter works? I read in the
- Kagamin (1/1) May 10 2012 Looks like it infers the declaring type's modifiers.
- Kenji Hara (51/54) May 10 2012 Hmm, I have thought following code should work about foo, but
- Timon Gehr (4/10) May 11 2012 Until now, I actually thought that template this parameters work the way...
- sclytrack (2/13) May 11 2012 I'm new to the concept of "shared const". What is the difference when
- sclytrack (51/65) May 11 2012 And to answer myself.
- sclytrack (4/9) May 11 2012 Nope, "shared const" still doesn't make sense to me.
- Steven Schveighoffer (8/19) May 11 2012 shared means it can be possibly accessed by other threads
In my development of the Ref / NotNull structure, I came across a problem: All the methods of "Proxy" aren't "inout". Has this a reason or will change? In my opinion they should all be "inout". I mentioned previous self fixes in my corresponding "Ref / NotNull" thread already.
May 08 2012
On Tuesday, 8 May 2012 at 22:58:07 UTC, Namespace wrote:In my development of the Ref / NotNull structure, I came across a problem: All the methods of "Proxy" aren't "inout". Has this a reason or will change? In my opinion they should all be "inout". I mentioned previous self fixes in my corresponding "Ref / NotNull" thread already.It is necessary. See following conceptual code: struct S { void f() {} void g() {} } struct Proxy(T) { T o; void f()() inout { return o.f(); } void g(this T)() { return o.g(); } } void main() { Proxy!S p; //p.f(); // inside Proxy.f, typeof(o) == inout p.g(); } 'Proxy' object should forward its 'this' type to original object. For the purpose, TemplateThisParameter ('this T') works as expected. Kenji Hara
May 08 2012
On Wednesday, 9 May 2012 at 04:49:39 UTC, Kenji Hara wrote:On Tuesday, 8 May 2012 at 22:58:07 UTC, Namespace wrote:I thought, "inout" is evaluated by the compiler and make the method either const or not If not, then I understand, "inout" probably not yet complete. But in this case you would have to offer just two methods: void f () () {return o.f ();} void f () () const {return o.f ();}In my development of the Ref / NotNull structure, I came across a problem: All the methods of "Proxy" aren't "inout". Has this a reason or will change? In my opinion they should all be "inout". I mentioned previous self fixes in my corresponding "Ref / NotNull" thread already.It is necessary. See following conceptual code: struct S { void f() {} void g() {} } struct Proxy(T) { T o; void f()() inout { return o.f(); } void g(this T)() { return o.g(); } } void main() { Proxy!S p; //p.f(); // inside Proxy.f, typeof(o) == inout p.g(); } 'Proxy' object should forward its 'this' type to original object. For the purpose, TemplateThisParameter ('this T') works as expected. Kenji Hara
May 08 2012
On Wednesday, 9 May 2012 at 06:42:09 UTC, Namespace wrote:On Wednesday, 9 May 2012 at 04:49:39 UTC, Kenji Hara wrote:Yes. *In this case*, we should define two member function 'f' in Proxy to forward the call to original object. But, in general case, it is not sufficient. struct S { void f() {} void f() const{} void f() immutable {} void f() shared {} void f() shared const {} } struct Proxy(T) { T o; // forward to original f, need *five* thunks. Terrible! void f1()() { return o.f(); } void f1()() const { return o.f(); } void f1()() immutable { return o.f(); } void f1()() shared { return o.f(); } void f1()() shared const { return o.f(); } // cannot forward, this calls only S.f() const void f2()() inout { return o.f(); } // needs only one thunk. Excellent! void f3(this T)() { return o.g(); } } void main() { Proxy!S p; p.f1(); // call mutable f p.f2(); // CANNOT call mutable f p.f3(); // call mutable f } My first version of Proxy had such duplicates, but it was hard maintainable. After that, in review phase, I've discovered the way using TemplateThisParameter. It makes code readable and easy maintainable. After all, it is the reason why I use TempalteThisParameter instead of inout. Kenji HaraOn Tuesday, 8 May 2012 at 22:58:07 UTC, Namespace wrote:I thought, "inout" is evaluated by the compiler and make the method either const or not If not, then I understand, "inout" probably not yet complete. But in this case you would have to offer just two methods: void f () () {return o.f ();} void f () () const {return o.f ();}In my development of the Ref / NotNull structure, I came across a problem: All the methods of "Proxy" aren't "inout". Has this a reason or will change? In my opinion they should all be "inout". I mentioned previous self fixes in my corresponding "Ref / NotNull" thread already.It is necessary. See following conceptual code: struct S { void f() {} void g() {} } struct Proxy(T) { T o; void f()() inout { return o.f(); } void g(this T)() { return o.g(); } } void main() { Proxy!S p; //p.f(); // inside Proxy.f, typeof(o) == inout p.g(); } 'Proxy' object should forward its 'this' type to original object. For the purpose, TemplateThisParameter ('this T') works as expected. Kenji Hara
May 09 2012
Can you explain me how TemplateThisParameter works? I read in the manual but a more detail explanation would help me a lot.
May 10 2012
On Thursday, 10 May 2012 at 07:32:42 UTC, Namespace wrote:Can you explain me how TemplateThisParameter works? I read in the manual but a more detail explanation would help me a lot.Hmm, I have thought following code should work about foo, but doesn't. import std.stdio; struct Proxy { void foo(this T)() { writeln(T.stringof); static assert(is(typeof(this) == T)); // I have thought this should pass with all cases... } void bar(this T)() inout { writeln(T.stringof); //static assert(is(typeof(this) == T)); static assert(is(typeof(this) == inout(Proxy))); } void bar(this T)() shared inout { writeln(T.stringof); //static assert(is(typeof(this) == T)); static assert(is(typeof(this) == shared(inout(Proxy)))); } } void main() { Proxy mp; const Proxy cp; immutable Proxy ip; shared Proxy sp; shared const Proxy scp; mp.foo(); // expects: Proxy -> OK /+ cp.foo(); // expects: const(Proxy) -> NG! ip.foo(); // expects: immutable(Proxy) -> NG! sp.foo(); // expects: shared(Proxy) -> NG! scp.foo(); // expects: shared(const(Proxy)) -> NG! +/ mp.bar(); // expects: Proxy -> OK cp.bar(); // expects: const(Proxy) -> OK ip.bar(); // expects: immutable(Proxy) -> OK sp.bar(); // expects: shared(Proxy) -> OK scp.bar(); // expects: shared(const(Proxy)) -> OK } The spec: http://dlang.org/template#TemplateThisParameter doesn't talk about typeof(this). I think current behavior is less useful than I have thought. And, current std.typecons.Proxy doesn't work as expected for non-mutable objects...
May 10 2012
On 05/11/2012 08:56 AM, Kenji Hara wrote:The spec: http://dlang.org/template#TemplateThisParameter doesn't talk about typeof(this). I think current behavior is less useful than I have thought.What would the current behavior be useful for?And, current std.typecons.Proxy doesn't work as expected for non-mutable objects...Until now, I actually thought that template this parameters work the way as you expected them to work.
May 11 2012
struct S { void f() {} void f() const{} void f() immutable {} void f() shared {} void f() shared const {} } struct Proxy(T) { T o;I'm new to the concept of "shared const". What is the difference when comparing to "immutable"?
May 11 2012
On 05/11/2012 11:51 AM, sclytrack wrote:And to answer myself. import std.stdio; void test1(shared const float [] p) { writeln("works"); } int main() { writeln("--"); shared(const(int)) a; const(shared(int)) b; immutable int c; writeln(typeof(a).stringof); writeln(typeof(b).stringof); writeln(typeof(c).stringof); writeln("--"); shared(const(int []) []) aa; shared(immutable(int []) []) ab; writeln(typeof(aa).stringof); writeln(typeof(ab).stringof); writeln("--"); const(shared(int []) []) ba; immutable(shared(int []) []) bb; writeln(typeof(ba).stringof); writeln(typeof(bb).stringof); writeln("--"); shared float [] sm = new shared(float[10]); test1(sm); immutable float [] im = new immutable(float[10]); test1(im); return 0; } -- shared(const(int)) shared(const(int)) immutable(int) -- shared(const(int[])[]) shared(immutable(int[])[]) -- const(shared(int[])[]) immutable(int[][]) -- works worksstruct S { void f() {} void f() const{} void f() immutable {} void f() shared {} void f() shared const {} } struct Proxy(T) { T o;I'm new to the concept of "shared const". What is the difference when comparing to "immutable"?
May 11 2012
import std.stdio; void test1(shared const float [] p) { writeln("works"); }Nope, "shared const" still doesn't make sense to me. In the above example the p values can still change at any time. Why does "shared const" even exist?
May 11 2012
On Fri, 11 May 2012 08:05:33 -0400, sclytrack <sclytrack iq87.fr> wrote:shared means it can be possibly accessed by other threads const means you can't change it through this reference *but* another reference could change the values it points at. Combine both, and you will realize that it could possibly be changing *as you use it*. Why do you think we don't need it? -Steveimport std.stdio; void test1(shared const float [] p) { writeln("works"); }Nope, "shared const" still doesn't make sense to me. In the above example the p values can still change at any time. Why does "shared const" even exist?
May 11 2012