Re: alias c=mixin(expr); disallowed, why?
On 2013-06-22 23:47, Timon Gehr wrote: No, it is arbitrary. I think the spec says you can only mixin whole expression. But for some reason you can use a mixin in a __traits expression without having the whole expression in a mixin. -- /Jacob Carlborg
Re: Can call static method with null reference
On 2013-06-22 23:51, Timon Gehr wrote: If that is the only problem then the solution is to allow overloading on static, which is easy to do. You still need to call the static method on the class/struct if there's an ambiguity. -- /Jacob Carlborg
Good Candy Doc Forks?
Does anybody know some good looking or with good features? btw, I'm wondering why is some basic version of Candy Doc bundled with DMD. Thanks.
Re: Can call static method with null reference
On Sunday, June 23, 2013 11:30:11 Jacob Carlborg wrote: > On 2013-06-22 23:51, Timon Gehr wrote: > > If that is the only problem then the solution is to allow overloading on > > static, which is easy to do. > > You still need to call the static method on the class/struct if there's > an ambiguity. I would have thought that that was obvious, and I fail to see why that would be a problem. The only risk I see in allowing static and non-static functions to be overloaded, is that if you have static function being called with an instance, and you add a non-static overload, then the code would silently change to call the non-static function. But we have that exact same problem with UFCS and member functions as it is, and that wouldn't break any existing code (since you can't overload on static right now). It would just be a future risk of breaking code. - Jonathan M Davis
Re: Can call static method with null reference
I don't see what's so terrible about it It's bug prone. class Foo { public: static void test1() { } void test2() { } } Foo f; f.test1(); /// Oh nice, that works, f is not null. f.test2(); /// WTF? f is null? Also I don't know why I should call static methods from an instance. What's the purpose?
Re: Can call static method with null reference
On Sunday, June 23, 2013 12:02:42 Namespace wrote: > > I don't see what's so terrible about it > > It's bug prone. > > class Foo { > public: > static void test1() { } > void test2() { } > } > > Foo f; > f.test1(); /// Oh nice, that works, f is not null. > f.test2(); /// WTF? f is null? I fail to see what's bug-prone about that. It's confusing, but it's not causing any bugs. > Also I don't know why I should call static methods from an > instance. What's the purpose? It's stupid and pointless as far as I can tell, but I believe that C++, Java, C#, and D all do it, so as stupid as it is, it's a common stupidity. I certainly wish that we could change it, but I wouldn't expect Walter to agree to the change, since it would break at least some existing code, and I suspect that he doesn't consider the fact that you can call static functions on instances to be a problem. That's not the sort of thing that he generally seems to think is an issue. It's almost always stuff that causes actual bugs that he agrees to change and not things that are aesthetically displeasing or which could theoretically cause bugs. - Jonathan M Davis
Re: alias c=mixin(expr); disallowed, why?
On 06/22/13 21:52, Timothee Cour wrote: > Is there a reason the language spec disallows this? > > > void main(){ > auto a=mixin("1");//OK > alias b=a;//OK > mixin("alias c=a;");//OK > // alias c=mixin("a");//NG : Error: basic type expected, not mixin > } How would that be different from "auto c=mixin("a");"? It's probably clear, but that error message is misleading, so i'll say it anyway - the reason why your 'alias' line does not work is because alias requires a symbol, but 'mixin()' is an expression. Special-casing mixin-expressions (so that they propagate the symbol when that is possible would be a bad idea); the other possibility is to allow aliasing /expressions/. But that's a bad idea too, and would likely not do what you expect it to do. A mixin-less version could be made to work, but there are already other ways to get the same effect. Hence the above question. artur
Re: Can call static method with null reference
On Sunday, 23 June 2013 at 10:09:39 UTC, Jonathan M Davis wrote: On Sunday, June 23, 2013 12:02:42 Namespace wrote: > I don't see what's so terrible about it It's bug prone. class Foo { public: static void test1() { } void test2() { } } Foo f; f.test1(); /// Oh nice, that works, f is not null. f.test2(); /// WTF? f is null? I fail to see what's bug-prone about that. It's confusing, but it's not causing any bugs. Also I don't know why I should call static methods from an instance. What's the purpose? It's stupid and pointless as far as I can tell, but I believe that C++, Java, C#, and D all do it, so as stupid as it is, it's a common stupidity. I certainly wish that we could change it, but I wouldn't expect Walter to agree to the change, since it would break at least some existing code, and I suspect that he doesn't consider the fact that you can call static functions on instances to be a problem. That's not the sort of thing that he generally seems to think is an issue. It's almost always stuff that causes actual bugs that he agrees to change and not things that are aesthetically displeasing or which could theoretically cause bugs. - Jonathan M Davis C++ doesn't allow it. I don't know about the rest. If anything, I find overloading static non static could make sense: A.print(); //"I'm an A!" a.print(); //"I'm an A called foo!" With this in mind, it can mean that a struct can first define the static function, and in the future, add extra logic to handle information from a specific instance, yet without having to caller code.
Re: Can call static method with null reference
On Sunday, June 23, 2013 12:48:15 monarch_dodra wrote: > C++ doesn't allow it. I don't know about the rest. Yes it does. I just tested it. This code compiles and runs just fine #include using namespace std; class C { public: static void foo() { cout << "I'm static!" << endl; } }; int main() { C c; c.foo(); return 0; } And just like D, C++ won't allow you to overload on static (also just tested), so D's behavior in this regard appears to be identical to C++. - Jonathan M Davis
InstanceOf
I'm trying to create a fairly generic component system, where an object iterates over a bunch of other objects that all implement a certain interface. And this all works fine, however, I would also like to be able to get objects of a specific type (a la instanceOf), and I can't figure out how to do it. Could anyone help me out? [code] interface I { void update(); void write(); } class A : I { int n; void update() { n++; } void write() { writeln(n); } } class B : I { int m; void update() { m--; } void write() { writeln(m); } } class C { I[] array; void addElem(I elem) { array ~= elem; } void loop() { foreach(elem; array) elem.update(); } void writeAll() { foreach(elem; array) elem.write(); } void writeB() { // Only call .write on B's // How do I get the B's from the array of I's? } } void main() { C c = new C(); c.addElem(new A()); c.addElem(new B()); c.loop(); c.writeAll(); c.writeB(); // This is the problem } [/code]
Re: InstanceOf
On 06/23/13 13:04, Lemonfiend wrote: > void writeAll() > { > foreach(elem; array) > elem.write(); > } > > void writeB() > { > // Only call .write on B's > // How do I get the B's from the array of I's? > } void writeB() { foreach(elem; array) if (auto b = cast(B)elem) b.write(); } artur
Re: InstanceOf
On Sunday, 23 June 2013 at 11:04:59 UTC, Lemonfiend wrote: ... void writeAll() { foreach(elem; array) elem.write(); } void writeB() { // Only call .write on B's // How do I get the B's from the array of I's? } http://dlang.org/expression.html#CastExpression So, this should do it: void writeB() { foreach(elem; array) if(cast(B) elem) elem.write(); } You can also do some things like this, if you want to use something specific to Bs: if(auto b = cast(B) elem) b.bSpecificMethod();
Re: InstanceOf
On Sunday, 23 June 2013 at 11:04:59 UTC, Lemonfiend wrote: I'm trying to create a fairly generic component system, where an object iterates over a bunch of other objects that all implement a certain interface. And this all works fine, however, I would also like to be able to get objects of a specific type (a la instanceOf), and I can't figure out how to do it. Could anyone help me out? [code] interface I { void update(); void write(); } class A : I { int n; void update() { n++; } void write() { writeln(n); } } class B : I { int m; void update() { m--; } void write() { writeln(m); } } class C { I[] array; void addElem(I elem) { array ~= elem; } void loop() { foreach(elem; array) elem.update(); } void writeAll() { foreach(elem; array) elem.write(); } void writeB() { // Only call .write on B's // How do I get the B's from the array of I's? } } void main() { C c = new C(); c.addElem(new A()); c.addElem(new B()); c.loop(); c.writeAll(); c.writeB(); // This is the problem } [/code] foreach (I i; array) { if (B b = cast(B) i) { ... } }
Re: alias c=mixin(expr); disallowed, why?
On 06/23/2013 12:19 PM, Artur Skawina wrote: On 06/22/13 21:52, Timothee Cour wrote: Is there a reason the language spec disallows this? void main(){ auto a=mixin("1");//OK alias b=a;//OK mixin("alias c=a;");//OK // alias c=mixin("a");//NG : Error: basic type expected, not mixin } How would that be different from "auto c=mixin("a");"? It's probably clear, but that error message is misleading, so i'll say it anyway - the reason why your 'alias' line does not work is because alias requires a symbol, but 'mixin()' is an expression. Special-casing mixin-expressions (so that they propagate the symbol when that is possible would be a bad idea); the other possibility is to allow aliasing /expressions/. But that's a bad idea too, and would likely not do what you expect it to do. A mixin-less version could be made to work, but there are already other ways to get the same effect. Hence the above question. artur mixin template T(alias x){ } void foo(){ import std.stdio; writeln("foo"); } void main(){ auto a=mixin("1"); mixin T!a; // ok mixin T!(mixin("a")); // ok mixin T!1; // ok (!) mixin T!(mixin("foo")); // ok (no implicit call) }
Re: alias c=mixin(expr); disallowed, why?
On 06/23/2013 11:32 AM, Jacob Carlborg wrote: On 2013-06-22 23:47, Timon Gehr wrote: No, it is arbitrary. I think the spec says you can only mixin whole expression. That only means you cannot do things like eg: mixin("a*"); mixin("b"); but instead you need to do: mixin("a*b"); such that the string content forms a valid expression according to the grammar. But for some reason you can use a mixin in a __traits expression without having the whole expression in a mixin. Example?
Re: InstanceOf
foreach (I i; array) { if (B b = cast(B) i) { ... } } Thanks all 3 of you for the quick and identical answers. :) It had not occurred to me to use a cast for this, but indeed the language ref says the same: "In order to determine if an object o is an instance of a class B use a cast" It does a bit inelegant to me.. Or are casts simply extremely cheap?
Re: InstanceOf
On 06/23/2013 01:26 PM, Lemonfiend wrote: foreach (I i; array) { if (B b = cast(B) i) { ... } } Thanks all 3 of you for the quick and identical answers. :) It had not occurred to me to use a cast for this, but indeed the language ref says the same: "In order to determine if an object o is an instance of a class B use a cast" It does a bit inelegant to me.. Or are casts simply extremely cheap? Casts are as cheap as testing whether an object is an instance of a certain class. Having the cast evaluate to a nullable reference is certainly more elegant than having instanceof and cast as separate constructs, where the cast may throw.
Re: Can call static method with null reference
On Sunday, 23 June 2013 at 10:59:06 UTC, Jonathan M Davis wrote: On Sunday, June 23, 2013 12:48:15 monarch_dodra wrote: C++ doesn't allow it. I don't know about the rest. Yes it does. - Jonathan M Davis Oh. Wow. That's news to me actually. I thought I new everything about C++ ^^
Re: Good Candy Doc Forks?
Am 23.06.2013 11:47, schrieb Michal Minich: > Does anybody know some good looking or with good features? > > btw, I'm wondering why is some basic version of Candy Doc bundled with DMD. > > Thanks. There is cuteDoc: https://github.com/JakobOvrum/cuteDoc - But it seems like Robik deleted his repo... And there is bootDoc: https://github.com/JakobOvrum/bootDoc (which requires JS)
Re: alias c=mixin(expr); disallowed, why?
On 06/23/13 13:23, Timon Gehr wrote: > On 06/23/2013 12:19 PM, Artur Skawina wrote: >> On 06/22/13 21:52, Timothee Cour wrote: >>> Is there a reason the language spec disallows this? >>> >>> >>> void main(){ >>> auto a=mixin("1");//OK >>> alias b=a;//OK >>> mixin("alias c=a;");//OK >>> // alias c=mixin("a");//NG : Error: basic type expected, not mixin >>> } >> >> How would that be different from "auto c=mixin("a");"? >> >> It's probably clear, but that error message is misleading, so i'll say >> it anyway - the reason why your 'alias' line does not work is because >> alias requires a symbol, but 'mixin()' is an expression. >> Special-casing mixin-expressions (so that they propagate the symbol when >> that is possible would be a bad idea); the other possibility is to allow >> aliasing /expressions/. But that's a bad idea too, and would likely not >> do what you expect it to do. A mixin-less version could be made to work, >> but there are already other ways to get the same effect. >> Hence the above question. > > mixin template T(alias x){ } > > void foo(){ import std.stdio; writeln("foo"); } > > void main(){ > auto a=mixin("1"); > mixin T!a; // ok > mixin T!(mixin("a")); // ok > mixin T!1; // ok (!) > mixin T!(mixin("foo")); // ok (no implicit call) > } Yes, template parms and literals are special (literals are useful as template parms, obviously). What would be the arguments for allowing these two: > mixin T!(mixin("a")); // ok > mixin T!(mixin("foo")); // ok (no implicit call) ? I didn't realize they were currently accepted. Is this actually documented somewhere? The fact that `mixin("foo")` and `mixin("foo+1")` mean subtly different things when used as a template parameter is a problem. artur
Re: Problem with object understanding and datatypes
Is this code available in any repo/archive somewhere? /Per
Range analysis result printing?
I am thinking about opening an enhancement request, but this time I first prefer to ask your opinion here. For this code: void main() { ubyte x; ubyte y = x << 1; } The range analysis determines that it's conceivable to the result of that expression to not fit in y, so the D compiler 2.064alpha gives: temp.d(3): Error: cannot implicitly convert expression (cast(int)x << 1) of type int to ubyte To help the programmer understand faster the mistake in his/her code when expressions become more complex I think it's also useful to print the range resulting from the analysis, like: temp.d(3): Error: cannot implicitly convert expression (cast(int)x << 1) in interval [0 ... 510] of type int to ubyte It uses 3 dots because it's an interval that includes the right end. Otherwise if you print an interval open on the right in a case like this you have to print a ulong.max+1 value: void main() { ulong x; int y = x; } Do you like? Bye, bearophile
Re: Can call static method with null reference
On 2013-06-23 12:04, Jonathan M Davis wrote: I would have thought that that was obvious, and I fail to see why that would be a problem. The only risk I see in allowing static and non-static functions to be overloaded, is that if you have static function being called with an instance, and you add a non-static overload, then the code would silently change to call the non-static function. But we have that exact same problem with UFCS and member functions as it is, and that wouldn't break any existing code (since you can't overload on static right now). It would just be a future risk of breaking code. That's true, I didn't think of that. -- /Jacob Carlborg
Re: alias c=mixin(expr); disallowed, why?
On 2013-06-23 13:27, Timon Gehr wrote: Example? @(3) int a; alias Tuple!(__traits(getAttributes, mixin("a"))) attrs; -- /Jacob Carlborg
Re: InstanceOf
On 2013-06-23 13:26, Lemonfiend wrote: foreach (I i; array) { if (B b = cast(B) i) { ... } } Thanks all 3 of you for the quick and identical answers. :) It had not occurred to me to use a cast for this, but indeed the language ref says the same: "In order to determine if an object o is an instance of a class B use a cast" It does a bit inelegant to me.. Or are casts simply extremely cheap? You can do something like this as well: if (i.classinfo is B.classinfo) { } But doing the cast is more efficient if you want to use the object of as the type you're checking for. You can also hide the cast in a function if you want to be a bit more clear of the intent: T instanceOf (T) (Object value) { return cast(T) value); } if (i.instanceOf!(B)) { } -- /Jacob Carlborg
Re: InstanceOf
On Sunday, 23 June 2013 at 15:15:16 UTC, Jacob Carlborg wrote: On 2013-06-23 13:26, Lemonfiend wrote: foreach (I i; array) { if (B b = cast(B) i) { ... } } Thanks all 3 of you for the quick and identical answers. :) It had not occurred to me to use a cast for this, but indeed the language ref says the same: "In order to determine if an object o is an instance of a class B use a cast" It does a bit inelegant to me.. Or are casts simply extremely cheap? You can do something like this as well: if (i.classinfo is B.classinfo) { } But doing the cast is more efficient if you want to use the object of as the type you're checking for. Using the .classinfo is what I looked at before asking here. However, according to the specs: ".classinfo applied to an interface gives the information for the interface, not the class it might be an instance of." So the i.classinfo and B.classinfo would be different? You can also hide the cast in a function if you want to be a bit more clear of the intent: T instanceOf (T) (Object value) { return cast(T) value); } if (i.instanceOf!(B)) { } This is indeed what I did :)
Re: InstanceOf
On 2013-06-23 17:29, Lemonfiend wrote: Using the .classinfo is what I looked at before asking here. However, according to the specs: ".classinfo applied to an interface gives the information for the interface, not the class it might be an instance of." So the i.classinfo and B.classinfo would be different? That might be the case, didn't think of that. In that case you need casts anyway. -- /Jacob Carlborg
Re: A little of coordination for Rosettacode
Adam D. Ruppe: code: http://arsdnet.net/dcode/rpc-example.d library: https://github.com/adamdruppe/misc-stuff-including-D-programming-language-web-stuff/blob/master/rpc.d It's online: http://rosettacode.org/wiki/Distributed_programming#D Bye, bearophile
Re: Can call static method with null reference
On Sunday, June 23, 2013 13:35:55 monarch_dodra wrote: > On Sunday, 23 June 2013 at 10:59:06 UTC, Jonathan M Davis wrote: > > On Sunday, June 23, 2013 12:48:15 monarch_dodra wrote: > >> C++ doesn't allow it. I don't know about the rest. > > > > Yes it does. > > > > - Jonathan M Davis > > Oh. Wow. That's news to me actually. I thought I new everything > about C++ ^^ LOL. I know a lot about C++ and _try_ to know it all, but C++ is just way too complicated for that (at least for me). Even if I learn all of the stray esoteric stuff, I can't retain it all. There's just too much of it. With D, I feel like I _might_ be able to do it. I definitely don't know everything that there is to know about D, and I don't always remember all of the little details that I learn (plus some of them change over time), but I do a much better job of remembering it. It doesn't have anywhere near as many dark corners to it, and so in spite of its complexity, it at least feels like it could all be understood and remembered by one person (unlike C++). So, _maybe_ someday I'll be able to claim that I know the D language through and through, but I'll definitely _never_ be able to claim that with C++. - Jonathan M Davis
Re: Range analysis result printing?
On Sunday, June 23, 2013 16:20:51 bearophile wrote: > It uses 3 dots because it's an interval that includes the right > end. The way that you normally indicate exclusive and inclusive intervals in math is ) vs ], where ) is exclusive and ] is inclusive. Some folks will understand that. I don't think that anyone will understand that ... says anything about whether the end is inclusive or exclusive - not unless that's commonly used somewhere else that I'm not familiar with. - Jonathan M Davis
Re: Range analysis result printing?
Jonathan M Davis: The way that you normally indicate exclusive and inclusive intervals in math is ) vs ], where ) is exclusive and ] is inclusive. Some folks will understand that. I don't think that anyone will understand that ... says anything about whether the end is inclusive or exclusive - not unless that's commonly used somewhere else that I'm not familiar with. I agree that such mathematical syntaxes are more commonly known than the ... syntax that is used in Perl and I think Ruby and few other languages. In other nations mathematicians use [x, y[ to represent open or close intervals (that syntax is used in std.random too). So maybe instead of (in interval x ... y) it's better to use (in interval [x, y]) and hope people will understand this doesn't follow the normal D/Python usage of closed-on-the-right intervals. I have added a note in the ER: http://d.puremagic.com/issues/show_bug.cgi?id=10455 Bye, bearophile
indexing a tuple containing a struct strange result
What is going on here? import std.stdio, std.typecons; struct S { int x; Tuple!(S) foo() { return tuple(this); } } void main() { S s; s.x = 8; writeln((s.foo())); //output: Tuple!(S)(S(8)) writeln((s.foo())[0]); //output: S(0) }
Re: indexing a tuple containing a struct strange result
On Monday, 24 June 2013 at 01:22:12 UTC, cal wrote: What is going on here? import std.stdio, std.typecons; struct S { int x; Tuple!(S) foo() { return tuple(this); } } void main() { S s; s.x = 8; writeln((s.foo())); //output: Tuple!(S)(S(8)) writeln((s.foo())[0]); //output: S(0) } import std.stdio, std.typecons; struct S { int x; int y; int z; auto foo() { return tuple(this.tupleof); } } void main() { S s; s.x = 8; s.y = 9; s.z = 10; writeln((s.foo())); //output: Tuple!(int, int, int)(8, 9, 10) writeln(s.foo()[2]); //output: 10 } Is this what you expected? I would explain what's going on but I'd be wrong.
Re: Ping qznc: Re: A little of coordination for Rosettacode
On Saturday, 22 June 2013 at 21:27:01 UTC, bearophile wrote: Ali Çehreli: The code compiles under 32-bit (e.g. with the -m32 compiler switch) where size_t is an alias of uint. Thanks, Ali! I'm always compiling on 64 bit systems; I'll add the 32 bit switch to my diagnostic approach now. Oh, I see. I compile most of the code on a 32 bit system. I asked Walter to warn d programmers against such mistakes, and Walter closed it down. Someone else has opened the ER again... In general, I think implicit conversions of any kind are a misfeature, but better error messages would be enough for me here. At least in Scala, you need to bring the conversion into scope yourself, or have it accidentally imported... Thanks for your help. -- Brian
Re: indexing a tuple containing a struct strange result
On 06/23/2013 09:40 PM, Anthony Goins wrote: > On Monday, 24 June 2013 at 01:22:12 UTC, cal wrote: >> Tuple!(S) foo() { return tuple(this); } > import std.stdio, std.typecons; > > struct S > { > int x; > int y; > int z; > > auto foo() { return tuple(this.tupleof); } > } > > void main() > { > S s; > s.x = 8; > s.y = 9; > s.z = 10; > writeln((s.foo())); //output: Tuple!(int, int, int)(8, 9, 10) > > writeln(s.foo()[2]); //output: 10 > } > > Is this what you expected? I think the OP is asking about the difference from when foo() is a non-member function: import std.stdio, std.typecons; struct S { int x; } Tuple!(S) foo(S s) { return tuple(s); } void main() { S s; s.x = 8; writeln((s.foo())); //output: Tuple!(S)(S(8)) writeln((s.foo())[0]); //output: S(8) } This time the output is S(8). I think it is a compiler bug. Ali
Re: indexing a tuple containing a struct strange result
On 06/23/2013 10:07 PM, Ali Çehreli wrote: > I think it is a compiler bug. Make that a Phobos bug. :) The following is a reduced program that exhibits the problem. The presence or absence of the unused member function makes a difference: import std.typecons; struct S { int x; // Bizarre: Comment-out this function to pass the assert in main. Tuple!(S) unused() { return tuple(S(7)); } } void main() { auto s = S(8); assert(tuple(s).expand[0] == S(8)); } Ali
Re: indexing a tuple containing a struct strange result
On Monday, 24 June 2013 at 05:31:29 UTC, Ali Çehreli wrote: On 06/23/2013 10:07 PM, Ali Çehreli wrote: > I think it is a compiler bug. Make that a Phobos bug. :) The following is a reduced program that exhibits the problem. The presence or absence of the unused member function makes a difference: import std.typecons; struct S { int x; // Bizarre: Comment-out this function to pass the assert in main. Tuple!(S) unused() { return tuple(S(7)); } } void main() { auto s = S(8); assert(tuple(s).expand[0] == S(8)); } Ali Actually I hadn't tried with free functions, but this test captures my problem. I'll file it now. Thanks!