Re: Visibility of variables in struct nested within a class
Charles Hixson: Is this the way things are supposed to happen? (Changing the struct to a class is an OK patch, but I don't understand why it should either work or be necessary.) Please show a complete very little program, and maybe someone will try to help you. (Eventually it's a good idea to write a simple FAQ for D.learn, that also explains how to ask questions and how to give answers). Bye, bearophile
Re: Visibility of variables in struct nested within a class
Please show a complete very little program, and maybe someone will try to help you. I've seen there is code in another (broken) thread, so please ignore this request. Bye, bearophile
enforcing alias this on derived types
I have an interface that I would like to make sure that any classes derived from it will use alias this, else it can potentially break code. interface A(T) { @property T Value(); @property T Value(T value); // need to enforce alias _value this somehow } class B(T) : A!T { private T _value; @property T Value() { return _value; } @property T Value(T value) { return value = _value; } alias _value this; // B must use alias this so B(T) behaves like type T }
Re: How can i increase max number recursive template expansions?
Simen Kjaeraas: However, you can amend std.traits.EnumMembers to work with larger enums by using this version: Worth putting in Phobos? Bye, bearophile
Re: enforcing alias this on derived types
interface A(T) { @property T Value(); @property T Value(T value); // need to enforce alias Value this somehow } class B(T) : A!T { private T _value; @property T Value() { return _value; } @property T Value(T value) { return value = _value; } alias Value this; // B must use alias this so B(T) behaves like type T }
creating a variadic interface
this may seem a bit nonsensical but it is just an example: interface A(T, S...) { ... Generate a getter for each type in S... // e.g., @property S[0] property1(); // @property S[1] property2(); // } I imagine I have to use a mixin template but I'm unsure how to create a static loop that can be used properly. I think maybe using mixin's of mixin's is possible but I can't think of any simple way. Any ideas?
Re: enforcing alias this on derived types
On Monday, 8 July 2013 at 08:59:16 UTC, JS wrote: I have an interface that I would like to make sure that any classes derived from it will use alias this, else it can potentially break code. interface A(T) { @property T Value(); @property T Value(T value); // need to enforce alias _value this somehow } class B(T) : A!T { private T _value; @property T Value() { return _value; } @property T Value(T value) { return value = _value; } alias _value this; // B must use alias this so B(T) behaves like type T } I can't think of a neat way to do this. However,if you don't mind a nasty solution: You can just force the derived class writer to write a function that checks. Even if they just put in a no-op, it acts as a very solid reminder that will also be visible to anyone else reading their code. struct S{} interface I { void checkForAliasThis(); } class A : I { void checkForAliasThis() { static assert(is(typeof(this) : S)); } S s; alias s this; } Most other solutions I tried failed because the compiler evaluates the check (e.g. out contracts) in the interface, which makes the check either semantically wrong, or statically false/failed.
Re: enforcing alias this on derived types
On Monday, 8 July 2013 at 09:52:44 UTC, John Colvin wrote: Most other solutions I tried failed because the compiler evaluates the check (e.g. out contracts) in the interface, which makes the check either semantically wrong, or statically false/failed. Woops, should be the contract exists in the scope of the interface, not the compiler evaluates the check (e.g. out contracts) in the interface
Re: creating a variadic interface
On Monday, 8 July 2013 at 09:34:46 UTC, JS wrote: this may seem a bit nonsensical but it is just an example: interface A(T, S...) { ... Generate a getter for each type in S... // e.g., @property S[0] property1(); // @property S[1] property2(); // } I imagine I have to use a mixin template but I'm unsure how to create a static loop that can be used properly. I think maybe using mixin's of mixin's is possible but I can't think of any simple way. Any ideas? Here you go :) //just to hide the string mixin. mixin template Getters(S ...) { mixin(GettersImpl!S); } import std.conv : to; template GettersImpl(S ...) { static if(S.length == 0) { enum GettersImpl = ; } else static if(S.length == 1) { enum GettersImpl = @property ~ (S[$-1]).stringof ~ property ~ to!string(S.length) ~ ();\n; } else { enum GettersImpl = @property ~ (S[$-1]).stringof ~ property ~ to!string(S.length) ~ ();\n ~ GettersImpl!(S[0..$-1]); } } interface A(S...) { mixin Getters!S; } class B : A!(int, long, string) { //if everything works, we get errors here for missing methods. }
Re: How can i increase max number recursive template expansions?
On Monday, 8 July 2013 at 09:03:24 UTC, bearophile wrote: Simen Kjaeraas: However, you can amend std.traits.EnumMembers to work with larger enums by using this version: Worth putting in Phobos? Bye, bearophile I reckon so. It's rare to have such huge structs or classes that this sort of this becomes a problem for them, but massive enums are reasonably common.
Re: creating a variadic interface
On Monday, 8 July 2013 at 10:16:22 UTC, John Colvin wrote: On Monday, 8 July 2013 at 09:34:46 UTC, JS wrote: this may seem a bit nonsensical but it is just an example: interface A(T, S...) { ... Generate a getter for each type in S... // e.g., @property S[0] property1(); // @property S[1] property2(); // } I imagine I have to use a mixin template but I'm unsure how to create a static loop that can be used properly. I think maybe using mixin's of mixin's is possible but I can't think of any simple way. Any ideas? Here you go :) //just to hide the string mixin. mixin template Getters(S ...) { mixin(GettersImpl!S); } import std.conv : to; template GettersImpl(S ...) { static if(S.length == 0) { enum GettersImpl = ; } else static if(S.length == 1) { enum GettersImpl = @property ~ (S[$-1]).stringof ~ property ~ to!string(S.length) ~ ();\n; } else { enum GettersImpl = @property ~ (S[$-1]).stringof ~ property ~ to!string(S.length) ~ ();\n ~ GettersImpl!(S[0..$-1]); } } interface A(S...) { mixin Getters!S; } class B : A!(int, long, string) { //if everything works, we get errors here for missing methods. } I guess you beat me too it but I came up with something very similar which I think works too(uses foreach instead of recursion).. mixin template a(T...) { template b(TT...) { static string eval() { string s; int i = 0; foreach(t; TT) s = @property ~(t).stringof~ Name~to!string(i++)~();\n; return s; } enum b = eval(); } mixin(mixin(b!T);); }
Re: enforcing alias this on derived types
On Monday, 8 July 2013 at 09:55:29 UTC, John Colvin wrote: On Monday, 8 July 2013 at 09:52:44 UTC, John Colvin wrote: Most other solutions I tried failed because the compiler evaluates the check (e.g. out contracts) in the interface, which makes the check either semantically wrong, or statically false/failed. Woops, should be the contract exists in the scope of the interface, not the compiler evaluates the check (e.g. out contracts) in the interface Hopefully there is a cleaner way but this beats nothing... thanks.
Re: How can i increase max number recursive template expansions?
On 2013-07-08, 11:03, bearophile wrote: Simen Kjaeraas: However, you can amend std.traits.EnumMembers to work with larger enums by using this version: Worth putting in Phobos? Filed: http://d.puremagic.com/issues/show_bug.cgi?id=10569 And created a pull request: https://github.com/D-Programming-Language/phobos/pull/1400 -- Simen
Re: creating a variadic interface
On 07/08/13 13:25, JS wrote: mixin template a(T...) { template b(TT...) { static string eval() { string s; int i = 0; foreach(t; TT) s = @property ~(t).stringof~ Name~to!string(i++)~();\n; return s; } enum b = eval(); } mixin(mixin(b!T);); } It won't work if one of the types isn't already available inside the template - the .stringof will give you the name, but the mixin will fail; to avoid this you can use `T[0]` etc as the type directly, w/o stringifying. Something like this would also work: template evalExpMap(string C, string F, A...) { enum evalExpMap = { import std.array, std.conv; string s, l; static if (is(typeof(A))) alias B = typeof(A); else alias B = A; foreach (I, _; B) { auto r = replace( replace(F, %s, A[I].stringof), %d, to!string(I)); l ~= (I?, :) ~ r; s ~= r ~ ;\n; } return replace(replace(C, %...;, s), %..., l); }(); } interface A(T, S...) { mixin(evalExpMap!(q{%...;}, q{@property S[%d]/*%s*/ property%d()}, S)); } class C : A!(int, long, string) { /* Needs `propertyN` implementations. */ } It expands to: interface A(T, S...) { @property S[0]/*long*/ property0(); @property S[1]/*string*/ property1(); } and is more readable (once one knows what that helper does ;) ). In real code, the property names may need to be more configurable; but I'm not sure what you want to use this for. The helper rewrites every %s pattern - type-name and every %d - index; maybe that is enough. artur
Re: creating a variadic interface
On Monday, 8 July 2013 at 13:01:32 UTC, Artur Skawina wrote: It won't work if one of the types isn't already available inside the template - the .stringof will give you the name, but the mixin will fail; When would the type not be available?
Re: enforcing alias this on derived types
On Monday, 8 July 2013 at 11:37:31 UTC, JS wrote: On Monday, 8 July 2013 at 09:55:29 UTC, John Colvin wrote: On Monday, 8 July 2013 at 09:52:44 UTC, John Colvin wrote: Most other solutions I tried failed because the compiler evaluates the check (e.g. out contracts) in the interface, which makes the check either semantically wrong, or statically false/failed. Woops, should be the contract exists in the scope of the interface, not the compiler evaluates the check (e.g. out contracts) in the interface Hopefully there is a cleaner way but this beats nothing... thanks. There could be merit in adding more sophisticated requirements in base classes and interfaces. Currently, AFAIK there isn't one. inherited static invariant() {} would be one possibility, run at compile-time. Perhaps only run on classes that can be explicitly instantiated, but declared in any class/interface further up the inheritance tree. All static invariants would have to pass, in derived and base classes, i.e. it's a tighten-only contract like out. It's a unittest of sorts, but compile-time and fully class-aware.
Re: creating a variadic interface
On 07/08/13 15:12, John Colvin wrote: On Monday, 8 July 2013 at 13:01:32 UTC, Artur Skawina wrote: It won't work if one of the types isn't already available inside the template - the .stringof will give you the name, but the mixin will fail; When would the type not be available? auto as() { struct An {} return An(); } template A(T) {} A!(typeof(as())) T.stringof inside 'A' will return a name, but there's no way to map it back to a type. The 'A' template can be instantiated from a different module - the type won't be available in A if A doesn't import that other module. The type may be private, then even an import in A (or any parent scope) won't help. artur
Re: creating a variadic interface
On Monday, 8 July 2013 at 13:42:36 UTC, Artur Skawina wrote: On 07/08/13 15:12, John Colvin wrote: On Monday, 8 July 2013 at 13:01:32 UTC, Artur Skawina wrote: It won't work if one of the types isn't already available inside the template - the .stringof will give you the name, but the mixin will fail; When would the type not be available? auto as() { struct An {} return An(); } template A(T) {} A!(typeof(as())) T.stringof inside 'A' will return a name, but there's no way to map it back to a type. The 'A' template can be instantiated from a different module - the type won't be available in A if A doesn't import that other module. The type may be private, then even an import in A (or any parent scope) won't help. artur Ah ok, I see. In those cases you're not going to be able to declare a function that explicitly uses that type anyway, whether handwritten or generated as above.
Re: creating a variadic interface
On 07/08/13 16:12, John Colvin wrote: On Monday, 8 July 2013 at 13:42:36 UTC, Artur Skawina wrote: On 07/08/13 15:12, John Colvin wrote: On Monday, 8 July 2013 at 13:01:32 UTC, Artur Skawina wrote: It won't work if one of the types isn't already available inside the template - the .stringof will give you the name, but the mixin will fail; When would the type not be available? auto as() { struct An {} return An(); } template A(T) {} A!(typeof(as())) T.stringof inside 'A' will return a name, but there's no way to map it back to a type. The 'A' template can be instantiated from a different module - the type won't be available in A if A doesn't import that other module. The type may be private, then even an import in A (or any parent scope) won't help. Ah ok, I see. In those cases you're not going to be able to declare a function that explicitly uses that type anyway, whether handwritten or generated as above. struct A(T) { T f(T a) { return a.blah; } } artur
Re: creating a variadic interface
On Monday, 8 July 2013 at 14:25:17 UTC, Artur Skawina wrote: On 07/08/13 16:12, John Colvin wrote: On Monday, 8 July 2013 at 13:42:36 UTC, Artur Skawina wrote: On 07/08/13 15:12, John Colvin wrote: On Monday, 8 July 2013 at 13:01:32 UTC, Artur Skawina wrote: It won't work if one of the types isn't already available inside the template - the .stringof will give you the name, but the mixin will fail; When would the type not be available? auto as() { struct An {} return An(); } template A(T) {} A!(typeof(as())) T.stringof inside 'A' will return a name, but there's no way to map it back to a type. The 'A' template can be instantiated from a different module - the type won't be available in A if A doesn't import that other module. The type may be private, then even an import in A (or any parent scope) won't help. Ah ok, I see. In those cases you're not going to be able to declare a function that explicitly uses that type anyway, whether handwritten or generated as above. struct A(T) { T f(T a) { return a.blah; } } artur Right So the problem is that there's no mapping available between the type name and the type, not that the type itself is unavailable for use. Don't know why I'm being so slow with this today...must be the heat!
Re: Allocating a slice object
Am Thu, 04 Jul 2013 15:54:48 +0200 schrieb monarch_dodra monarchdo...@gmail.com: This should work: int[] *pSlice = (new int[][1]).ptr; -Steve Hum... That would allocate a dynamic array of slices though right? There'd be the Appendable overhead for just one element... No, it allocates a static one-element array of int[]s and then returns the pointer to the first and only element. It's similar to wrapping it in a struct. So +1 for that solution. -- Marco
Re: Allocating a slice object
On Monday, 8 July 2013 at 15:43:21 UTC, Marco Leise wrote: Am Thu, 04 Jul 2013 15:54:48 +0200 schrieb monarch_dodra monarchdo...@gmail.com: This should work: int[] *pSlice = (new int[][1]).ptr; -Steve Hum... That would allocate a dynamic array of slices though right? There'd be the Appendable overhead for just one element... No, it allocates a static one-element array of int[]s and then returns the pointer to the first and only element. It's similar to wrapping it in a struct. So +1 for that solution. I don't think that allocates a static array, it's just an alternative syntax for dynamic array allocation. The fact that you are extracting a pointer from it and it only has a single element doesn't mean it is a static array. // void main() { int[]* pSlice = (new int[][4]).ptr; writeln(pSlice[0 .. 4].capacity); } // This prints 7 for me, which would simply be impossible for new was allocating a static array.
Re: enforcing alias this on derived types
Am Mon, 08 Jul 2013 10:59:14 +0200 schrieb JS js.m...@gmail.com: I have an interface that I would like to make sure that any classes derived from it will use alias this, else it can potentially break code. interface A(T) { @property T Value(); @property T Value(T value); // need to enforce alias _value this somehow } class B(T) : A!T { private T _value; @property T Value() { return _value; } @property T Value(T value) { return value = _value; } alias _value this; // B must use alias this so B(T) behaves like type T } Interfaces only declare functions and have no state. What you do looks like you actually want to give the interface state through the alias ... this crutch. This is where you use abstract classes if possible: abstract class A(T) { private T _value; @property T Value() { return _value; } @property T Value(T value) { return value = _value; } alias _value this; } class B(T) : A!T { } I have only used alias ... this with structs and not tested this code. Generally I try to avoid mixing the realms of value types and class types in D like you are trying to. It gives me a bad gut feeling. In the OOP world I'd say, just use obj.Value everywhere you want your object to work like type T. -- Marco
Re: GitHub behind proxy servers among other questions
On Monday, 8 July 2013 at 03:35:03 UTC, Jesse Phillips wrote: On Monday, 8 July 2013 at 02:42:50 UTC, JohnnyK wrote: Hi all, I have searched everywhere over the Internet and I have yet to find a way to clone a project using git when my workstation is behind a company proxy. Can you guys clone your projects to a single zip file that I can download? This would be easier instead of working with some strange command-line tool that does not recognize modern networks. Honestly I just need the DWT binary with the help files so I can use the api. I have spent weeks searching for a way to download DWT to my windows workstation at work and have yet figured out how to make GIT work. Git provides a download by zip; Right side, bottom. This is what I found on getting Git to work with a proxy: http://stackoverflow.com/questions/128035/how-do-i-pull-from-a-git-repository-through-an-http-proxy I appreciate your response. I have tried these. I think the real issue is that I am not sure on the IP and port needed for the proxy here at work. The company uses WPAD in the browser and I cannot figure out what the IP and port the browser is using to connect through the proxy. If I knew that I probably could make it work. It would be nice if GitHUB would change their Downlaod Zip button such that it does a recursive zip to include all the subfolders.
Re: GitHub behind proxy servers among other questions
On Monday, 8 July 2013 at 02:42:50 UTC, JohnnyK wrote: Hi all, I have searched everywhere over the Internet and I have yet to find a way to clone a project using git when my workstation is behind a company proxy. Can you guys clone your projects to a single zip file that I can download? This would be easier instead of working with some strange command-line tool that does not recognize modern networks. Honestly I just need the DWT binary with the help files so I can use the api. I have spent weeks searching for a way to download DWT to my windows workstation at work and have yet figured out how to make GIT work. git can clone via HTTP(S): git clone http://github.com/D-Programming-Language/dmd.git
Re: GitHub behind proxy servers among other questions
On Monday, 8 July 2013 at 16:24:53 UTC, JohnnyK wrote: On Monday, 8 July 2013 at 03:35:03 UTC, Jesse Phillips wrote: On Monday, 8 July 2013 at 02:42:50 UTC, JohnnyK wrote: Hi all, I have searched everywhere over the Internet and I have yet to find a way to clone a project using git when my workstation is behind a company proxy. Can you guys clone your projects to a single zip file that I can download? This would be easier instead of working with some strange command-line tool that does not recognize modern networks. Honestly I just need the DWT binary with the help files so I can use the api. I have spent weeks searching for a way to download DWT to my windows workstation at work and have yet figured out how to make GIT work. Git provides a download by zip; Right side, bottom. This is what I found on getting Git to work with a proxy: http://stackoverflow.com/questions/128035/how-do-i-pull-from-a-git-repository-through-an-http-proxy I appreciate your response. I have tried these. I think the real issue is that I am not sure on the IP and port needed for the proxy here at work. The company uses WPAD in the browser and I cannot figure out what the IP and port the browser is using to connect through the proxy. If I knew that I probably could make it work. It would be nice if GitHUB would change their Downlaod Zip button such that it does a recursive zip to include all the subfolders. I would just ssh to somewhere outside the firewall, git clone there, tar the folder, then scp it back. Assuming that is possible through your firewall. If you're on windows then there are the always useful putty and winscp to do your ssh and scp work respectively.
Help me investigate a bug to file it.
Yeah, not very exiting, but I just spent an hour tracking down the fix, but now I'd like to track down *what* was making it break (my fix was luck). This should help Kenji (or others) have an easier time fixing it :) Also, I'm only repro'ing this on linux... I think there are two things involved here. The first, is accessing members of a struct for a static if, in a global scope: // import std.stdio; import std.range; struct S(R) { R _input; void foo() { static assert(is(typeof(_input[size_t.max .. size_t.max]))); //ok static assert(is(typeof(_input[size_t.max .. $]))); //ok } static assert(is(typeof(_input[size_t.max .. size_t.max]))); //ok static assert(is(typeof(_input[size_t.max .. $]))); //NOPE! } void main() { auto k = iota(0, 1).cycle(); S!(typeof(k)) s; } // As you can see, the static if behaves differently in a function, or in the raw body of the struct. Is this normal? Anybody know what is going on exactly? I'm trying to get more context here... --- Second, one of the things I found strange was that only *1* of the two assertions failed. basically, _input[0 .. 1] is fair game, yet, _input[0 .. $] is not? What gives? I put my nose in cycles's opDollar. It is written like this: // private static struct DollarToken {} DollarToken opDollar() { return DollarToken.init; } // Nothing special about it. Just a function that returns an object. Declaring it const/nothrow/@safe *and* pure does not fix the problem... *HOWEVER* declaring it as a manifest constant *does* fix the issue: // private static struct DollarToken {} enum opDollar = DollarToken.init; // I think I've run into global static ifs using members issues before, but just figured I wasn't allowed to use them. Apparently, to issue is more subtle than this. I have *no* idea how to file this, I have no idea what the rules are. Any insight?
Re: GitHub behind proxy servers among other questions
On Monday, 8 July 2013 at 16:49:05 UTC, John Colvin wrote: On Monday, 8 July 2013 at 16:24:53 UTC, JohnnyK wrote: On Monday, 8 July 2013 at 03:35:03 UTC, Jesse Phillips wrote: On Monday, 8 July 2013 at 02:42:50 UTC, JohnnyK wrote: Hi all, I have searched everywhere over the Internet and I have yet to find a way to clone a project using git when my workstation is behind a company proxy. Can you guys clone your projects to a single zip file that I can download? This would be easier instead of working with some strange command-line tool that does not recognize modern networks. Honestly I just need the DWT binary with the help files so I can use the api. I have spent weeks searching for a way to download DWT to my windows workstation at work and have yet figured out how to make GIT work. Git provides a download by zip; Right side, bottom. This is what I found on getting Git to work with a proxy: http://stackoverflow.com/questions/128035/how-do-i-pull-from-a-git-repository-through-an-http-proxy I appreciate your response. I have tried these. I think the real issue is that I am not sure on the IP and port needed for the proxy here at work. The company uses WPAD in the browser and I cannot figure out what the IP and port the browser is using to connect through the proxy. If I knew that I probably could make it work. It would be nice if GitHUB would change their Downlaod Zip button such that it does a recursive zip to include all the subfolders. I would just ssh to somewhere outside the firewall, git clone there, tar the folder, then scp it back. Assuming that is possible through your firewall. If you're on windows then there are the always useful putty and winscp to do your ssh and scp work respectively. Well, the thing to remember is that he did say company, so such approaches to bypass a firewall could very well be a violation of his IT policies. I know doing this would be *major* violation of my companie's policies, and could be cause for termination.
Re: GitHub behind proxy servers among other questions
On Monday, 8 July 2013 at 16:24:53 UTC, JohnnyK wrote: It would be nice if GitHUB would change their Downlaod Zip button such that it does a recursive zip to include all the subfolders. Ehhh, well that is useless. Sorry I couldn't hook you up with a solution.
Re: Help me investigate a bug to file it.
On 07/08/13 19:54, monarch_dodra wrote: struct S(R) { R _input; void foo() { static assert(is(typeof(_input[size_t.max .. size_t.max]))); //ok static assert(is(typeof(_input[size_t.max .. $]))); //ok } static assert(is(typeof(_input[size_t.max .. size_t.max]))); //ok static assert(is(typeof(_input[size_t.max .. $]))); //NOPE! } As you can see, the static if behaves differently in a function, or in the raw body of the struct. Is this normal? Anybody know what is going on exactly? I'm trying to get more context here... --- Second, one of the things I found strange was that only *1* of the two assertions failed. basically, _input[0 .. 1] is fair game, yet, _input[0 .. $] is not? What gives? I put my nose in cycles's opDollar. It is written like this: Did you really mean size_t.*max* above? Anyway, when '$' is rewritten as 'opDollar' and that is defined as a non-static method, it would be surprising if calling the method did work w/o any context pointer... // private static struct DollarToken {} DollarToken opDollar() { return DollarToken.init; } // Nothing special about it. Just a function that returns an object. Declaring it const/nothrow/@safe *and* pure does not fix the problem... *HOWEVER* declaring it as a manifest constant *does* fix the issue: // private static struct DollarToken {} enum opDollar = DollarToken.init; // Does declaring the opDollar function as `static` fix it? artur
Re: GitHub behind proxy servers among other questions
On Monday, 8 July 2013 at 18:09:44 UTC, monarch_dodra wrote: On Monday, 8 July 2013 at 16:49:05 UTC, John Colvin wrote: On Monday, 8 July 2013 at 16:24:53 UTC, JohnnyK wrote: On Monday, 8 July 2013 at 03:35:03 UTC, Jesse Phillips wrote: On Monday, 8 July 2013 at 02:42:50 UTC, JohnnyK wrote: Hi all, I have searched everywhere over the Internet and I have yet to find a way to clone a project using git when my workstation is behind a company proxy. Can you guys clone your projects to a single zip file that I can download? This would be easier instead of working with some strange command-line tool that does not recognize modern networks. Honestly I just need the DWT binary with the help files so I can use the api. I have spent weeks searching for a way to download DWT to my windows workstation at work and have yet figured out how to make GIT work. Git provides a download by zip; Right side, bottom. This is what I found on getting Git to work with a proxy: http://stackoverflow.com/questions/128035/how-do-i-pull-from-a-git-repository-through-an-http-proxy I appreciate your response. I have tried these. I think the real issue is that I am not sure on the IP and port needed for the proxy here at work. The company uses WPAD in the browser and I cannot figure out what the IP and port the browser is using to connect through the proxy. If I knew that I probably could make it work. It would be nice if GitHUB would change their Downlaod Zip button such that it does a recursive zip to include all the subfolders. I would just ssh to somewhere outside the firewall, git clone there, tar the folder, then scp it back. Assuming that is possible through your firewall. If you're on windows then there are the always useful putty and winscp to do your ssh and scp work respectively. Well, the thing to remember is that he did say company, so such approaches to bypass a firewall could very well be a violation of his IT policies. I know doing this would be *major* violation of my companie's policies, and could be cause for termination. I don't see how it is problematic? The firewall doesn't allow a particular type of connection, so you cache the result somewhere else and then access it via something that is allowed. It's the same as downloading the zip file from github, only you're doing the zipping yourself, then using scp to do the download instead of http. Is it common to have ssh connections banned in the IT policy but *not* blocked by the firewall?
Re: GitHub behind proxy servers among other questions
On Monday, 8 July 2013 at 18:34:33 UTC, Jesse Phillips wrote: On Monday, 8 July 2013 at 16:24:53 UTC, JohnnyK wrote: It would be nice if GitHUB would change their Downlaod Zip button such that it does a recursive zip to include all the subfolders. Ehhh, well that is useless. Sorry I couldn't hook you up with a solution. Thanks for all the input. I found a tool called NTLMAPS at http://ntlmaps.sourceforge.net/ which allows one to create a pass through proxy which understands NTLM proxy servers and are able to connect and forward HTTP requests and return responses so long story short I can now git clone as I need to NTLMAPS config file is pretty easy to configure with your proxy authentication information. However I did have to change the following named/value pairs. from this LM_PART:1 NT_PART:0 # Highly experimental option. See research.txt for details. # LM - 0682 # NT - 0582 # LM + NT - 0782 NTLM_FLAGS: 0682 to this LM_PART:1 NT_PART:1 # Highly experimental option. See research.txt for details. # LM - 0682 # NT - 0582 # LM + NT - 0782 NTLM_FLAGS: 0782 The proxy that I am behind was not happy until I did that. Anyway it is working now and I hope this post serves to help others with the same issue. also note that I had to use http:// in place of git:// in the git paths and in the case of DWT I had to go to every major folder and git clone them individually because for some reason git wanted to use git:// for subsequent requests. It is strange that it did not do that for the Win-Res folder just for the others. So I had to do commands like the following C:\GITClonescd dwt C:\GITClones\dwtgit clone --recursive http://github.com/d-widget-toolkit/base.g it Cloning into 'base'... remote: Counting objects: 806, done. remote: Compressing objects: 100% (326/326), done. remote: Total 806 (delta 402), reused 803 (delta 401) Receiving objects: 100% (806/806), 310.62 KiB | 261.00 KiB/s, done. Resolving deltas: 100% (402/402), done. C:\GITClones\dwtgit clone --recursive http://github.com/d-widget-toolkit/org.ec lipse.swt.gtk.linux.x86.git Cloning into 'org.eclipse.swt.gtk.linux.x86'... remote: Counting objects: 1691, done. remote: Compressing objects: 100% (634/634), done. remote: Total 1691 (delta 951), reused 1659 (delta 944) Receiving objects: 100% (1691/1691), 1.71 MiB | 361.00 KiB/s, done. Resolving deltas: 100% (951/951), done. C:\GITClones\dwtgit clone --recursive http://github.com/d-widget-toolkit/org.ec lipse.swt.win32.win32.x86.git Cloning into 'org.eclipse.swt.win32.win32.x86'... The only other thing I wish git could do is compile it for me so that I wouldn't have too but until we have HDgit I guess I am stuck with all this command line busy work. Thanks again for every ones time.
Re: GitHub behind proxy servers among other questions
On Monday, 8 July 2013 at 19:37:08 UTC, JohnnyK wrote: Another thing about GitHub's Download Zip button and this process as a whole. While the Download Zip button does allow you to download the master folders with recursive directories I do find it somewhat cumbersome or should I say awkward since you have to extract these in their correct locations upon download. This is not good when you are trying to follow someones instructions on how to download, build, and install their wares. I just don't get git? Just compile the code and put a binary up there for people to use. If I want to contribute to the code base then I will I guess go through all this hassle but for those of us not smart enough to contribute and just want to use it show me the binary please. In the amount of time it is taking to get this stuff I could have made major strides at building my own. Also I don't know what this fragmented downloading is going to do in the future when I want an updated version of the software. Please remember many of us are simpletons and don't use all these fancy version control systems and just need the binary so that we can use it. I guess you could say we are your customers and not your contributors. Please everyone in the D community try and follow the KISS methodology and if you do I bet you could get many more users of your wares and not people banging their heads until they give up. Yeah I was only 2 clicks away from giving up on this whole D thing thinking it was just too darned hard to make it worth my while. Who knows I still may give up since I have not attempted to compile it yet. I think I will wait until tomorrow before I try to tackle that part of the destruction's. For now I think I have it downloaded. BTW did I mention that I really hate git and compiling other people's code just to use an edit box and button on a dialog???
Beginner problem: casting in opCmp override
I'm trying to implement rational numbers with fully functioning comparison operators, but I can't seem to figure out why I'm getting this error and any help would be appreciated: Error: cannot cast from object.Object to Rat The code I have is as follows: int opCmp( Object o ) { Rat other = cast(Rat) o; --- this line throws the error … //stuff to return -1, 0, or 1 to opCmp with rational numbers for , =, etc. … } Thanks to anyone who can help!
Re: Beginner problem: casting in opCmp override
On Monday, July 08, 2013 23:21:59 Ugbar Ikenaki wrote: I'm trying to implement rational numbers with fully functioning comparison operators, but I can't seem to figure out why I'm getting this error and any help would be appreciated: Error: cannot cast from object.Object to Rat The code I have is as follows: int opCmp( Object o ) { Rat other = cast(Rat) o; --- this line throws the error … //stuff to return -1, 0, or 1 to opCmp with rational numbers for , =, etc. … } Thanks to anyone who can help! You're going to need to provide more code than that. Without knowing anything about Rat, we can't help you. On a side note, I point out that talking about compiler errors as being thrown is going to cause confusion, as throwing is something completely different. - Jonathan M Davis
Re: Beginner problem: casting in opCmp override
Also…Rat is a struct, not a class. Herein might lie the problem.
Re: Beginner problem: casting in opCmp override
Thanks for the quick response! Here is the initialization code for my Rat struct. I created a GCD function that I've tested to work fine: import std.stdio, std.exception; struct Rat { private long n; //Numerator private long d; //Denominator public this( long numerator, long denominator ) { enforce( denominator != 0, Error. Denominator can not be 0. (Rat.this)); //Default 0-value Rat object if( numerator == 0 || numerator == -0 ) { n = 0; d = 1; } else { //Assign appropriates signs (+ / -) to numerator // -x/-y if( numerator 0 denominator 0 ) { numerator = -numerator; denominator = -denominator; // x/-y } else if( numerator 0 denominator 0 ) { numerator = -numerator; denominator = -denominator; } //Find GCD of numerator and denominator long gcd = gcd( numerator, denominator ); //Return reduced fraction of numerator and denominator (invariant) n = numerator / gcd; d = denominator / gcd; } } The following is the code to override the opCmp function: int opCmp( Object o ) { Rat other = cast(Rat) o; long num1 = n; long den1 = d; long num2 = other.n; long den2 = other.d; //If denominators are not equal to each other... if( den1 != den2 ) { //Set denominators equal to each other (with corresponding numerators) num1 *= den2; den1 *= den2; if(den2 den1) { num2 *= (den1 / den2); den2 *= (den1 / den2); } else { num2 *= (den2 / den1); den2 *= (den2 / den1); } //Return opCmp int value (-1, 0, 1) if( num1 - num2 0 ) { return -1; } else if( num1 - num2 == 0 ) { return 0; } else { //if( num1 - num2 0 ) return 1; } //If denominators are equal to each other... } else { //Less than if( num1 - num2 0 ) { return -1; //Equal to } else if( num1 - num2 == 0 ) { return 0; //Greater than } else { //if( num1 - num2 0 ) return 1; } } }
Re: Beginner problem: casting in opCmp override
On Monday, July 08, 2013 23:31:14 Ugbar Ikenaki wrote: Also…Rat is a struct, not a class. Herein might lie the problem. So, this is Rat's opCmp, correct? If it's a struct, it makes no sense for it to take an Object. Object is the base class for all classes and has nothing to do with structs. opCmp needs to take Rat, not Object. And to be fully functional, you might need to have a ref overload as well (since sometimes the compiler and runtime get overly picky about exact signatures - which is slowly getting fixed fortunately). So, something like this should work: int opCmp(Rat other) { return this.opCmp(other); } int opCmp(ref Rat other) { //do stuff for comparison } - Jonathan M Davis
Re: Beginner problem: casting in opCmp override
On 07/08/2013 02:21 PM, Ugbar Ikenaki wrote: I'm trying to implement rational numbers with fully functioning comparison operators, but I can't seem to figure out why I'm getting this error and any help would be appreciated: Error: cannot cast from object.Object to Rat The code I have is as follows: int opCmp( Object o ) { Rat other = cast(Rat) o; --- this line throws the error … //stuff to return -1, 0, or 1 to opCmp with rational numbers for , =, etc. … } Thanks to anyone who can help! Yeah, the signature of opCmp is different for structs so you don't need to cast. Once you have the subtraction defined, opCmp can be as simple as the following: /* Sort order operator: Returns a negative value if this * fraction is before, a positive value if this fraction * is after, and zero if both fractions have the same sort * order. */ int opCmp(const ref Fraction rhs) const { immutable result = this - rhs; /* Being a long, num cannot be converted to int * automatically; it must be converted explicitly by * 'to' (or cast). */ return to!int(result.num); } I have a couple of chapters that go over operator overloading. Operator Overloading: http://ddili.org/ders/d.en/operator_overloading.html Object is specifically for classes: http://ddili.org/ders/d.en/object.html Ali
Re: Help me investigate a bug to file it.
On Monday, 8 July 2013 at 18:55:30 UTC, Artur Skawina wrote: On 07/08/13 19:54, monarch_dodra wrote: struct S(R) { R _input; void foo() { static assert(is(typeof(_input[size_t.max .. size_t.max]))); //ok static assert(is(typeof(_input[size_t.max .. $]))); //ok } static assert(is(typeof(_input[size_t.max .. size_t.max]))); //ok static assert(is(typeof(_input[size_t.max .. $]))); //NOPE! } As you can see, the static if behaves differently in a function, or in the raw body of the struct. Is this normal? Anybody know what is going on exactly? I'm trying to get more context here... --- Second, one of the things I found strange was that only *1* of the two assertions failed. basically, _input[0 .. 1] is fair game, yet, _input[0 .. $] is not? What gives? I put my nose in cycles's opDollar. It is written like this: Did you really mean size_t.*max* above? Yeah. It's not a runtime test. In this case, I *also* need to make sure that the slie operation accepts a size_t arg. If I use size_t.min, it statically evaluates to zero, so the test becomes sens-less: saying fun(size_t.min) works doesn't actually guarantee you can pass a size_t: it may actually only accepts ubytes or short indexing. But I guess that is a detail in the scope of the original problem. Anyway, when '$' is rewritten as 'opDollar' and that is defined as a non-static method, it would be surprising if calling the method did work w/o any context pointer... But, the context pointer *should* be defined as whatever the owner of the indexing/slicing object is, no? In this case, it's simply _input. It has nothing to do with the this pointer being available... If anything, it kind of worries me about *what* the implementation is doing with the this pointer, but I haven't been able to trick it into calling a wrong function. Does declaring the opDollar function as `static` fix it? artur Yes. It does fix it. I think you put your finger exactly on where the issue is. I'll report it in the morning. Thank you for participating :)
Re: Beginner problem: casting in opCmp override
On Mon, Jul 08, 2013 at 02:42:30PM -0700, Jonathan M Davis wrote: On Monday, July 08, 2013 23:31:14 Ugbar Ikenaki wrote: Also…Rat is a struct, not a class. Herein might lie the problem. So, this is Rat's opCmp, correct? If it's a struct, it makes no sense for it to take an Object. Object is the base class for all classes and has nothing to do with structs. opCmp needs to take Rat, not Object. And to be fully functional, you might need to have a ref overload as well (since sometimes the compiler and runtime get overly picky about exact signatures - which is slowly getting fixed fortunately). So, something like this should work: int opCmp(Rat other) { return this.opCmp(other); } int opCmp(ref Rat other) [...] The second overload above should be: int opCmp(ref const Rat other) const otherwise the typeinfo of Rat will be wrong, and using Rat in AA's will not work correctly. (DMD is very picky about the exact signature of opCmp when it's generating typeinfos -- as I found out yesterday.) T -- I think the conspiracy theorists are out to get us...
Re: Beginner problem: casting in opCmp override
Wow! You guys are fast and helpful! Thank you Jonathan and Ali! I already got it to work, and Ali, your book is great! I've read about the first 150 pages. I'll check out those operator overloading chapters for sure. -U
Re: Beginner problem: casting in opCmp override
And thanks for that pointer, too, H.S.
Re: Beginner problem: casting in opCmp override
Here's one more question: Before I knew that opEquals existed, I tried overloading the equality expressions (== and !=) in opBinary using the code below. It worked. Why would the overloaded opBinary version get called if the equality expressions are held in opEquals? I'm just interested in knowing how dmd chooses where to take an expression from if it lies in multiple places (e.g. == in opEquals and opBinary), even if what I did was just add the == operator to opBinary. (Is that what I did there?) override bool opBinary( string op ) ( Rect r ) if( op == == ) { //Check if rectangle coordinates are equal if( left == r.left right == r.right top == r.top bottom == r.bottom ) { return true; } else { return false; } } Thanks!
Re: Help me investigate a bug to file it.
On 07/08/13 23:45, monarch_dodra wrote: On Monday, 8 July 2013 at 18:55:30 UTC, Artur Skawina wrote: On 07/08/13 19:54, monarch_dodra wrote: struct S(R) { R _input; void foo() { static assert(is(typeof(_input[size_t.max .. size_t.max]))); //ok static assert(is(typeof(_input[size_t.max .. $]))); //ok } static assert(is(typeof(_input[size_t.max .. size_t.max]))); //ok static assert(is(typeof(_input[size_t.max .. $]))); //NOPE! } As you can see, the static if behaves differently in a function, or in the raw body of the struct. Is this normal? Anybody know what is going on exactly? I'm trying to get more context here... --- Second, one of the things I found strange was that only *1* of the two assertions failed. basically, _input[0 .. 1] is fair game, yet, _input[0 .. $] is not? What gives? I put my nose in cycles's opDollar. It is written like this: Did you really mean size_t.*max* above? Yeah. It's not a runtime test. In this case, I *also* need to make sure that the slie operation accepts a size_t arg. If I use size_t.min, it statically evaluates to zero, so the test becomes sens-less: saying fun(size_t.min) works doesn't actually guarantee you can pass a size_t: it may actually only accepts ubytes or short indexing. Didn't think of that; these implicit narrowing conversion can be, umm, surprising. But as long as the right overload gets picked, I guess they're safe. Thanks for the explanation. Anyway, when '$' is rewritten as 'opDollar' and that is defined as a non-static method, it would be surprising if calling the method did work w/o any context pointer... But, the context pointer *should* be defined as whatever the owner of the indexing/slicing object is, no? In this case, it's simply _input. It has nothing to do with the this pointer being available... If anything, it kind of worries me about *what* the implementation is doing with the this pointer, but I haven't been able to trick it into calling a wrong function. It's just like struct S { auto opDollar() { return 42; } enum a = opDollar(); } This can't work - there is no S object to call the method with. enum a = S.init.opDollar(); would work, just as making the method static. Does declaring the opDollar function as `static` fix it? Yes. It does fix it. I think you put your finger exactly on where the issue is. I'll report it in the morning. Thank you for participating :) Thank you for still trying to improve the std lib. I gave up on using it, other than for toy examples, long time ago. Hopefully it will be usable at some point. artur
Re: Beginner problem: casting in opCmp override
On Tuesday, July 09, 2013 00:35:32 Ugbar Ikenaki wrote: Here's one more question: Before I knew that opEquals existed, I tried overloading the equality expressions (== and !=) in opBinary using the code below. It worked. Why would the overloaded opBinary version get called if the equality expressions are held in opEquals? I'm just interested in knowing how dmd chooses where to take an expression from if it lies in multiple places (e.g. == in opEquals and opBinary), even if what I did was just add the == operator to opBinary. (Is that what I did there?) override bool opBinary( string op ) ( Rect r ) if( op == == ) { //Check if rectangle coordinates are equal if( left == r.left right == r.right top == r.top bottom == r.bottom ) { return true; } else { return false; } } Thanks! I don't believe that that will ever work. If you want to overload == and !=, use opEquals. opBinary isn't used for that. Look at http://dlang.org/operatoroverloading.html if you want to see which function to use to overload for each operator. - Jonathan M Davis
Re: Beginner problem: casting in opCmp override
On Tue, Jul 09, 2013 at 12:35:32AM +0200, Ugbar Ikenaki wrote: Here's one more question: Before I knew that opEquals existed, I tried overloading the equality expressions (== and !=) in opBinary using the code below. It worked. Why would the overloaded opBinary version get called if the equality expressions are held in opEquals? [...] I doubt opBinary was actually called. Probably what happened was that == defaulted to the built-in implementation of opEquals, which simply performs a bitwise comparison of the struct/class, and it just so happened that it was close to (or the same) as what you intended. Basically, when you write x==y, the compiler looks for opEquals and opCmp. If opEquals is found, then it's rewritten as x.opEquals(y); otherwise, if opCmp is found, it's rewritten as x.opCmp(y)==0. If neither are found, then the compiler generates a default implementation of opEquals, which basically does a bitwise comparison of x and y. T -- Arise, you prisoners of Windows Arise, you slaves of Redmond, Wash, The day and hour soon are coming When all the IT folks say Gosh! It isn't from a clever lawsuit That Windowsland will finally fall, But thousands writing open source code Like mice who nibble through a wall. -- The Linux-nationale by Greg Baker
Re: Beginner problem: casting in opCmp override
On Monday, July 08, 2013 16:38:16 H. S. Teoh wrote: On Tue, Jul 09, 2013 at 12:35:32AM +0200, Ugbar Ikenaki wrote: Here's one more question: Before I knew that opEquals existed, I tried overloading the equality expressions (== and !=) in opBinary using the code below. It worked. Why would the overloaded opBinary version get called if the equality expressions are held in opEquals? [...] I doubt opBinary was actually called. Probably what happened was that == defaulted to the built-in implementation of opEquals, which simply performs a bitwise comparison of the struct/class, and it just so happened that it was close to (or the same) as what you intended. Basically, when you write x==y, the compiler looks for opEquals and opCmp. If opEquals is found, then it's rewritten as x.opEquals(y); otherwise, if opCmp is found, it's rewritten as x.opCmp(y)==0. If neither are found, then the compiler generates a default implementation of opEquals, which basically does a bitwise comparison of x and y. Actually, what it's supposed to do isn't necessarily a bitwise comparison. It's supposed to do a recursive comparison of all of the members, where it calls == on each of the members. If a bitwise comparison will do that, then it may end up as a bitwise comparison for efficiency reasons, but it's not necessarily a bitwise comparison. It used to be that it was doing a bitwise comparison when it wasn't supposed to, but that was fixed fairly recently (though I don't recall if that fix has been released yet). Basically, there's no reason to overload opEquals unless you have a member which you don't want to compare with == (e.g. pointers). - Jonathan M Davis
Re: Beginner problem: casting in opCmp override
On Monday, July 08, 2013 16:48:05 Jonathan M Davis wrote: On Monday, July 08, 2013 16:38:16 H. S. Teoh wrote: On Tue, Jul 09, 2013 at 12:35:32AM +0200, Ugbar Ikenaki wrote: Here's one more question: Before I knew that opEquals existed, I tried overloading the equality expressions (== and !=) in opBinary using the code below. It worked. Why would the overloaded opBinary version get called if the equality expressions are held in opEquals? [...] I doubt opBinary was actually called. Probably what happened was that == defaulted to the built-in implementation of opEquals, which simply performs a bitwise comparison of the struct/class, and it just so happened that it was close to (or the same) as what you intended. Basically, when you write x==y, the compiler looks for opEquals and opCmp. If opEquals is found, then it's rewritten as x.opEquals(y); otherwise, if opCmp is found, it's rewritten as x.opCmp(y)==0. If neither are found, then the compiler generates a default implementation of opEquals, which basically does a bitwise comparison of x and y. Actually, what it's supposed to do isn't necessarily a bitwise comparison. It's supposed to do a recursive comparison of all of the members, where it calls == on each of the members. If a bitwise comparison will do that, then it may end up as a bitwise comparison for efficiency reasons, but it's not necessarily a bitwise comparison. It used to be that it was doing a bitwise comparison when it wasn't supposed to, but that was fixed fairly recently (though I don't recall if that fix has been released yet). Basically, there's no reason to overload opEquals unless you have a member which you don't want to compare with == (e.g. pointers). I should point out though (in case someone misunderstands) is that that applies specifically to structs. You always have to overload opEquals on classes if you want == to work properly (since Object's opEquals does a comparison of the references rather than the objects). - Jonathan M Davis
Re: Beginner problem: casting in opCmp override
On Mon, Jul 08, 2013 at 04:48:05PM -0700, Jonathan M Davis wrote: On Monday, July 08, 2013 16:38:16 H. S. Teoh wrote: [...] Basically, when you write x==y, the compiler looks for opEquals and opCmp. If opEquals is found, then it's rewritten as x.opEquals(y); otherwise, if opCmp is found, it's rewritten as x.opCmp(y)==0. If neither are found, then the compiler generates a default implementation of opEquals, which basically does a bitwise comparison of x and y. Actually, what it's supposed to do isn't necessarily a bitwise comparison. It's supposed to do a recursive comparison of all of the members, where it calls == on each of the members. If a bitwise comparison will do that, then it may end up as a bitwise comparison for efficiency reasons, but it's not necessarily a bitwise comparison. It used to be that it was doing a bitwise comparison when it wasn't supposed to, but that was fixed fairly recently (though I don't recall if that fix has been released yet). Basically, there's no reason to overload opEquals unless you have a member which you don't want to compare with == (e.g. pointers). [...] Unfortunately, this isn't true for opCmp. If you don't define opCmp, the typeinfo of the struct will have a compare function that basically does bitwise comparison. Proof: struct S { int[] data; } void main() { auto s = S([1,2,3]); auto t = S([1,2,3]); auto u = S([1,2,4]); assert(s == t); assert(s != u); assert(typeid(s).compare(s, t) == 0); // FAILS assert(typeid(s).compare(s, u) != 0); } Should this be filed as a DMD bug? T -- A computer doesn't mind if its programs are put to purposes that don't match their names. -- D. Knuth
Re: Help me investigate a bug to file it.
On 07/09/13 00:43, Artur Skawina wrote: On 07/08/13 23:45, monarch_dodra wrote: But, the context pointer *should* be defined as whatever the owner of the indexing/slicing object is, no? In this case, it's simply _input. It has nothing to do with the this pointer being available... If anything, it kind of worries me about *what* the implementation is doing with the this pointer, but I haven't been able to trick it into calling a wrong function. It's just like Sorry, didn't read that code again before replying. What is indeed unintuitive is that the first typeof expression succeeds but the other one fails. But this is related to how typeof() works, apparently by design. Eg: auto f(int a) { return a; } pragma(msg, typeof(f(1))); // int. OK. alias INT = int; pragma(msg, typeof(f(INT))); // int. OK... //pragma(msg, typeof(f(int))); // Compile error. That plus a non-existing this._input, results in a bit (too much) magic, and the first test passes. The other one fails because of the '$' (ie opDollar() call). artur
Re: Beginner problem: casting in opCmp override
On Monday, July 08, 2013 16:58:03 H. S. Teoh wrote: On Mon, Jul 08, 2013 at 04:48:05PM -0700, Jonathan M Davis wrote: On Monday, July 08, 2013 16:38:16 H. S. Teoh wrote: [...] Basically, when you write x==y, the compiler looks for opEquals and opCmp. If opEquals is found, then it's rewritten as x.opEquals(y); otherwise, if opCmp is found, it's rewritten as x.opCmp(y)==0. If neither are found, then the compiler generates a default implementation of opEquals, which basically does a bitwise comparison of x and y. Actually, what it's supposed to do isn't necessarily a bitwise comparison. It's supposed to do a recursive comparison of all of the members, where it calls == on each of the members. If a bitwise comparison will do that, then it may end up as a bitwise comparison for efficiency reasons, but it's not necessarily a bitwise comparison. It used to be that it was doing a bitwise comparison when it wasn't supposed to, but that was fixed fairly recently (though I don't recall if that fix has been released yet). Basically, there's no reason to overload opEquals unless you have a member which you don't want to compare with == (e.g. pointers). [...] Unfortunately, this isn't true for opCmp. If you don't define opCmp, the typeinfo of the struct will have a compare function that basically does bitwise comparison. Proof: struct S { int[] data; } void main() { auto s = S([1,2,3]); auto t = S([1,2,3]); auto u = S([1,2,4]); assert(s == t); assert(s != u); assert(typeid(s).compare(s, t) == 0); // FAILS assert(typeid(s).compare(s, u) != 0); } Should this be filed as a DMD bug? Yes. opCmp's behavior should definitely match opEquals' behavior. - Jonathan M Davis
function type stringification
I'm a bit confused with the behavior of function type stringification: int main(string[]args){ auto foo=main; pragma(msg,typeid(typeof(foo))); pragma(msg,typeid(typeof(foo)).stringof); //pragma(msg,typeid(typeof(foo))); import std.stdio; writeln(typeid(typeof(foo)).stringof); writeln(typeid(typeof(foo))); writeln(typeof(main).stringof); writeln(typeid(typeof(main)).stringof); writeln(typeof(main).stringof); return 0; } dmd -run main.d: D17TypeInfo_PFAAyaZi6__initZ D17TypeInfo_PFAAyaZi6__initZ D17TypeInfo_PFAAyaZi6__initZ int()* int function(string[] args) D16TypeInfo_FAAyaZi6__initZ int(string[] args) A) pragma(msg,typeid(typeof(foo))); adds an extra space compared to pragma(msg,typeid(typeof(foo)).stringof); B) can someone please explain the behavior of each stringification? Eg, writeln(typeid(typeof(foo))) discards input argument types (int()*), etc.