Re: Overload of ! operator
On Wednesday, 26 June 2013 at 05:29:49 UTC, Jonathan M Davis wrote: 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 Yeah, basically, you define: * opCast(bool) //to test both true and false * opEqual //test equality (both == and !=) * opCmp //Comparison ( = =) And everything gets defined from these. It also works that way for operators: op++ is defined in terms or ++op. And if you define op+, then defining op++ becomes entirely optional! This is a cool feature, although there are those *very* rare cases where it gets in your way. For example, the other day, I was trying to implement a tribool: http://www.boost.org/doc/libs/1_53_0/doc/html/tribool/tutorial.html It did not work, I mean: AT ALL! This is because for a tribool, being not true does not imply being false...
Re: mutable constant?
On Tuesday, 25 June 2013 at 23:39:45 UTC, Ali Çehreli wrote: 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 This is no real code. Just a test example to check. ;)
Bug search: derelict3 and scope(exit)
Since I had a problem by using derelict3 (more precise: I get an Access Violation), Mike Parker and I were looking for the problem. Today Mike Parker figured out that it happens only if scope(exit) is used in combination with glPopAttrib. But because we have not much experience in reading assembly, and I (and maybe he also) have no good debugger, I like to ask for help to find and reduce the bug. The regarding post with the example code is here: http://dblog.aldacron.net/forum/index.php?topic=832.msg1011#msg1011 If you write the scope(exit) glPopAttrib(mask); without the scope statement and move it to the end of the function everything works fine. But IMO it should work also with scope(exit). Thoughts?
Re: Bug search: derelict3 and scope(exit)
Second workaround so far: Use something like that: scope(exit) glAvoidAE(glPopAttrib(mask)); with void glAvoidAE(lazy void Func) { Func(); } That's strange.
Re: Bug search: derelict3 and scope(exit)
On Wednesday, 26 June 2013 at 07:55:29 UTC, Namespace wrote: Today Mike Parker figured out that it happens only if scope(exit) is used in combination with glPopAttrib. But That's not exactly what I was getting at. The problem isn't with scope(exit) or, I believe, glPopAttrib. It just so happens that the way your test case was set up, that particular line was the last to be executed before going back up the callstack to exit the app. Adding a writeln statement within that scope(exit) block caused the access violation to appear somewhere else (which happened to also be a scope(exit) glPopAttrib in another function). Adding a writeln there shifted it into the Windows kernel. This is a classic sign of a memory corruption bug.
Re: mutable constant?
On Wednesday, 26 June 2013 at 07:35:08 UTC, Namespace wrote: On Tuesday, 25 June 2013 at 23:39:45 UTC, Ali Çehreli wrote: 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 This is no real code. Just a test example to check. ;) It seems safe, however, your example seems to show how to indeed break the type system... without a cast (!): @property Point* ptr() inout { points[this.id].x = cast(int) this.x; points[this.id].y = cast(int) this.y; return points[this.id]; } void main() { immutable TplPoint!float my = TplPoint!float(42, 23); Point* p = my.ptr; //Oops! mutable point! } Disturbing... this(T x, T y) { this.x = x; this.y = y; points ~= this._point; I'd careful with this, you can easily end up with pointers to destroyed temporaries...
Re: eof
On Wednesday, 26 June 2013 at 04:46:32 UTC, Ali Çehreli wrote: 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 Hi,Ali,I tried those codes,it doesn't work under win7.The result is done again will follow done,without giving me any chance to input. lx
Re: eof
On Wednesday, 26 June 2013 at 13:45:41 UTC, lx wrote: On Wednesday, 26 June 2013 at 04:46:32 UTC, Ali Çehreli wrote: 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 Hi,Ali,I tried those codes,it doesn't work under win7.The result is done again will follow done,without giving me any chance to input again after I enter ctrl-z . lx
Re: mutable constant?
On Wednesday, June 26, 2013 13:16:16 monarch_dodra wrote: It seems safe, however, your example seems to show how to indeed break the type system... without a cast (!): @property Point* ptr() inout { points[this.id].x = cast(int) this.x; points[this.id].y = cast(int) this.y; return points[this.id]; } void main() { immutable TplPoint!float my = TplPoint!float(42, 23); Point* p = my.ptr; //Oops! mutable point! } Disturbing... It doesn't break anything. It just shows the need for pure. - Jonathan M Davis
Re: mutable constant?
On Wednesday, 26 June 2013 at 15:48:42 UTC, Jonathan M Davis wrote: It doesn't break anything. It just shows the need for pure. - Jonathan M Davis OO I just got it :( nevermind then...
How would you solve this 'interview' question in D?
Just for a bit of fun, I saw this question posted on reddit the other day and wondered how *you* would solve this in D? http://stackoverflow.com/questions/731832/interview-question-ffn-n
Re: How would you solve this 'interview' question in D?
The text from the question: Design a function f, such that: f(f(n)) == -n Where n is a 32 bit signed integer; you can't use complex numbers arithmetic. If you can't design such a function for the whole range of numbers, design it for the largest range possible.
Re: How would you solve this 'interview' question in D?
On Wednesday, 26 June 2013 at 20:51:35 UTC, Gary Willoughby wrote: Just for a bit of fun, I saw this question posted on reddit the other day and wondered how *you* would solve this in D? Since they didn't say *pure* function, I'd cheat: int f(int n) { static bool isOddCall; isOddCall = !isOddCall; if(!isOddCall) return -n; return n; } :P
Re: How would you solve this 'interview' question in D?
On Wednesday, 26 June 2013 at 20:51:35 UTC, Gary Willoughby wrote: Just for a bit of fun, I saw this question posted on reddit the other day and wondered how *you* would solve this in D? http://stackoverflow.com/questions/731832/interview-question-ffn-n First answer port: http://dpaste.dzfl.pl/0e3d145c
Re: How would you solve this 'interview' question in D?
Am Wed, 26 Jun 2013 22:52:17 +0200 schrieb Gary Willoughby d...@kalekold.net: The text from the question: Design a function f, such that: f(f(n)) == -n Where n is a 32 bit signed integer; you can't use complex numbers arithmetic. If you can't design such a function for the whole range of numbers, design it for the largest range possible. Well some good answers are given that would work in D, too. I like how this question turns out the nature of the person much more than their general programming skill. Some options: o downvote the question and close the tab o face it with humor (e.g. throw NotImplementedException(You get the rest of the code when you give me the job)) o get dirty and hack around the issue, by actually having two 'f's (by means of C preprocessor abuse, or C++ overloads) o be the pragmatic Python programmer: no overflows, no problems o adhere strictly to the problem description and give multiple solutions that do or don't handle 0 or -2^31. Anyway I've yet to see a solution that works for all input ;) -- Marco
Re: How would you solve this 'interview' question in D?
Anyway I've yet to see a solution that works for all input ;) Scratch that. -- Marco
Re: How would you solve this 'interview' question in D?
Am 26.06.2013 22:51, schrieb Gary Willoughby: Just for a bit of fun, I saw this question posted on reddit the other day and wondered how *you* would solve this in D? http://stackoverflow.com/questions/731832/interview-question-ffn-n I solved it ;) http://dpaste.dzfl.pl/5cd56e9d
Re: How would you solve this 'interview' question in D?
On 6/26/13, Gary Willoughby d...@kalekold.net wrote: Just for a bit of fun, I saw this question posted on reddit the other day and wondered how *you* would solve this in D? http://stackoverflow.com/questions/731832/interview-question-ffn-n Silly mathematicians, nobody said you had to make it performant. import std.conv; import std.string; import std.stdio; auto f(T)(T n) { static struct S { int n; } static if (is(T == int)) return S(n); else return to!int(- ~ n.n.to!string.chompPrefix(-)); } void main() { foreach (i; int.min .. int.max) { writefln(%s = %s, i, i.f.f); } }
Re: How would you solve this 'interview' question in D?
On Wednesday, 26 June 2013 at 22:43:05 UTC, David wrote: Am 26.06.2013 22:51, schrieb Gary Willoughby: Just for a bit of fun, I saw this question posted on reddit the other day and wondered how *you* would solve this in D? http://stackoverflow.com/questions/731832/interview-question-ffn-n I solved it ;) http://dpaste.dzfl.pl/5cd56e9d Let's keep it simple: int f(uint n) { return n; } uint f(int n) { return -n; }
Re: How would you solve this 'interview' question in D?
On Thu, Jun 27, 2013 at 12:43:04AM +0200, David wrote: Am 26.06.2013 22:51, schrieb Gary Willoughby: Just for a bit of fun, I saw this question posted on reddit the other day and wondered how *you* would solve this in D? http://stackoverflow.com/questions/731832/interview-question-ffn-n I solved it ;) http://dpaste.dzfl.pl/5cd56e9d [...] Well, technically it's invalid because it says design *a* function f. But maybe it can be salvaged: auto f(T)(T n) { static if (is(T==int)) return cast(double)n; else if (is(T==double)) return -cast(int)n; else static assert(0); } Well, it's still cheating, though. :-P I think the 4-cycle algorithm is probably still the best one I've seen. A more interesting interview question, IMO, would be to design a function of the form: bool f(void delegate(int) dg, int n); which returns true if dg(n) returns, and false otherwise. :-P T -- Three out of two people have difficulties with fractions. -- Dirk Eddelbuettel
Re: mutable constant?
On Wednesday, 26 June 2013 at 15:48:42 UTC, Jonathan M Davis wrote: It doesn't break anything. It just shows the need for pure. Really? In the following simplified code I see mutation of an immutable variable, which should not be possible, of course. That is breaking the type system, no? What am I missing? import std.stdio; int* point; struct TplPoint { int _point; this(int x) { _point = x; point = _point; } } void main() { immutable TplPoint my = TplPoint(42); writeln(my._point); // 42 *point = 13; // uh-oh writeln(my._point); // 13 !!! }
Re: How would you solve this 'interview' question in D?
On 6/27/13, H. S. Teoh hst...@quickfur.ath.cx wrote: Well, it's still cheating, though. :-P I think the 4-cycle algorithm is probably still the best one I've seen. What I don't understand is why the CPU is so slow that it takes ages to go through int.min .. int.max in a loop.
Re: How would you solve this 'interview' question in D?
On Wednesday, 26 June 2013 at 22:43:05 UTC, David wrote: Am 26.06.2013 22:51, schrieb Gary Willoughby: I solved it ;) http://dpaste.dzfl.pl/5cd56e9d Yes, but maybe the interviewer is waiting just one function, since the question was: Design a function f. So I rewrote your example: import std.stdio; import std.string; auto f(T)(T n){ if(is(T==float)) return cast(int)n; return cast(float)-n; } void main() { foreach(n; int.min..int.max) { assert(f(f(n)) == -n); } } Again, in the same way, maybe the interviewer want n as 32 signed int not a auto/template etc. :D
Re: How would you solve this 'interview' question in D?
On 6/27/13, Andrej Mitrovic andrej.mitrov...@gmail.com wrote: On 6/27/13, H. S. Teoh hst...@quickfur.ath.cx wrote: Well, it's still cheating, though. :-P I think the 4-cycle algorithm is probably still the best one I've seen. What I don't understand is why the CPU is so slow that it takes ages to go through int.min .. int.max in a loop. I mean this takes 31 seconds on my machine (obviously without optimization flags): - int f(int n) { return n; } void main() { foreach (n; int.min..int.max) f(f(n)); } - Maybe I need an upgrade.
Re: mutable constant?
On Thursday, June 27, 2013 01:45:22 anonymous wrote: On Wednesday, 26 June 2013 at 15:48:42 UTC, Jonathan M Davis wrote: It doesn't break anything. It just shows the need for pure. Really? In the following simplified code I see mutation of an immutable variable, which should not be possible, of course. That is breaking the type system, no? What am I missing? import std.stdio; int* point; struct TplPoint { int _point; this(int x) { _point = x; point = _point; } } void main() { immutable TplPoint my = TplPoint(42); writeln(my._point); // 42 *point = 13; // uh-oh writeln(my._point); // 13 !!! } It looks to me like your code is fundamentally different from the OP's example rather than being a simplification of the original code. In the OP's example, the variable being mutated is a module-level variable, so the immutability of the object is irrelevant when its member function is called (since it's not the object itself which is being mutated). It also has nothing to do with construction. Your example, on the other hand, is showing a bug with regards to constructing immutable objects in that the object doesn't actually become immutable until it's fully constructed, and the compiler isn't catching something which then violates the impending immutability. I _think_ that that bug has already been reported, but I can't find it at the moment. But regardless, your example is quite different from the OP's example. - Jonathan M Davis
Re: mutable constant?
On Thursday, 27 June 2013 at 00:53:48 UTC, Jonathan M Davis wrote: It looks to me like your code is fundamentally different from the OP's example rather than being a simplification of the original code. In the OP's example, the variable being mutated is a module-level variable, so the immutability of the object is irrelevant when its member function is called (since it's not the object itself which is being mutated). It also has nothing to do with construction. Your example, on the other hand, is showing a bug with regards to constructing immutable objects in that the object doesn't actually become immutable until it's fully constructed, and the compiler isn't catching something which then violates the impending immutability. I don't see the fundamental difference. In both versions: - An immutable struct instance is constructed. mine: immutable TplPoint my = TplPoint(42); OP: const TplPoint!float my = TplPoint!float(42, 23); Note that this does not set my._point to Point(42, 23). - The constructor stores a mutable pointer to its contents in module scope. mine: point = _point; OP: points ~= this._point; - Via that mutable pointer the data is altered. mine: *point = 13; OP: a bit more convoluted, TplPoint.ptr does the nasty work, but it could just as well be in main: points[someid].x = somevalue; = Immutability broken.
Re: mutable constant?
On Thursday, June 27, 2013 03:31:01 anonymous wrote: On Thursday, 27 June 2013 at 00:53:48 UTC, Jonathan M Davis wrote: It looks to me like your code is fundamentally different from the OP's example rather than being a simplification of the original code. In the OP's example, the variable being mutated is a module-level variable, so the immutability of the object is irrelevant when its member function is called (since it's not the object itself which is being mutated). It also has nothing to do with construction. Your example, on the other hand, is showing a bug with regards to constructing immutable objects in that the object doesn't actually become immutable until it's fully constructed, and the compiler isn't catching something which then violates the impending immutability. I don't see the fundamental difference. In both versions: - An immutable struct instance is constructed. mine: immutable TplPoint my = TplPoint(42); OP: const TplPoint!float my = TplPoint!float(42, 23); Note that this does not set my._point to Point(42, 23). - The constructor stores a mutable pointer to its contents in module scope. mine: point = _point; OP: points ~= this._point; - Via that mutable pointer the data is altered. mine: *point = 13; OP: a bit more convoluted, TplPoint.ptr does the nasty work, but it could just as well be in main: points[someid].x = somevalue; = Immutability broken. You're right. I didn't read over the OP's example carefully enough. The mutation is being done to a module-level variable in an inout function, which is completely legit. I thought that what the OP thought was wrong was mutating a module-level variable in a non-mutable function (and that's perfectly fine as long as it's not pure). What I missed (and you didn't) was the fact that that module-level variable was pointing to the contents of the object which was const. And that mutable pointer _is_ being obtained via the constructor just like in your example. And that is most definitely a compiler bug - the same one that your example shows. - Jonathan M Davis
Re: How would you solve this 'interview' question in D?
On Wednesday, 26 June 2013 at 20:51:35 UTC, Gary Willoughby wrote: Just for a bit of fun, I saw this question posted on reddit the other day and wondered how *you* would solve this in D? http://stackoverflow.com/questions/731832/interview-question-ffn-n Well, considering there is little to that specification: int f(int num) { import std.exception; static called = false; enforce(num != int.min); if(!called) { called = true; return num; } else { called = false; // Only for unittesting return -num; } } unittest { assert(f(f(3)) == -3); assert(f(f(-3)) == 3); assert(f(f(int.min+1)) == int.max); assert(f(f(int.max)) == int.min+1); } int having the issue that not all numbers are representable in both +/-.