Re: typeof map
On Tuesday, 25 June 2013 at 04:26:00 UTC, Timothee Cour wrote: I think it's because each lambda litteral is treated unique. can dmd be changed to recognize identical lambda litterals as identical? Is there any particular issue making that difficult? it already recognizes identical string literals as identical I could be wrong, but the difference might be that it *can* recognize string literals as idential, but it doesn't actually guarantee it as spec. This is not an issue for strings, but... Imagine I have a module, where I declare alias T = R!some_labda. Then in another module, I declare alias U = R!some_labda. Then in a third module, would I be able to declare a T, and store it inside a U ? Would the compiler be able to see that both lambdas are actually the same? I honestly don't know. But it seems dangerous to me: Lambdas specifically don't have names, and are unique. If you type two of them that have the same body, that shouldn't mean they are actually the same. Also, doing this would create symbol collisions, where a user has defined two different lambdas, that have the same body, but expected different definitions. EG: alias T = R!some_lambda; alias U = R!some_same_lambda void foo(T t); void foo(U u); //Nope, foo(U) already declared; What?
Re: Warning: explicit element-wise assignment (this.vector)[] = vec.vector[cast(ulong)0..cast(ulong)dimension]
Am 24.06.2013 22:50, schrieb bearophile: David: What kind of bugs does it avoid? I can't think of a single bug which could happen... (Ranges/Lengths are checked at runtime...) Some reasons: - Syntax uniformity: similar behaviours should look similar. This is a general rule of language design, that avoids troubles you don't even know. All array ops use [], so it's right for vector assignment to use them. - The second rule is that in a language as D we want to denote different code complexities with different code. This is the reason given in the Changelog, and it explains while length and walkLength have different names. In past you were not able to tell from a look at the syntax what's happening: void main() { int[][3] x; int[]y; int[]z; x[] = z; // copies just the z pointer y[] = z; // copies the elements in z } More details: http://d.puremagic.com/issues/show_bug.cgi?id=7444 Coming from this older: http://d.puremagic.com/issues/show_bug.cgi?id=3971 You are welcome, bearophile This really sucks... I guess I can workaround it with a static foreach and do an elementwise copy. Thanks for the explanation.
Re: Trouble with lockstep
On 6/25/13, Andrej Mitrovic andrej.mitrov...@gmail.com wrote: It's a regression which I've caused. I've made a fixup pull: http://d.puremagic.com/issues/show_bug.cgi?id=10468 I'm very sorry for this mishap. It's now fixed in git-head. Chances are we're not going to have another 2.063 point release (I'm only speculating) so you may have to use the latest git-head version to use lockstep.
Re: Problems building docs
On Monday, 24 June 2013 at 19:20:44 UTC, H. S. Teoh wrote: For me personally, I find that nesting dmd/druntime/phobos inside the git checkout of d-programming-language.org a tad ugly, so I use this instead: parent/d-programming-language.org parent/d-programming-language.org/web parent/dmd parent/druntime parent/phobos d-programming-language.org was changed to dlang.org, that is most likely the problem. No need for the web/ directory that will be created if everything else is placed correctly.
Re: Trouble with lockstep
On Tuesday, 25 June 2013 at 10:52:22 UTC, Andrej Mitrovic wrote: On 6/25/13, Andrej Mitrovic andrej.mitrov...@gmail.com wrote: It's now fixed in git-head. Chances are we're not going to have another 2.063 point release (I'm only speculating) so you may have to use the latest git-head version to use lockstep. That's a shame, I'd like to think there'd be a commitment to release regression fixes. Anyway, thanks for getting a fix made, and don't feel too guilty about the regression -- you're just pushing people towards the superior zip :-) Besides DMD, this fix needs to be propagated to GDC and LDC.
mutable constant?
I want to ask if this code should compile or if it's a bug, because I circumvent the const system: import std.stdio; struct Point { int x, y; } Point*[] points; struct TplPoint(T) { public: Point _point; T x, y; const uint id; this(T x, T y) { this.x = x; this.y = y; points ~= this._point; id = points.length - 1; } @property inout(Point)* ptr() inout { points[this.id].x = cast(int) this.x; points[this.id].y = cast(int) this.y; return cast(inout Point*) points[this.id]; } } void main() { const TplPoint!float my = TplPoint!float(42, 23); writeln(my._point, ::, my._point); writeln(*my.ptr, ::, my.ptr); } Or is the fact that it compiles ok and it's only unsafe?
Re: mutable constant?
On Wed, 26 Jun 2013 00:07:38 +0200, Namespace rswhi...@googlemail.com wrote: I want to ask if this code should compile or if it's a bug, because I circumvent the const system: import std.stdio; struct Point { int x, y; } Point*[] points; struct TplPoint(T) { public: Point _point; T x, y; const uint id; this(T x, T y) { this.x = x; this.y = y; points ~= this._point; id = points.length - 1; } @property inout(Point)* ptr() inout { points[this.id].x = cast(int) this.x; points[this.id].y = cast(int) this.y; return cast(inout Point*) points[this.id]; } } void main() { const TplPoint!float my = TplPoint!float(42, 23); writeln(my._point, ::, my._point); writeln(*my.ptr, ::, my.ptr); } Or is the fact that it compiles ok and it's only unsafe? This is perfectly fine. -- Simen
Re: mutable constant?
On Wednesday, June 26, 2013 00:07:38 Namespace wrote: I want to ask if this code should compile or if it's a bug, because I circumvent the const system: import std.stdio; struct Point { int x, y; } Point*[] points; struct TplPoint(T) { public: Point _point; T x, y; const uint id; this(T x, T y) { this.x = x; this.y = y; points ~= this._point; id = points.length - 1; } @property inout(Point)* ptr() inout { points[this.id].x = cast(int) this.x; points[this.id].y = cast(int) this.y; return cast(inout Point*) points[this.id]; } } void main() { const TplPoint!float my = TplPoint!float(42, 23); writeln(my._point, ::, my._point); writeln(*my.ptr, ::, my.ptr); } Or is the fact that it compiles ok and it's only unsafe? I could certainly be missing something here, but I don't understand what about the code you're even concerned about. Where in here would you be breaking the type system? I don't see any place in here where you're mutating a const variable or anything like that. The worst thing I see about the code is that it won't compile on 64-bit machines thanks to id = points.length - 1; - Jonathan M Davis
Re: mutable constant?
If you change uint to size_t it works fine AFAIK.
Re: mutable constant?
On Wednesday, June 26, 2013 00:52:58 Namespace wrote: If you change uint to size_t it works fine AFAIK. Yes. It's easy enough to fix, but it _is_ arguably a bug in the code, and it's the only one that's obvious to me. I don't understand what about the code makes you think that it might be violating the type system. - Jonathan M Davis P.S. Please always quote at least a portion of the post that you're replying to. Clients frequently do not manage to thread posts correctly, and it's not always clear which post a post is replying to if it doesn't quote any of its parent. In this particular case, based on what you said, I expect that you were replying to me, but it's threaded in my client as being a responsed to Simen. Also, not all posters even use a threaded view. So, relying on threading to make it clear which post you're replying to is not a good idea.
Re: mutable constant?
With apologies, I have unrelated comments to make. On 06/25/2013 03:07 PM, Namespace wrote: this(T x, T y) { this.x = x; this.y = y; points ~= this._point; I have seen similar designs in the past where constructors had side-effects such as registering the object in a global state. (Exactly what the last line is doing above.) It has almost always been cause of trouble. It is better to register an object from the outside after constructing it. Sometimes I had attempted to remove seemingly unused objects only to be reminded by a comment that it should not be: // Do not remove! Registers itself in the points array auto p = Point(); @property inout(Point)* ptr() inout { points[this.id].x = cast(int) this.x; points[this.id].y = cast(int) this.y; That looks questionable as well: ptr() looks like an accessor but it makes changes to a global state. Ali
Re: typeof map
On Tuesday, 25 June 2013 at 06:58:33 UTC, monarch_dodra wrote: On Tuesday, 25 June 2013 at 04:26:00 UTC, Timothee Cour wrote: I think it's because each lambda litteral is treated unique. can dmd be changed to recognize identical lambda litterals as identical? Is there any particular issue making that difficult? it already recognizes identical string literals as identical I could be wrong, but the difference might be that it *can* recognize string literals as idential, but it doesn't actually guarantee it as spec. This is not an issue for strings, but... I also thought it was to do with identical lambda literals being unique, and that the code should have compiled, but I've changed my mind after seeing your argument.
Overload of ! operator
Is there a way to overload the ! operator? I can't seem to get it to work with the standard unaryOp method. I need this because I am making a wrapper for a C++ API that has ! overloaded. -Eric
Re: Overload of ! operator
Eric: Is there a way to overload the ! operator? I can't seem to get it to work with the standard unaryOp method. I need this because I am making a wrapper for a C++ API that has ! overloaded. D is not a superset of C++ and I think there is no way to overload the ! alone. This is by design. But you can define a bang property method. Maybe other people can give you a better answer. Bye, bearophile
Re: Overload of ! operator
On Wednesday, June 26, 2013 04:50:44 Eric wrote: Is there a way to overload the ! operator? I can't seem to get it to work with the standard unaryOp method. I need this because I am making a wrapper for a C++ API that has ! overloaded. TDPL does not list it as an overloadable operator, so it probably can't be overloaded (especially if you've tried it, and it doesn't work). But you should be able to simply have a wrapper function which is a normal function rather than an overloaded operator. - Jonathan M Davis
Re: Overload of ! operator
On Wednesday, 26 June 2013 at 02:50:51 UTC, Eric wrote: Is there a way to overload the ! operator? I can't seem to get it to work with the standard unaryOp method. I need this because I am making a wrapper for a C++ API that has ! overloaded. -Eric According to http://dlang.org/operatoroverloading.html#Cast, the following are rewritten: if (e) = if (e.opCast!(bool)) if (!e) = if (!e.opCast!(bool)) So perhaps you need to override opCast!(bool).
Re: Overload of ! operator
On Wednesday, June 26, 2013 05:35:03 cal wrote: On Wednesday, 26 June 2013 at 02:50:51 UTC, Eric wrote: Is there a way to overload the ! operator? I can't seem to get it to work with the standard unaryOp method. I need this because I am making a wrapper for a C++ API that has ! overloaded. -Eric According to http://dlang.org/operatoroverloading.html#Cast, the following are rewritten: if (e) = if (e.opCast!(bool)) if (!e) = if (!e.opCast!(bool)) So perhaps you need to override opCast!(bool). Yeah, that should work for the conditions in if, while, and for loops but won't work for anything else (_maybe_ ternary operators, but I'm not sure). So, if you need to be able to do !obj in the general case, that's not going to work, but if you only need it for conditions, then it would. And of course this all assumes that the C++ code is overloading ! to do something sane with bool rather than redefining it to mean something completely different. - Jonathan M Davis
Re: Overload of ! operator
On 06/25/2013 09:05 PM, Jonathan M Davis wrote: On Wednesday, June 26, 2013 05:35:03 cal wrote: On Wednesday, 26 June 2013 at 02:50:51 UTC, Eric wrote: Is there a way to overload the ! operator? I can't seem to get it to work with the standard unaryOp method. I need this because I am making a wrapper for a C++ API that has ! overloaded. -Eric According to http://dlang.org/operatoroverloading.html#Cast, the following are rewritten: if (e) = if (e.opCast!(bool)) if (!e) = if (!e.opCast!(bool)) So perhaps you need to override opCast!(bool). Yeah, that should work for the conditions in if, while, and for loops but won't work for anything else (_maybe_ ternary operators, but I'm not sure). Works for ternary as well. The other option is 'alias this' but it is a little dangerous because bool is an arithmetic type. So, opCast would be better. import std.stdio; struct S { int i; bool truth() const { return i == 42; } alias truth this; } void foo(bool b) { writeln(b); } void main() { auto s = S(42); if (s){ } while (s) { break; } int i = s ? 4 : 5; foo(s); // What does it mean? writeln(s + 2); writeln(!s - 7); } So, if you need to be able to do !obj in the general case, that's not going to work It surprisingly works both with opCast and 'alias this'. Ali
Re: eof
On Monday, 24 June 2013 at 21:13:31 UTC, bearophile wrote: I am very confused that ctrl+z didn't teminate the input of console,it result in a dead loop. I think this is a library bug, I noticed it some times, but I didn't file it. Maybe it's worth filing in Bugzilla. I have added this bug report, is this the issue you are seeing/having? http://d.puremagic.com/issues/show_bug.cgi?id=10467 Bye, bearophile I read those information and yes,it is the issue I am having.I should have handled it in right way.Ctrl+z seems close the stream.So,if I want to input another batch of data,it became impossilbe.So,how to reopen the stream again to allow me to input another batch of data? And,another problem:if I input ctrl+c,the code will terminate abnormally.Why this happened? Thanks. lx
Re: eof
On 06/25/2013 09:26 PM, lx wrote: Ctrl+z seems close the stream.So,if I want to input another batch of data,it became impossilbe.So,how to reopen the stream again to allow me to input another batch of data? Making a copy of stdin works on Linux (where the stream is terminated by Ctrl-D in the console): import std.stdio; import std.algorithm; void main() { auto stdin_dup = stdin; stdin .byLine(KeepTerminator.yes) .copy(stdout.lockingTextWriter); writeln(done); stdin_dup .byLine(KeepTerminator.yes) .copy(stdout.lockingTextWriter); writeln(done again); } Ali
Re: Overload of ! operator
On Wednesday, 26 June 2013 at 04:16:30 UTC, Ali Çehreli wrote: On 06/25/2013 09:05 PM, Jonathan M Davis wrote: On Wednesday, June 26, 2013 05:35:03 cal wrote: On Wednesday, 26 June 2013 at 02:50:51 UTC, Eric wrote: Is there a way to overload the ! operator? I can't seem to get it to work with the standard unaryOp method. I need this because I am making a wrapper for a C++ API that has ! overloaded. -Eric According to http://dlang.org/operatoroverloading.html#Cast, the following are rewritten: if (e) = if (e.opCast!(bool)) if (!e) = if (!e.opCast!(bool)) So perhaps you need to override opCast!(bool). Yeah, that should work for the conditions in if, while, and for loops but won't work for anything else (_maybe_ ternary operators, but I'm not sure). Works for ternary as well. The other option is 'alias this' but it is a little dangerous because bool is an arithmetic type. So, opCast would be better. import std.stdio; struct S { int i; bool truth() const { return i == 42; } alias truth this; } void foo(bool b) { writeln(b); } void main() { auto s = S(42); if (s){ } while (s) { break; } int i = s ? 4 : 5; foo(s); // What does it mean? writeln(s + 2); writeln(!s - 7); } So, if you need to be able to do !obj in the general case, that's not going to work It surprisingly works both with opCast and 'alias this'. Ali Thanks for all the insignt. But I think I'm just going to fudge this one with a bang() method... Incidently, for this project I figured out an interesting use of alias. The C++ classes I am wrapping have a lot of virtual methods with all primitive arguments. So I create an D-interface for them, and wrap the rest with C methods. The wrapper class then makes methods that call the C methods, and then aliases the interface reference to this so that the wrapper class instance points to both the C++ native methods as well as the C-wrapped methods. -Eric
Re: Overload of ! operator
On Wednesday, 26 June 2013 at 04:06:05 UTC, Jonathan M Davis wrote: Yeah, that should work for the conditions in if, while, and for loops but won't work for anything else (_maybe_ ternary operators, but I'm not sure). So, if you need to be able to do !obj in the general case, that's not going to work ... import std.stdio; struct S { int x; bool opCast(T)() if (is(T == bool)) { return x == 0; } } void main() { auto s = S(1); auto b = !s; writeln(b); // true } Is this not supposed to work?
Re: Overload of ! operator
On Wednesday, June 26, 2013 06:59:14 cal wrote: On Wednesday, 26 June 2013 at 04:06:05 UTC, Jonathan M Davis wrote: Yeah, that should work for the conditions in if, while, and for loops but won't work for anything else (_maybe_ ternary operators, but I'm not sure). So, if you need to be able to do !obj in the general case, that's not going to work ... import std.stdio; struct S { int x; bool opCast(T)() if (is(T == bool)) { return x == 0; } } void main() { auto s = S(1); auto b = !s; writeln(b);// true } Is this not supposed to work? No, it's not. That would require an implicit cast (which requires using alias this). opCast gives you an explicit cast only. Where that becomes confusing is the fact that the compiler inserts explicitly casts to bool in conditions for if statements, loops, and the ternary operator. e.g. if(foo) {...} becomes if(cast(bool)foo) {...} So, if you've overloaded opCast to bool, then it'll get used in the conditions for if statements, loops, and the ternary operator. But no explicit cast is added just for putting ! in front of a variable. It works with something like if(!foo) {...} simply because that becomes if(!cast(bool)foo) {...} But nothing special is done for !, and !a will not call opCast. - Jonathan M Davis
Re: Overload of ! operator
On Wednesday, 26 June 2013 at 05:08:07 UTC, Jonathan M Davis wrote: On Wednesday, June 26, 2013 06:59:14 cal wrote: On Wednesday, 26 June 2013 at 04:06:05 UTC, Jonathan M Davis wrote: Yeah, that should work for the conditions in if, while, and for loops but won't work for anything else (_maybe_ ternary operators, but I'm not sure). So, if you need to be able to do !obj in the general case, that's not going to work ... import std.stdio; struct S { int x; bool opCast(T)() if (is(T == bool)) { return x == 0; } } void main() { auto s = S(1); auto b = !s; writeln(b); // true } Is this not supposed to work? No, it's not. That would require an implicit cast (which requires using alias this). opCast gives you an explicit cast only. Where that becomes confusing is the fact that the compiler inserts explicitly casts to bool in conditions for if statements, loops, and the ternary operator. e.g. if(foo) {...} becomes if(cast(bool)foo) {...} So, if you've overloaded opCast to bool, then it'll get used in the conditions for if statements, loops, and the ternary operator. But no explicit cast is added just for putting ! in front of a variable. It works with something like if(!foo) {...} simply because that becomes if(!cast(bool)foo) {...} But nothing special is done for !, and !a will not call opCast. - Jonathan M Davis But that code I posted does work, and gives the output shown. Am I misunderstanding?
Re: eof
On 06/25/2013 09:26 PM, lx wrote: I input ctrl+c,the code will terminate abnormally.Why this happened? Ctrl-C appears as SIGINT under POSIX systems. You need to register a handler for that signal: import std.stdio; import std.string; import core.sys.posix.signal; bool isDone = false; extern(C) void mySIGINThandler(int) nothrow @system { isDone = true; } void main() { signal(SIGINT, mySIGINThandler); while (true) { string line = chomp(readln()); if (stdin.eof() || isDone) { break; } else { writefln(Nice line: %s, line); } } } Ali
Re: Overload of ! operator
On Wednesday, 26 June 2013 at 04:59:19 UTC, cal wrote: On Wednesday, 26 June 2013 at 04:06:05 UTC, Jonathan M Davis wrote: Yeah, that should work for the conditions in if, while, and for loops but won't work for anything else (_maybe_ ternary operators, but I'm not sure). So, if you need to be able to do !obj in the general case, that's not going to work ... import std.stdio; struct S { int x; bool opCast(T)() if (is(T == bool)) { return x == 0; } } void main() { auto s = S(1); auto b = !s; writeln(b); // true } Is this not supposed to work? I should have also added that the overloaded ! method returns a class instance and not a bool. -Eric
Re: Overload of ! operator
On Wednesday, June 26, 2013 07:14:36 cal wrote: But that code I posted does work, and gives the output shown. Am I misunderstanding? Then my understanding of how ! is handled is wrong. Apparently !s does get replaced with !cast(bool)s, or it couldn't work. But note that bool b = s; doesn't work, so as I said, it's not the case that opCast gives you an implicit cast. It's just the cases where cases where the compiler inserts an explicit cast for you that it looks like it gives you an implicit cast. But apparently, there was a case that it inserts an explicit cast of which I was not aware. - Jonathan M Davis
Re: Overload of ! operator
On Wednesday, June 26, 2013 07:15:19 Eric wrote: I should have also added that the overloaded ! method returns a class instance and not a bool. Well, at that point, you're completely out of luck with regards to overloading !. In general, D doesn't really support overloading operators in a manner that doesn't match how the built-in types work. It does things like assume that , =, =, and will act the same way that they do with the built-in types and uses opCmp to extrapolate all of those operators. In some cases, you _can_ make overloaded operators return types that make it so that they don't function anything like the built-in types (e.g. opBinary with + could return a completely unrelated type that had nothing to do with the original type or with addition), but in pretty much any case where the compiler can get away with using the same overloaded operator for multiple operators, it does it. So, a number of decisions were made to better support correctness with types that actually try and overload operators to match what the built-in types do without caring about how that would affect types that would try and overload them to do unrelated stuff. - Jonathan M Davis