Re: Is this a bug in iota?
On Thursday, April 19, 2012 05:45:54 Brad Anderson wrote: Doing this same thing to a slice of an array does throw a Range Violation exception in release (and asserts in debug). That's impossible for a library to do. There is no way to version code on whether it's in release mode or not. Only the compiler controls that. So, you can use assertions, which will then be around in non-release mode but not release mode, but you can't do anything which will be around in non-release mode and not release mode. The closest thing is -debug, but that's _completely_ different. It just enables debug blocks. - Jonathan M Davis
Re: Cast Object - get null
Wow, many thanks for your trouble. Now it works as aspected. I only need T opCast(T)() const if(isImplicitlyConvertible!(typeof(this), T)) { return this; } to work. But if i try to cast to a const like this const Vector2s vs_ = cast(Vector2s)(vf); I get a long list of compiler errors. Thereby it's petty if i have only T opCast(T)() const if(isImplicitlyConvertible!(typeof(this), T)) { return this; } or additional the const variant const(T) opCast(T)() const if(isImplicitlyConvertible!(typeof(this), const T)) { return this; }
Re: Cast Object - get null
On Thursday, April 19, 2012 08:25:13 Namespace wrote: Wow, many thanks for your trouble. Now it works as aspected. I only need T opCast(T)() const if(isImplicitlyConvertible!(typeof(this), T)) { return this; } to work. But if i try to cast to a const like this const Vector2s vs_ = cast(Vector2s)(vf); I get a long list of compiler errors. Thereby it's petty if i have only T opCast(T)() const if(isImplicitlyConvertible!(typeof(this), T)) { return this; } or additional the const variant const(T) opCast(T)() const if(isImplicitlyConvertible!(typeof(this), const T)) { return this; } Well, if the function is const (which makes this const), since you're returning this, the return type must be const. It can only return non-const if the function isn't const. That's why I suggested having both overloads. - Jonathan M Davis
Re: Cast Object - get null
I must correct me: your solution works only with if (vs2 == Vector2s(vf)) { writeln(equal); } but not with if (vs2 == vf) { writeln(equal); }
Re: Cast Object - get null
On Thursday, 19 April 2012 at 06:56:21 UTC, Jonathan M Davis wrote: On Thursday, April 19, 2012 08:25:13 Namespace wrote: Wow, many thanks for your trouble. Now it works as aspected. I only need T opCast(T)() const if(isImplicitlyConvertible!(typeof(this), T)) { return this; } to work. But if i try to cast to a const like this const Vector2s vs_ = cast(Vector2s)(vf); I get a long list of compiler errors. Thereby it's petty if i have only T opCast(T)() const if(isImplicitlyConvertible!(typeof(this), T)) { return this; } or additional the const variant const(T) opCast(T)() const if(isImplicitlyConvertible!(typeof(this), const T)) { return this; } Well, if the function is const (which makes this const), since you're returning this, the return type must be const. It can only return non-const if the function isn't const. That's why I suggested having both overloads. - Jonathan M Davis Yeah, but const Vector2s vs_ = cast(Vector2s)(vf); don't work even with U opCast(U)() const if (is(Unqual!U == Vector2D!byte) || is(Unqual!U == Vector2D!ubyte) || is(Unqual!U == Vector2D!short) || is(Unqual!U == Vector2D!ushort) || is(Unqual!U == Vector2D!int) || is(Unqual!U == Vector2D!uint) || is(Unqual!U == Vector2D!long) || is(Unqual!U == Vector2D!ulong) || is(Unqual!U == Vector2D!float) || is(Unqual!U == Vector2D!double) || is(Unqual!U == Vector2D!real)) { return U(this.x, this.y); } T opCast(T)() if(isImplicitlyConvertible!(typeof(this), T)) { return this; } const(T) opCast(T)() const if(isImplicitlyConvertible!(typeof(this), const T)) { return this; }
Re: Cast Object - get null
On Thursday, April 19, 2012 09:01:15 Namespace wrote: Yeah, but const Vector2s vs_ = cast(Vector2s)(vf); don't work even with I don't know why it isn't working for you. It's working for me. You can look at the altered code here: http://codepad.org/C5Td5tVz I had to comment out the lines with Summe though, since there's no such function in the code that you gave. You should be able to compare the two versions with diff -w (assuming that you're on Linux - I don't know what the equivalent would be on Windows). But as far as I can tell based on your messages, what you have should work, so there's obviously a discrepancy or miscommunication somewhere. - Jonathan M Davis
Re: Is this a bug in iota?
On 04/18/2012 08:45 PM, Brad Anderson wrote: On Thursday, 19 April 2012 at 03:37:00 UTC, bearophile wrote: Brad Anderson: You can popFront() for as long as you want well passed the length. Obviously popping off the front of a zero length range isn't valid but I would have expected a range violation to occur rather than it to silently continuing the series with a wrapped around length. I agree. I think it is just an oversight in iota()'s general implementation because its floating point specialization does have an assert check in popFront(): import std.range; void main() { auto r = iota(1.0); // -- note 'double' type r.popFront(); r.popFront(); // -- assertion failure } I think it's a matter of design and it's a matter of having an alternative Phobos release that contains asserts too. Adding the test slows down something (iota) that must be as fast as possible. And currently asserts are removed from the compiled Phobos... Bye, bearophile Since iota is a template doesn't that mean it's not in phobos.lib but rather generated and built into my application? I'm not compiling in release mode so I would think any bounds checking it had would remain (I haven't yet looked at the source to see if there are any checks). I can definitely see stripping any bounds checking from a release build, of course. I think this warrants an enhancement request. Thank you. :) Doing this same thing to a slice of an array does throw a Range Violation exception in release (and asserts in debug). Regards, Brad Anderson Ali
Re: Is this a bug in iota?
Le 19/04/2012 05:36, bearophile a écrit : Brad Anderson: You can popFront() for as long as you want well passed the length. Obviously popping off the front of a zero length range isn't valid but I would have expected a range violation to occur rather than it to silently continuing the series with a wrapped around length. I think it's a matter of design and it's a matter of having an alternative Phobos release that contains asserts too. Adding the test slows down something (iota) that must be as fast as possible. And currently asserts are removed from the compiled Phobos... Bye, bearophile You've gotta be kidding. How can this NOT be a bug ? import std.range, std.stdio; void main() { auto r = iota(3); //writeln(isInfinite!r); assert(!isInfinite!(int[])); assert(isInfinite!(Repeat!(int))); //assert(isRandomAccessRange!i); writeln(r.front, , length: , r.length, empty ? , r.empty); r.popFront(); writeln(r.front, , length: , r.length, empty ? , r.empty); r.popFront(); writeln(r.front, , length: , r.length, empty ? , r.empty); r.popFront(); writeln(r.front, , length: , r.length, empty ? , r.empty); r.popFront(); writeln(r.front, , length: , r.length, empty ? , r.empty); r.popFront(); } Returns: 0, length: 3 empty ? false 1, length: 2 empty ? false 2, length: 1 empty ? false 3, length: 0 empty ? true 4, length: 4294967295 empty ? false
Access violation using chain()
Perhaps I'm just misunderstanding something about closures but the following code seems to behave oddly: import std.stdio, std.range, std.algorithm, std.string; void main() { auto lst = [a, b]; auto rng = range_gen(lst); writeln(rng.take(5)); } auto range_gen(string[] lst) { auto a = sequence!n+1().map!(a=format(%s%d, lst[0], a))(); return chain(lst, a); // access violation //return a; // works } Returning with the chain() gives an access violation after the writeln has processed the first two elements and gets to the elements generated by map(sequence()) (the output is '[a, b, '). If I just return the map(sequence()) it works correctly. If I don't use lst[0] in the map and instead use a literal it works without issue. It also works without issue if I use a global in place of lst[0]. I can work around this. Moving the chain() outside to the calling function seems to work fine but I was making using of ResultOf to type a member variable which is why I had the function in the first place (I can manually type it but it's pretty ugly). Regards, Brad Anderson
Re: Is this a bug in iota?
On Thursday, April 19, 2012 09:58:00 Somedude wrote: Le 19/04/2012 05:36, bearophile a écrit : Brad Anderson: You can popFront() for as long as you want well passed the length. Obviously popping off the front of a zero length range isn't valid but I would have expected a range violation to occur rather than it to silently continuing the series with a wrapped around length. I think it's a matter of design and it's a matter of having an alternative Phobos release that contains asserts too. Adding the test slows down something (iota) that must be as fast as possible. And currently asserts are removed from the compiled Phobos... Bye, bearophile You've gotta be kidding. How can this NOT be a bug ? import std.range, std.stdio; void main() { auto r = iota(3); //writeln(isInfinite!r); assert(!isInfinite!(int[])); assert(isInfinite!(Repeat!(int))); //assert(isRandomAccessRange!i); writeln(r.front, , length: , r.length, empty ? , r.empty); r.popFront(); writeln(r.front, , length: , r.length, empty ? , r.empty); r.popFront(); writeln(r.front, , length: , r.length, empty ? , r.empty); r.popFront(); writeln(r.front, , length: , r.length, empty ? , r.empty); r.popFront(); writeln(r.front, , length: , r.length, empty ? , r.empty); r.popFront(); } Returns: 0, length: 3 empty ? false 1, length: 2 empty ? false 2, length: 1 empty ? false 3, length: 0 empty ? true 4, length: 4294967295 empty ? false Having an assertion may be desirable, but the bug is in the usage of iota, not iota itself. At best, the assertion would help indicate that the caller has a bug. It's exactly the same as doing something like for(size_t i = 3; cond; --i) {} It's basic integer arithmetic. If you subtract from the minimum value that the integral type will hold, then its value will wrap around to the maximum. So, while adding an assertion would be desirable, I don't see how this could be considered a bug in iota. - Jonathan M Davis
Re: Is this a bug in iota?
Le 19/04/2012 10:07, Jonathan M Davis a écrit : Having an assertion may be desirable, but the bug is in the usage of iota, not iota itself. At best, the assertion would help indicate that the caller has a bug. It's exactly the same as doing something like for(size_t i = 3; cond; --i) {} It's basic integer arithmetic. If you subtract from the minimum value that the integral type will hold, then its value will wrap around to the maximum. So, while adding an assertion would be desirable, I don't see how this could be considered a bug in iota. - Jonathan M Davis I don't get it, for me iota has nothing to do with the problem, the problem is in the implementation of popfront(), which should check beforehand whether the range is empty, right ?
Re: tupleof.length of a class in a template return 0
Le 19/04/2012 05:04, Michaël Larouche michael.larou...@gmail.com a écrit : Reading the bug thread, I am wondering why my template worked in a struct but not inside a class. Anyway, I decided to move my mixin outside the struct/class and abuse UFCS instead. Now everything works like a charm :) Cool. Glad it helpted. :)
Re: Cast Object - get null
And which version do you use? I use DMD 2.059 on Windows 7. I get this compile error with your code object.Error: Access Violation 41943C 4192C7 40F75B 40BE90 40BECA 40BAEB 4206E1 If i comment out this part if (vs2 == vf) { writeln(equal); } it works fine.
Re: Cast Object - get null
On Thursday, April 19, 2012 10:48:45 Namespace wrote: And which version do you use? I use DMD 2.059 on Windows 7. I get this compile error with your code object.Error: Access Violation 41943C 4192C7 40F75B 40BE90 40BECA 40BAEB 4206E1 If i comment out this part if (vs2 == vf) { writeln(equal); } it works fine. I tried both 2.058 and the latest from github. But I'm on 64-bit Linux, so it's possible that you're seeing a Windows-specific issue. - Jonathan M Davis
Re: Is this a bug in iota?
On Thursday, April 19, 2012 10:14:39 Somedude wrote: Le 19/04/2012 10:07, Jonathan M Davis a écrit : Having an assertion may be desirable, but the bug is in the usage of iota, not iota itself. At best, the assertion would help indicate that the caller has a bug. It's exactly the same as doing something like for(size_t i = 3; cond; --i) {} It's basic integer arithmetic. If you subtract from the minimum value that the integral type will hold, then its value will wrap around to the maximum. So, while adding an assertion would be desirable, I don't see how this could be considered a bug in iota. - Jonathan M Davis I don't get it, for me iota has nothing to do with the problem, the problem is in the implementation of popfront(), which should check beforehand whether the range is empty, right ? Maybe, maybe not. popFront _must_ succeed. It has three options if the range is empty: assert, throw an exception, or just assume that it's going to succeed and choke in whatever manner the implementation ends up choking if the range is empty when it tries to pop an element from an empty range. Very few ranges are going to throw exceptions from popFront, because that incures overhead, and really, it's a bug in the caller if they keep trying to pop elements from an empty range. So, throwing an exception really isn't the correct behavior. Asserting is an option, and since iota is templated, it should probably do that (asserting in non-templated code is more debatable, because it'll only be there if Phobos itself is compiled without -release rather than the program or library call it - in most cases, such an assertion would probably never end up being run, because using a release version of Phobos is the default). But it's not doing that right now. An enhancement request for such would be appropriate. Currently, it's taking the third option of not checking, and so you get this problem. But the fact that the code is attempting to pop off an element from an empty range is a bug in the caller, not popFront. - Jonathan M Davis
Re: Cast Object - get null
On Thursday, 19 April 2012 at 09:05:13 UTC, Jonathan M Davis wrote: On Thursday, April 19, 2012 10:48:45 Namespace wrote: And which version do you use? I use DMD 2.059 on Windows 7. I get this compile error with your code object.Error: Access Violation 41943C 4192C7 40F75B 40BE90 40BECA 40BAEB 4206E1 If i comment out this part if (vs2 == vf) { writeln(equal); } it works fine. I tried both 2.058 and the latest from github. But I'm on 64-bit Linux, so it's possible that you're seeing a Windows-specific issue. - Jonathan M Davis A specific Windows bug with opEquals and opCast? My Windows is 64 bit also. Can anyone reproduce this behaviour with Windows? I will download dmd later again to check if i have an older version or beta.
Re: Cast Object - get null
On Thursday, April 19, 2012 11:15:23 Namespace wrote: A specific Windows bug with opEquals and opCast? Maybe. Certainly, it's working on my Linux box, so if you're compiling the same code that I am, and you're using 2.059, it definitely sounds like it's a Windows-specific bug. My Windows is 64 bit also. The fact that it's 64-bit shouldn't matter on Windows, because dmd can't generate 64-bit code on Windows yet. - Jonathan M Davis
Re: Cast Object - get null
I will download dmd later again to check if i have an older version or beta. After download dmd again it get still the same compile error.
Re: Cast Object - get null
On Thursday, 19 April 2012 at 09:22:24 UTC, Jonathan M Davis wrote: On Thursday, April 19, 2012 11:15:23 Namespace wrote: A specific Windows bug with opEquals and opCast? Maybe. Certainly, it's working on my Linux box, so if you're compiling the same code that I am, and you're using 2.059, it definitely sounds like it's a Windows-specific bug. My Windows is 64 bit also. The fact that it's 64-bit shouldn't matter on Windows, because dmd can't generate 64-bit code on Windows yet. - Jonathan M Davis Ok. And what schould i do now? Any patches available for that? Otherwise i must cast up to dmd 2.060 explicit as you do in the first if condition.
Re: Cast Object - get null
On Thursday, April 19, 2012 11:27:20 Namespace wrote: On Thursday, 19 April 2012 at 09:22:24 UTC, Jonathan M Davis wrote: On Thursday, April 19, 2012 11:15:23 Namespace wrote: A specific Windows bug with opEquals and opCast? Maybe. Certainly, it's working on my Linux box, so if you're compiling the same code that I am, and you're using 2.059, it definitely sounds like it's a Windows-specific bug. My Windows is 64 bit also. The fact that it's 64-bit shouldn't matter on Windows, because dmd can't generate 64-bit code on Windows yet. - Jonathan M Davis Ok. And what schould i do now? Any patches available for that? Otherwise i must cast up to dmd 2.060 explicit as you do in the first if condition. Actually, I just re-ran the code on my box, and it does segfault. Either I forgot to run it or I didn't notice the segfault, since it isn't as obvious on Linux with all of the other output: vs.x: 23, vs.y: 42 raw.Vector2D!(short).Vector2D raw.Vector2D!(short).Vector2D equal raw.Vector2D!(float).Vector2D null Segmentation fault What's going wrong is that this cast in opEquals: Vector2D!(T) vec = cast(Vector2D!(T)) o; is failing. The result is null. That's what you'd expect if the built-in cast is being used rather than opCast. And if I put print statements in all three of the opCasts, none of them are called. Upon thinking further about it, I believe that the problem is that you're casting from _Object_ rather than one of the other instantiations of Vector2D, and Object obviously doesn't define an opCast for your type. So, it uses the normal, built-in cast, and it fails, because the type that you're attempting to cast to is not derived from the one that you're trying to cast to. If you could get it to its actual type and _then_ cast it, you could do it. But that's a rather nasty problem. After messing with it a bit though, I do believe that I've come up with a solution. Change opEquals to this: override bool opEquals(Object o) const { writeln(o); auto vec = castFromObject(o); assert(vec !is null); writeln(vec); return vec.x == this.x vec.y == this.y; } private static Vector2D castFromObject(Object o) { import std.typetuple; foreach(U; TypeTuple!(byte, ubyte, short, ushort, int, uint, long, ulong, float, double, real)) { if(auto vec = cast(Vector2D!U)o) return cast(Vector2D)vec; } return null; } I believe that that takes care of the problem. By the way, inside of a template, you don't need to reuse the template arguments when refering to it. So, inside of Vector2D, you can use Vector2D instead of Vector2D!T. - Jonathan M Davis
Re: Is this a bug in iota?
Le 19/04/2012 11:11, Jonathan M Davis a écrit : On Thursday, April 19, 2012 10:14:39 Somedude wrote: Le 19/04/2012 10:07, Jonathan M Davis a écrit : Having an assertion may be desirable, but the bug is in the usage of iota, not iota itself. At best, the assertion would help indicate that the caller has a bug. It's exactly the same as doing something like for(size_t i = 3; cond; --i) {} It's basic integer arithmetic. If you subtract from the minimum value that the integral type will hold, then its value will wrap around to the maximum. So, while adding an assertion would be desirable, I don't see how this could be considered a bug in iota. - Jonathan M Davis I don't get it, for me iota has nothing to do with the problem, the problem is in the implementation of popfront(), which should check beforehand whether the range is empty, right ? Maybe, maybe not. popFront _must_ succeed. It has three options if the range is empty: assert, throw an exception, or just assume that it's going to succeed and choke in whatever manner the implementation ends up choking if the range is empty when it tries to pop an element from an empty range. Very few ranges are going to throw exceptions from popFront, because that incures overhead, and really, it's a bug in the caller if they keep trying to pop elements from an empty range. So, throwing an exception really isn't the correct behavior. Asserting is an option, and since iota is templated, it should probably do that (asserting in non-templated code is more debatable, because it'll only be there if Phobos itself is compiled without -release rather than the program or library call it - in most cases, such an assertion would probably never end up being run, because using a release version of Phobos is the default). But it's not doing that right now. An enhancement request for such would be appropriate. Oh that's right. Still I think it should be done for development, and I also think Phobos should ship in both versions, dev AND release. We shouldn't link against the release phobos when we compile without -release.
Re: Is this a bug in iota?
On Thu, 19 Apr 2012 04:07:00 -0400, Jonathan M Davis jmdavisp...@gmx.com wrote: Having an assertion may be desirable, but the bug is in the usage of iota, not iota itself. Yes, and iota should detect that bug with an assert. No case can really be made that iota shouldn't be changed. Please file an enhancement request. -Steve
Re: delegates vs functions = practical consequences
On Wed, 18 Apr 2012 17:07:07 -0400, Xan xancor...@gmail.com wrote: Hi, I want to know what is most interesting for me: delegates or functions. I consulted sources but none say the practical consequences of such election. What can I do and what can't I do with functions and delegates? Please, be didactics, I'm a newbee In my experience, delegates are the more useful type to *store*. I've implemented this in some places: int delegate(int) stored_dg; void setDelegate(int delegate(int) dg) { stored_dg = dg; } void setDelegate(int function(int) fn) { stored_dg = std.functional.toDelegate(fn); } On the whole, delegates are slightly more expensive to call, but not by much. However, a function converted to a delegate pays the penalty of a double call, because it takes a call to strip out the context pointer. I wish there was a more straightforward way to do this... But I've not seen this be a huge factor -- yet. -Steve
Re: Cast Object - get null
A great thanks to you. But any of my tries to make const Vector2D vec = castFromObject(o); possible i get an error. Didn't i must only write private static const(Vector2D) castFromObject(Object o) instead of private static Vector2D castFromObject(Object o)?
Re: Is this a bug in iota?
On Thursday, 19 April 2012 at 11:38:39 UTC, Steven Schveighoffer wrote: On Thu, 19 Apr 2012 04:07:00 -0400, Jonathan M Davis jmdavisp...@gmx.com wrote: Having an assertion may be desirable, but the bug is in the usage of iota, not iota itself. Yes, and iota should detect that bug with an assert. No case can really be made that iota shouldn't be changed. Please file an enhancement request. -Steve http://d.puremagic.com/issues/show_bug.cgi?id=7944
Re: delegates vs functions = practical consequences
On Thursday, 19 April 2012 at 11:46:59 UTC, Steven Schveighoffer wrote: On Wed, 18 Apr 2012 17:07:07 -0400, Xan xancor...@gmail.com wrote: Hi, I want to know what is most interesting for me: delegates or functions. I consulted sources but none say the practical consequences of such election. What can I do and what can't I do with functions and delegates? Please, be didactics, I'm a newbee In my experience, delegates are the more useful type to *store*. I've implemented this in some places: int delegate(int) stored_dg; void setDelegate(int delegate(int) dg) { stored_dg = dg; } void setDelegate(int function(int) fn) { stored_dg = std.functional.toDelegate(fn); } On the whole, delegates are slightly more expensive to call, but not by much. However, a function converted to a delegate pays the penalty of a double call, because it takes a call to strip out the context pointer. I wish there was a more straightforward way to do this... But I've not seen this be a huge factor -- yet. -Steve Thank you very much all of you for the information. Now I have an idea of practical benefits and contra-benefits of these. By the other hand, is there toFunction for passing delegate to function (theorically it's possible, isn't?) Thanks, Xan.
Immutable Structs and std.concurrency
The program: import std.concurrency ; import std.stdio ; /*immutable*/ struct X { int i ; } void printI ( ) { receive ( ( X x ) { writeln ( x.i ) ; } ) ; } int main ( immutable string[] args ) { auto x = spawn ( printI ) ; x.send ( X ( 3 ) ) ; return 0 ; } behaves entirely as expected. Taking the comments off the immutable leads to: core.exception.AssertError@/home/users/russel/lib.Linux.x86_64/DMD2/bin64/../../src/phobos/std/variant.d(286): X /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(_d_assert_msg+0x1f) [0x43f81f] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(long std.variant.VariantN!(32uL).VariantN.handler!(immutableStruct.X).handler(std.variant.VariantN!(32uL).VariantN.OpID, ubyte[32]*, void*).bool tryPutting(immutableStruct.X*, TypeInfo, void*)+0x7a) [0x43b0fa] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(long std.variant.VariantN!(32uL).VariantN.handler!(immutableStruct.X).handler(std.variant.VariantN!(32uL).VariantN.OpID, ubyte[32]*, void*)+0x103) [0x43ae03] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(@property immutableStruct.X std.variant.VariantN!(32uL).VariantN.get!(immutableStruct.X).get()+0x57) [0x434cf7] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(void std.concurrency.Message.map!(void function(immutableStruct.X)*).map(void function(immutableStruct.X)*)+0x46) [0x434c96] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(bool std.concurrency.MessageBox.get!(void function(immutableStruct.X)*).get(scope void function(immutableStruct.X)*).bool onStandardMsg(ref std.concurrency.Message)+0x2d) [0x434731] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(bool std.concurrency.MessageBox.get!(void function(immutableStruct.X)*).get(scope void function(immutableStruct.X)*).bool scan(ref std.concurrency.List!(std.concurrency.Message).List)+0xd3) [0x434a47] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(bool std.concurrency.MessageBox.get!(void function(immutableStruct.X)*).get(scope void function(immutableStruct.X)*)+0x15e) [0x434692] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(void std.concurrency.receive!(void function(immutableStruct.X)*).receive(void function(immutableStruct.X)*)+0x2e) [0x434526] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(void immutableStruct.printI()+0x13) [0x433d1b] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(_D3std11concurrency11__T6_spawnZ6_spawnFbPFZvZS3std11concurrency3Tid4execMFZv+0x3d) [0x43abb5] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(void core.thread.Thread.run()+0x2a) [0x449caa] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(thread_entryPoint+0xf3) [0x449a43] I believe this is wrong on so many levels, but is it because I don't know D? -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder signature.asc Description: This is a digitally signed message part
Re: Access violation using chain()
Brad Anderson , dans le message (digitalmars.D.learn:34902), a écrit : Perhaps I'm just misunderstanding something about closures but the following code seems to behave oddly: import std.stdio, std.range, std.algorithm, std.string; void main() { auto lst = [a, b]; auto rng = range_gen(lst); writeln(rng.take(5)); } auto range_gen(string[] lst) { auto a = sequence!n+1().map!(a=format(%s%d, lst[0], a))(); return chain(lst, a); // access violation //return a; // works } My guess is that chain takes lst by reference, just like the delegates for map, wo both are working on the same slice instance. The chain first pops elements from lst, and then calls the mapped sequence. At that time, lst is empty. You can just copy lst before you give it to chain (or to map's delegate) to solve this bug: auto range_gen(string[] lst) { auto a = sequence!n+1().map!(a=format(%s%d, lst[0], a))(); string[] lst2 = lst; return chain(lst2, a); // access violation }
Allow empty field function arguments for default?
I put this here because it's probably a flawed idea. A 'learn' level suggestion. At present function arguments that you want to default must go at the end like so: int fun(int a = 1, int b = 2, int c = 3) { return a + b + c; } fun(4); //Modifies a where the default fields can only be fields after any argument provided. Why not allow something like: fun( , 4, ); //Modifies b fun( , , 5); //Modifies c for when you want to call fun with other fields not being default? This would seem more flexible and pretty clear what is intended.
Re: Allow empty field function arguments for default?
And while I think about it why not allow the following to make b and c int rather than have to redeclare the type each time? int fun(int a = 1, b = 2, c = 3) { return a + b + c; }
How does this work ?
I'm going through a number of bug reports, trying to reproduce the problems and see what can be closed easily (i.e non reproduced, correct behaviour, etc), and I just came accross http://d.puremagic.com/issues/show_bug.cgi?id=7326 titled write interprets enum with byte backing type as a character Here is the case description: import std.stdio; enum X : byte { Foobar = 65, } void main() { X x; writeln(x); // writes 'A' writeln(cast(byte)x); // writes 65 } That's it. When I run this on Win32, I get: Foo 65 Can anyone explain me if it is the correct behaviour, and if yes, why ? Thx.
Re: How does this work ?
On 4/19/12, Somedude lovelyd...@mailmetrash.com wrote: Can anyone explain me if it is the correct behaviour, and if yes, why ? It's fixed now and we can close this down. I think it was related to formatting issues, that's all.
Re: Cast Object - get null
It seems that i can't cast if i want a const Vector2D, neither with castFromtObject nor with opCast. If i do it i get a very long list of compile errors. It's no problem because i can deal without cast to const but it would be usefull if you can show me how i can use both, const and normal casts.
Re: Access violation using chain()
On Thu, Apr 19, 2012 at 7:25 AM, Christophe trav...@phare.normalesup.orgwrote: Brad Anderson , dans le message (digitalmars.D.learn:34902), a écrit : Perhaps I'm just misunderstanding something about closures but the following code seems to behave oddly: import std.stdio, std.range, std.algorithm, std.string; void main() { auto lst = [a, b]; auto rng = range_gen(lst); writeln(rng.take(5)); } auto range_gen(string[] lst) { auto a = sequence!n+1().map!(a=format(%s%d, lst[0], a))(); return chain(lst, a); // access violation //return a; // works } My guess is that chain takes lst by reference, just like the delegates for map, wo both are working on the same slice instance. The chain first pops elements from lst, and then calls the mapped sequence. At that time, lst is empty. You can just copy lst before you give it to chain (or to map's delegate) to solve this bug: auto range_gen(string[] lst) { auto a = sequence!n+1().map!(a=format(%s%d, lst[0], a))(); string[] lst2 = lst; return chain(lst2, a); // access violation } Ah, that would make sense. I'll test and make sure when I get home. Range consumption tricks me more often than I wish. I'll eventually learn to look out for it more actively. Regards, Brad Anderson
Re: Immutable Structs and std.concurrency
On 04/19/2012 03:27 PM, Russel Winder wrote: The program: import std.concurrency ; import std.stdio ; /*immutable*/ struct X { int i ; } void printI ( ) { receive ( ( X x ) { writeln ( x.i ) ; } ) ; } int main ( immutable string[] args ) { auto x = spawn ( printI ) ; x.send ( X ( 3 ) ) ; return 0 ; } behaves entirely as expected. Taking the comments off the immutable leads to: core.exception.AssertError@/home/users/russel/lib.Linux.x86_64/DMD2/bin64/../../src/phobos/std/variant.d(286): X /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(_d_assert_msg+0x1f) [0x43f81f] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(long std.variant.VariantN!(32uL).VariantN.handler!(immutableStruct.X).handler(std.variant.VariantN!(32uL).VariantN.OpID, ubyte[32]*, void*).bool tryPutting(immutableStruct.X*, TypeInfo, void*)+0x7a) [0x43b0fa] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(long std.variant.VariantN!(32uL).VariantN.handler!(immutableStruct.X).handler(std.variant.VariantN!(32uL).VariantN.OpID, ubyte[32]*, void*)+0x103) [0x43ae03] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(@property immutableStruct.X std.variant.VariantN!(32uL).VariantN.get!(immutableStruct.X).get()+0x57) [0x434cf7] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(void std.concurrency.Message.map!(void function(immutableStruct.X)*).map(void function(immutableStruct.X)*)+0x46) [0x434c96] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(bool std.concurrency.MessageBox.get!(void function(immutableStruct.X)*).get(scope void function(immutableStruct.X)*).bool onStandardMsg(ref std.concurrency.Message)+0x2d) [0x434731] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(bool std.concurrency.MessageBox.get!(void function(immutableStruct.X)*).get(scope void function(immutableStruct.X)*).bool scan(ref std.concurrency.List!(std.concurrency.Message).List)+0xd3) [0x434a47] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(bool std.concurrency.MessageBox.get!(void function(immutableStruct.X)*).get(scope void function(immutableStruct.X)*)+0x15e) [0x434692] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(void std.concurrency.receive!(void function(immutableStruct.X)*).receive(void function(immutableStruct.X)*)+0x2e) [0x434526] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(void immutableStruct.printI()+0x13) [0x433d1b] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(_D3std11concurrency11__T6_spawnZ6_spawnFbPFZvZS3std11concurrency3Tid4execMFZv+0x3d) [0x43abb5] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(void core.thread.Thread.run()+0x2a) [0x449caa] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(thread_entryPoint+0xf3) [0x449a43] I believe this is wrong on so many levels, but is it because I don't know D? It certainly should work. std.concurrency does not do a good job dealing with head-immutable/head-const types currently (this includes class references). This needs to be fixed. The general problem is that it should be possible to declare a rebindable tail-immutable version of some type. std.typecons.Rebindable can be used for this, but an in-language solution would be superior.
Re: delegates vs functions = practical consequences
On Thu, 19 Apr 2012 09:04:47 -0400, Xan xancor...@gmail.com wrote: Thank you very much all of you for the information. Now I have an idea of practical benefits and contra-benefits of these. By the other hand, is there toFunction for passing delegate to function (theorically it's possible, isn't?) No. A delegate requires a context pointer. you *can* extract the actual function pointer and context pointer from a delegate, but you can't call the function without making a delegate out of it again. -Steve
Re: Newbie Introduction (was Re: arrays and foreach)
On Wednesday, 18 April 2012 at 19:43:50 UTC, Paul D. Anderson wrote: SomeDude: Your outline and especially your emphasis on what a rank beginner needs to know is very good. Would you consider writing it up yourself? Not the whole thing, maybe but the beginner info and the compiler/linker appendices. You have a commendable prose style. There are tutorials available already, but too many is way better than too few. Paul Thanks. I wouldn't mind having a stab at it, but: 1. it is Ali's book, not mine, so we would need Ali's agreement. If he offers me to contribute, why not, 2. I'm myself a D beginner, so you would probably need to proof read and correct me afterwards.
Github/Git Pull 482
I am having a problem with my Pull-Request, I don't know how I can do that: https://github.com/D-Programming-Language/phobos/pull/482#issuecomment-5070817 I hope you can give me a short intstruction what to do, thanks.
Re: Github/Git Pull 482
On Thursday, 19 April 2012 at 17:27:18 UTC, David wrote: I am having a problem with my Pull-Request, I don't know how I can do that: https://github.com/D-Programming-Language/phobos/pull/482#issuecomment-5070817 I hope you can give me a short intstruction what to do, thanks. Pull from upstream (if you don't have upstream set up as a remote do a git remote add upstream https://github.com/D-Programming-Language/phobos.git; then git pull upstream master). Then do git checkout conv2 if you aren't already on that branch. Finally git rebase master. Resolve conflicts, if necessary. Then git push -f origin (presumably origin is your GitHub repo). The -f is required to force the push because you are screwing around with history when you do a rebase. Regards, Brad Anderson
Re: Github/Git Pull 482
On 19.04.2012 21:27, David wrote: I am having a problem with my Pull-Request, I don't know how I can do that: https://github.com/D-Programming-Language/phobos/pull/482#issuecomment-5070817 I hope you can give me a short intstruction what to do, thanks. Should be as simple as: git pull --rebase https://github.com/D-Programming-Language/phobos.git master And fix conflicts if any. (assuming you are on the same branch as pull request) then a forced push: git push -f But you'd better setup some alias for DPL as e.g. 'upstream' remote Brad already mentioned. then it looks like this: git pull --rebase upstream master -- Dmitry Olshansky
new std.process new aa status
Are there any info about them? I tought that new std.process would replace the old one in version 2.059, but it seems not...
Re: Newbie Introduction (was Re: arrays and foreach)
On 04/19/2012 10:02 AM, SomeDude wrote: On Wednesday, 18 April 2012 at 19:43:50 UTC, Paul D. Anderson wrote: SomeDude: Your outline and especially your emphasis on what a rank beginner needs to know is very good. Would you consider writing it up yourself? Not the whole thing, maybe but the beginner info and the compiler/linker appendices. You have a commendable prose style. There are tutorials available already, but too many is way better than too few. Paul Thanks. I wouldn't mind having a stab at it, but: 1. it is Ali's book, not mine, so we would need Ali's agreement. If he offers me to contribute, why not, I will improve the beginning of the book with your ideas. (I don't have free time yet; maybe by the end of next week.) I would also like to thank you if you would please e-mail me your full name at acehr...@yahoo.com. I think it would be even better if you add a newbie section (or improve the existing ones as you graciously have been doing) on the wiki site, or some other site. I would be happy to link to that section from the book. (I have a feeling Paul D. Anderson meant that you wrote a separate document anyway.) 2. I'm myself a D beginner, so you would probably need to proof read and correct me afterwards. Gladly, as much as I know myself. :) Ali
Re: Github/Git Pull 482
Am 19.04.2012 20:00, schrieb Dmitry Olshansky: On 19.04.2012 21:27, David wrote: I am having a problem with my Pull-Request, I don't know how I can do that: https://github.com/D-Programming-Language/phobos/pull/482#issuecomment-5070817 I hope you can give me a short intstruction what to do, thanks. Should be as simple as: git pull --rebase https://github.com/D-Programming-Language/phobos.git master And fix conflicts if any. (assuming you are on the same branch as pull request) then a forced push: git push -f But you'd better setup some alias for DPL as e.g. 'upstream' remote Brad already mentioned. then it looks like this: git pull --rebase upstream master Thanks you two, it seems like it worked ... at least I hope that :)
Re: new std.process new aa status
On Thu, 19 Apr 2012 14:17:04 -0400, Andrea Fontana nos...@example.com wrote: Are there any info about them? I tought that new std.process would replace the old one in version 2.059, but it seems not... std.process is being worked on. I'm hoping 2.060 -Steve
Re: Allow empty field function arguments for default?
On 2012-04-19 16:13, ixid wrote: I put this here because it's probably a flawed idea. A 'learn' level suggestion. At present function arguments that you want to default must go at the end like so: int fun(int a = 1, int b = 2, int c = 3) { return a + b + c; } fun(4); //Modifies a where the default fields can only be fields after any argument provided. Why not allow something like: fun( , 4, ); //Modifies b fun( , , 5); //Modifies c for when you want to call fun with other fields not being default? This would seem more flexible and pretty clear what is intended. Named arguments would probably be better for this. fun(c = 5); -- /Jacob Carlborg
Re: Allow empty field function arguments for default?
On 2012-04-19 20:34, Jacob Carlborg wrote: On 2012-04-19 16:13, ixid wrote: I put this here because it's probably a flawed idea. A 'learn' level suggestion. At present function arguments that you want to default must go at the end like so: int fun(int a = 1, int b = 2, int c = 3) { return a + b + c; } fun(4); //Modifies a where the default fields can only be fields after any argument provided. Why not allow something like: fun( , 4, ); //Modifies b fun( , , 5); //Modifies c for when you want to call fun with other fields not being default? This would seem more flexible and pretty clear what is intended. Named arguments would probably be better for this. fun(c = 5); Which is actually possible to emulate: callWithNamedArguments(fun, c=5); See: https://github.com/jacob-carlborg/orange/blob/master/orange/util/Reflection.d#L135 -- /Jacob Carlborg
Re: new std.process new aa status
On Thu, Apr 19, 2012 at 08:17:04PM +0200, Andrea Fontana wrote: Are there any info about them? I tought that new std.process would replace the old one in version 2.059, but it seems not... [...] The new AA implementation is still in the works. The code is not finished yet, and even after it's finished, there's still the non-trivial task of replacing the current implementation in the compiler. Hopefully it will end up in 2.060, but it may happen later, depending on how things go. Anyway, there shouldn't be any significant changes from how AA's currently work, from the user's POV. If anything, it should mainly be bugfixes and other enhancements. T -- Bare foot: (n.) A device for locating thumb tacks on the floor.
Operator overloading
Hi, I read http://dlang.org/operatoroverloading.html but in my code it does not work. I tried to overload '*' binary operator in my class Algorisme: [...] class Algorisme(U,V) { string nom; uint versio; alias V function (U) Funcio; Funcio funcio; this(string nom, uint versio, Funcio funcio) { try { this.nom = nom; this.versio = versio; this.funcio = funcio; } catch { writeln(Error); } } string toString() { return format(%s (versió %s): %s - %s, nom, versio, typeid(U), typeid(V)); } Algorisme(U, V) opBinary(string op) (Algorisme(U, V) alg) { static if (op == '*') return new Algorisme(U,V)(composició, this.versio+alg.versio, this.funcio); } } [...] but I receive these errors: $ gdmd-4.6 algorisme.d algorisme.d:31: function declaration without return type. (Note that constructors are always named 'this') algorisme.d:31: no identifier for declarator Algorisme(U, V) algorisme.d:31: semicolon expected following function declaration algorisme.d:31: function declaration without return type. (Note that constructors are always named 'this') algorisme.d:31: function declaration without return type. (Note that constructors are always named 'this') algorisme.d:31: found 'alg' when expecting ')' algorisme.d:31: no identifier for declarator opBinary(Algorisme(U, V)) algorisme.d:31: semicolon expected following function declaration algorisme.d:31: Declaration expected, not ')' algorisme.d:35: unrecognized declaration Why it fails? Anyone could help me? Thanks, Xan.
Re: Cast Object - get null
On Thursday, 19 April 2012 at 15:48:29 UTC, Namespace wrote: It seems that i can't cast if i want a const Vector2D, neither with castFromtObject nor with opCast. If i do it i get a very long list of compile errors. It's no problem because i can deal without cast to const but it would be usefull if you can show me how i can use both, const and normal casts. For example in this case void foo(T)(const Vector2D!(T) vec) { bar(cast(Vector2s) vec); } void bar(const Vector2s vec) { } const Vector2f vf = Vector2f(23, 42); Vector2s vs = Vector2s(vf); Vector2s vs_ = cast(Vector2s) vf; Vector2f vf_ = cast(Vector2f) vs; Vector2s vs2 = Vector2s(23, 42); if (vs2 == vf) { writeln(equal!); } foo(vf); foo(vs); i get this compiler errors: cast.d(323): Error: template cast.Vector2D!(short).Vector2D.opCast matches more than one template declaration, cast.d(285):opCast(U) if (is(Unqual!(U) == Vector 2D!(byte)) || is(Unqual!(U) == Vector2D!(ubyte)) || is(Unqual!(U) == Vector2D!(s hort)) || is(Unqual!(U) == Vector2D!(ushort)) || is(Unqual!(U) == Vector2D!(int) ) || is(Unqual!(U) == Vector2D!(uint)) || is(Unqual!(U) == Vector2D!(long)) || i s(Unqual!(U) == Vector2D!(ulong)) || is(Unqual!(U) == Vector2D!(float)) || is(Un qual!(U) == Vector2D!(double)) || is(Unqual!(U) == Vector2D!(real))) and cast.d( 306):opCast(T) if (isImplicitlyConvertible!(typeof(this),const(T))) cast.d(360): Error: template instance cast.foo!(short) error instantiating I can avoid them if i change bar to void foo(T)(const Vector2D!(T) vec) { static if (is(typeof(vec.x) == const float)) { bar(cast(Vector2s) vec); } else { bar(vec); } } Of course i must check for more then only const float but it is only a test case. So it seems i have to change the cast operator. But i have no idea how. I thougth that inout would help me, but i was wrong. So maybe you have some ideas?
Re: Operator overloading
On 19.04.2012 23:14, Xan wrote: Hi, I read http://dlang.org/operatoroverloading.html but in my code it does not work. I tried to overload '*' binary operator in my class Algorisme: [...] class Algorisme(U,V) { string nom; uint versio; alias V function (U) Funcio; Funcio funcio; this(string nom, uint versio, Funcio funcio) { try { this.nom = nom; this.versio = versio; this.funcio = funcio; } catch { writeln(Error); } } string toString() { return format(%s (versió %s): %s - %s, nom, versio, typeid(U), typeid(V)); } Algorisme(U, V) opBinary(string op) (Algorisme(U, V) alg) { Algorisme! opBinary(string op) (Algorisme alg) { or Algorisme!(U,V) opBinary(string op) (Algorisme!(U,V) alg) { should do it static if (op == '*') return new Algorisme(composició, or: static if (op == '*') return new Algorisme!(U,v)(composició, same here. There is no need to put !(params) explicitly if it's the same as the template you are writing. this.versio+alg.versio, this.funcio); } } [...] but I receive these errors: $ gdmd-4.6 algorisme.d algorisme.d:31: function declaration without return type. (Note that constructors are always named 'this') algorisme.d:31: no identifier for declarator Algorisme(U, V) algorisme.d:31: semicolon expected following function declaration algorisme.d:31: function declaration without return type. (Note that constructors are always named 'this') algorisme.d:31: function declaration without return type. (Note that constructors are always named 'this') algorisme.d:31: found 'alg' when expecting ')' algorisme.d:31: no identifier for declarator opBinary(Algorisme(U, V)) algorisme.d:31: semicolon expected following function declaration algorisme.d:31: Declaration expected, not ')' algorisme.d:35: unrecognized declaration Why it fails? Anyone could help me? Thanks, Xan. -- Dmitry Olshansky
Re: Operator overloading
On Thursday, 19 April 2012 at 19:24:40 UTC, Dmitry Olshansky wrote: On 19.04.2012 23:14, Xan wrote: Hi, I read http://dlang.org/operatoroverloading.html but in my code it does not work. I tried to overload '*' binary operator in my class Algorisme: [...] class Algorisme(U,V) { string nom; uint versio; alias V function (U) Funcio; Funcio funcio; this(string nom, uint versio, Funcio funcio) { try { this.nom = nom; this.versio = versio; this.funcio = funcio; } catch { writeln(Error); } } string toString() { return format(%s (versió %s): %s - %s, nom, versio, typeid(U), typeid(V)); } Algorisme(U, V) opBinary(string op) (Algorisme(U, V) alg) { Algorisme! opBinary(string op) (Algorisme alg) { or Algorisme!(U,V) opBinary(string op) (Algorisme!(U,V) alg) { should do it static if (op == '*') return new Algorisme(composició, or: static if (op == '*') return new Algorisme!(U,v)(composició, same here. There is no need to put !(params) explicitly if it's the same as the template you are writing. this.versio+alg.versio, this.funcio); } Thanks, Dmitry, but it's a correction * instead of '*' (string instead of char) The definitive code is: Algorisme!(U,V) opBinary(string op)(Algorisme!(U,V) alg) { static if (op==*) return new Algorisme!(U,V)(composició, this.versio+alg.versio, this.funcio); } Thanks a lot, another time, Xan. } [...] but I receive these errors: $ gdmd-4.6 algorisme.d algorisme.d:31: function declaration without return type. (Note that constructors are always named 'this') algorisme.d:31: no identifier for declarator Algorisme(U, V) algorisme.d:31: semicolon expected following function declaration algorisme.d:31: function declaration without return type. (Note that constructors are always named 'this') algorisme.d:31: function declaration without return type. (Note that constructors are always named 'this') algorisme.d:31: found 'alg' when expecting ')' algorisme.d:31: no identifier for declarator opBinary(Algorisme(U, V)) algorisme.d:31: semicolon expected following function declaration algorisme.d:31: Declaration expected, not ')' algorisme.d:35: unrecognized declaration Why it fails? Anyone could help me? Thanks, Xan.
Re: Operator overloading
On Thursday, April 19, 2012 21:14:43 Xan wrote: Hi, I read http://dlang.org/operatoroverloading.html but in my code it does not work. I tried to overload '*' binary operator in my class Algorisme: [...] class Algorisme(U,V) { string nom; uint versio; alias V function (U) Funcio; Funcio funcio; this(string nom, uint versio, Funcio funcio) { try { this.nom = nom; this.versio = versio; this.funcio = funcio; } catch { writeln(Error); } } string toString() { return format(%s (versió %s): %s - %s, nom, versio, typeid(U), typeid(V)); } Algorisme(U, V) opBinary(string op) (Algorisme(U, V) alg) { static if (op == '*') return new Algorisme(U,V)(composició, this.versio+alg.versio, this.funcio); } } [...] but I receive these errors: $ gdmd-4.6 algorisme.d algorisme.d:31: function declaration without return type. (Note that constructors are always named 'this') algorisme.d:31: no identifier for declarator Algorisme(U, V) algorisme.d:31: semicolon expected following function declaration algorisme.d:31: function declaration without return type. (Note that constructors are always named 'this') algorisme.d:31: function declaration without return type. (Note that constructors are always named 'this') algorisme.d:31: found 'alg' when expecting ')' algorisme.d:31: no identifier for declarator opBinary(Algorisme(U, V)) algorisme.d:31: semicolon expected following function declaration algorisme.d:31: Declaration expected, not ')' algorisme.d:35: unrecognized declaration Why it fails? Anyone could help me? Use a template constraint rather than a static if. As it stands, any operator other than * will result in a function with no return statement. Algorisme opBinary(string op)(Algorisme alg) if(op == *) { return new Algorisme(composició, this.versio+alg.versio, this.funcio); } - Jonathan M Davis
Re: Cast Object - get null
On Wednesday, 18 April 2012 at 17:28:16 UTC, Jonathan M Davis wrote: Ideally, you'd also have a template constraint restricting the cast to the types that you want to be able to cast to, but since you're dealing with a templated type, that can be a bit tricky. One (somewhat ugly) option would be to do something like U opCast(U) const if(is(Unqual!U == Vector2D!byte) || is(Unqual!U == Vector2D!ubyte) || is(Unqual!U == Vector2D!short) || is(Unqual!U == Vector2D!ushort) || is(Unqual!U == Vector2D!int) || is(Unqual!U == Vector2D!uint) || is(Unqual!U == Vector2D!long) || is(Unqual!U == Vector2D!ulong) || is(Unqual!U == Vector2D!float) || is(Unqual!U == Vector2D!double) || is(Unqual!U == Vector2D!real)) { return new U(x, y); } Another would be to have an enum on the type indicating that it's an instantiation of your Vector2D template (e.g. isVector2D). U opCast(U) const if(__traits(compiles, U.isVector2D)) { return new U(x, y); } - Jonathan M Davis T opCast(T : const(Vector2D!U), U)() const { return new T(x, y); }
Re: Immutable Structs and std.concurrency
On Thursday, 19 April 2012 at 16:26:19 UTC, Timon Gehr wrote: On 04/19/2012 03:27 PM, Russel Winder wrote: The program: import std.concurrency ; import std.stdio ; /*immutable*/ struct X { int i ; } void printI ( ) { receive ( ( X x ) { writeln ( x.i ) ; } ) ; } int main ( immutable string[] args ) { auto x = spawn ( printI ) ; x.send ( X ( 3 ) ) ; return 0 ; } behaves entirely as expected. Taking the comments off the immutable leads to: core.exception.AssertError@/home/users/russel/lib.Linux.x86_64/DMD2/bin64/../../src/phobos/std/variant.d(286): X /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(_d_assert_msg+0x1f) [0x43f81f] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(long std.variant.VariantN!(32uL).VariantN.handler!(immutableStruct.X).handler(std.variant.VariantN!(32uL).VariantN.OpID, ubyte[32]*, void*).bool tryPutting(immutableStruct.X*, TypeInfo, void*)+0x7a) [0x43b0fa] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(long std.variant.VariantN!(32uL).VariantN.handler!(immutableStruct.X).handler(std.variant.VariantN!(32uL).VariantN.OpID, ubyte[32]*, void*)+0x103) [0x43ae03] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(@property immutableStruct.X std.variant.VariantN!(32uL).VariantN.get!(immutableStruct.X).get()+0x57) [0x434cf7] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(void std.concurrency.Message.map!(void function(immutableStruct.X)*).map(void function(immutableStruct.X)*)+0x46) [0x434c96] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(bool std.concurrency.MessageBox.get!(void function(immutableStruct.X)*).get(scope void function(immutableStruct.X)*).bool onStandardMsg(ref std.concurrency.Message)+0x2d) [0x434731] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(bool std.concurrency.MessageBox.get!(void function(immutableStruct.X)*).get(scope void function(immutableStruct.X)*).bool scan(ref std.concurrency.List!(std.concurrency.Message).List)+0xd3) [0x434a47] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(bool std.concurrency.MessageBox.get!(void function(immutableStruct.X)*).get(scope void function(immutableStruct.X)*)+0x15e) [0x434692] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(void std.concurrency.receive!(void function(immutableStruct.X)*).receive(void function(immutableStruct.X)*)+0x2e) [0x434526] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(void immutableStruct.printI()+0x13) [0x433d1b] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(_D3std11concurrency11__T6_spawnZ6_spawnFbPFZvZS3std11concurrency3Tid4execMFZv+0x3d) [0x43abb5] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(void core.thread.Thread.run()+0x2a) [0x449caa] /tmp/.rdmd-1000/home/users/russel/Progs/OddsByLanguage/D/Odds/immutableStruct.d.EDDA68DBDAF917356C855298813D6CD2(thread_entryPoint+0xf3) [0x449a43] I believe this is wrong on so many levels, but is it because I don't know D? It certainly should work. std.concurrency does not do a good job dealing with head-immutable/head-const types currently (this includes class references). This needs to be fixed. The general problem is that it should be possible to declare a rebindable tail-immutable version of some type. std.typecons.Rebindable can be used for this, but an in-language solution would be superior. Fixing std.concurrency entails fixing std.variant which entails fixing std.typecons.Rebindable by moving its functionality into the language where it belongs. https://github.com/D-Programming-Language/dmd/pull/3 This one has been lurking around forever, I wish Walter would accept this patch already.
Re: Allow empty field function arguments for default?
On Thursday, 19 April 2012 at 18:34:41 UTC, Jacob Carlborg wrote: Named arguments would probably be better for this. fun(c = 5); Maybe so, but `fun(c = 5);` is not an additive change, while the OP's suggestion actually is.
Re: Cast Object - get null
T opCast(T : const(Vector2D!U), U)() const { return new T(x, y); } Awesome, now i only need this three and it works perfect. typeof(this) opCast(T)() if (isImplicitlyConvertible!(typeof(this), T)) { writeln(implicit cast); return this; } const(typeof(this)) opCast(T)() const if (isImplicitlyConvertible!(typeof(this), const T)) { writeln(implicit const cast); return this; } T opCast(T : const(Vector2D!(U)), U)() const { writeln(Other cast); return T(x, y); } Many thanks to you two! :)
Re: Cast Object - get null
On Thursday, April 19, 2012 23:06:58 Jakob Ovrum wrote: T opCast(T : const(Vector2D!U), U)() const { return new T(x, y); } Cool. That's definitely better. I definitely need to improve my template-foo with regards to :. - Jonathan M Davis
Re: Immutable Structs and std.concurrency
On 04/19/2012 11:11 PM, Jakob Ovrum wrote: Fixing std.concurrency entails fixing std.variant which entails fixing std.typecons.Rebindable by moving its functionality into the language where it belongs. https://github.com/D-Programming-Language/dmd/pull/3 This one has been lurking around forever, I wish Walter would accept this patch already. Unfortunately the patch is incomplete. (template parameter matching is not implemented afaik and it does not work for structs)
Re: Immutable Structs and std.concurrency
On Thursday, 19 April 2012 at 21:33:46 UTC, Timon Gehr wrote: Unfortunately the patch is incomplete. (template parameter matching is not implemented afaik and it does not work for structs) Ah, didn't know about the template blocker, but how should it work for structs? Shouldn't the syntax only be allowed for implicit reference types, i.e. classes only?
Re: Immutable Structs and std.concurrency
On 04/19/2012 11:55 PM, Jakob Ovrum wrote: On Thursday, 19 April 2012 at 21:33:46 UTC, Timon Gehr wrote: Unfortunately the patch is incomplete. (template parameter matching is not implemented afaik and it does not work for structs) Ah, didn't know about the template blocker, but how should it work for structs? Shouldn't the syntax only be allowed for implicit reference types, i.e. classes only? std.typecons.Rebindable works for immutable structs with indirections. Reference types are just value types with indirections anyway: struct Object{ ObjectInstance* storage; alias storage this; } The language should catch this case even for user-defined types imo.
Re: D, Derelict2, and OpenGL
In the same vein, I have getting nothing on the screen when there should be rendered a red triangle. The vertex positions are those used by McKeeson http://www.arcsynthesis.org/gltut/, being in ndc fall within the frustum. The code for setting up vao and shaders is: module ShaderHub; import std.stdio; import std.string; import derelict.opengl3.gl3; class ShaderHub{ private bool ok=true; private GLuint shad=0, vshad=0, fshad=0; private int voff=0; private GLuint vbo=0, vao=0; const float[] v = [ 0.75f, 0.75f, 0.0f, 1.0f, 0.75f, -0.75f, 0.0f, 1.0f, -0.75f, -0.75f, 0.0f, 1.0f]; public this(){ immutable string vshader = ` #version 330 layout(location = 1) in vec4 pos; void main(void) { gl_Position = pos; } `; immutable string fshader = ` #version 330 void main(void) { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); } `; shad=glCreateProgram(); if(shad==0){ writeln(Error: GL did not assigh main shader program id); ok=false; } vshad=glCreateShader(GL_VERTEX_SHADER); const char *vptr=toStringz(vshader); glShaderSource(vshad, 1, vptr, null); glCompileShader(vshad); int status, len; glGetShaderiv(vshad, GL_COMPILE_STATUS, status); if(status==GL_FALSE){ glGetShaderiv(vshad, GL_INFO_LOG_LENGTH, len); char[] error=new char[len]; glGetShaderInfoLog(vshad, len, null, cast(char*)error); writeln(error); ok=false; } fshad=glCreateShader(GL_FRAGMENT_SHADER); const char *fptr=toStringz(fshader); glShaderSource(fshad, 1, fptr, null); glCompileShader(fshad); glGetShaderiv(vshad, GL_COMPILE_STATUS, status); if(status==GL_FALSE){ glGetShaderiv(fshad, GL_INFO_LOG_LENGTH, len); char[] error=new char[len]; glGetShaderInfoLog(fshad, len, null, cast(char*)error); writeln(error); ok=false; } glAttachShader(shad, vshad); glAttachShader(shad, fshad); glLinkProgram(shad); glGetShaderiv(shad, GL_LINK_STATUS, status); if(status==GL_FALSE){ glGetShaderiv(shad, GL_INFO_LOG_LENGTH, len); char[] error=new char[len]; glGetShaderInfoLog(shad, len, null, cast(char*)error); writeln(error); ok=false; } glGenVertexArrays(1, vao); if(vao1){ writeln(Error: GL failed to assign vao id); ok=false; } glBindVertexArray(vao); glGenBuffers(1, vbo); if(vbo1){ writeln(Error: GL failed to assign vbo id); ok=false; } glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, v.length * GL_FLOAT.sizeof, v[0], GL_STATIC_DRAW); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, cast(void*)voff); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); } public void draw(){ glUseProgram(shad); writeln(glGetAttribLocation(shad, pos));//prints 1 glBindVertexArray(vao); glDrawArrays(GL_TRIANGLES, 0, 6); glBindVertexArray(0); glUseProgram(0); } } //__ the code for setting up openGL3 is: import std.stdio; import derelict.sdl2.sdl; import derelict.opengl3.gl3; import EventHub; import ExposeApp; pragma(lib, DerelictUtil.lib); pragma(lib, DerelictSDL2.lib); pragma(lib, DerelictGL3.lib); class App{ private ExposeApp funcPtrs; private EventHub ehub; private SDL_Window *win; private SDL_GLContext context; private int w=600, h=480, fov=55; private bool running=true; public this(){ if(!initSDL()){ writeln(Error initializing SDL); SDL_Quit(); } initGL(); funcPtrs=new ExposeApp(); funcPtrs.stop=stopLoop;
Docs: Section on local variables
Can I remove this section from the D docs, in functions? : Local Variables It is an error to use a local variable without first assigning it a value. The implementation may not always be able to detect these cases. Other language compilers sometimes issue a warning for this, but since it is always a bug, it should be an error. It is an error to declare a local variable that is never referred to. Dead variables, like anachronistic dead code, are just a source of confusion for maintenance programmers. I don't think this will ever be implemented, or that it should be for that matter.
Re: Docs: Section on local variables
On Friday, April 20, 2012 02:53:25 Andrej Mitrovic wrote: Can I remove this section from the D docs, in functions? : Local Variables It is an error to use a local variable without first assigning it a value. The implementation may not always be able to detect these cases. Other language compilers sometimes issue a warning for this, but since it is always a bug, it should be an error. It is an error to declare a local variable that is never referred to. Dead variables, like anachronistic dead code, are just a source of confusion for maintenance programmers. I don't think this will ever be implemented, or that it should be for that matter. Ask in the main list. My inclination would be that it should be removed, but the main D list is the place to discuss it. - Jonathan M Davis
Re: Is this a bug in iota?
On Thursday, 19 April 2012 at 12:39:25 UTC, SomeDude wrote: On Thursday, 19 April 2012 at 11:38:39 UTC, Steven Schveighoffer wrote: On Thu, 19 Apr 2012 04:07:00 -0400, Jonathan M Davis jmdavisp...@gmx.com wrote: Having an assertion may be desirable, but the bug is in the usage of iota, not iota itself. Yes, and iota should detect that bug with an assert. No case can really be made that iota shouldn't be changed. Please file an enhancement request. -Steve http://d.puremagic.com/issues/show_bug.cgi?id=7944 https://github.com/D-Programming-Language/phobos/pull/545 Regards, Brad Anderson
Re: Equivalents to policy classes in D
On 03/04/12 02:24, Cristi Cobzarenco wrote: Mixins templates would be the answer: OK, I've had a go at writing up some mixin template-based policy code of my own. However ... it winds up with compilation errors that I can't decipher: mixin.d(55): Error: type MyStruct!(ulong,GenOne,WriteOne) has no value mixin.d(56): Error: type MyStruct!(double,GenOne,WriteTwo) has no value mixin.d(57): Error: type MyStruct!(double,GenThree,WriteOne) has no value mixin.d(58): Error: type MyStruct!(long,GenThree,WriteTwo) has no value /usr/local/include/d2/std/conv.d(244): Error: template std.conv.toImpl does not match any function template declaration /usr/local/include/d2/std/conv.d(252): Error: template std.conv.toImpl cannot deduce template function from argument types !(string)(ubyte) /usr/local/include/d2/std/conv.d(244): Error: template instance toImpl!(string) errors instantiating template Here's the code. What am I doing wrong ... ? / import std.stdio; mixin template GenOne(T) { void generate() { foreach(size_t i, ref T x; this.array) x = i; } } mixin template GenThree(T) { void generate() { foreach(size_t i, ref T x; this.array) x = 3*i; } } mixin template WriteOne(T) { void myWrite() { foreach(T x; this.array) writeln(x); } } mixin template WriteTwo(T) { void myWrite() { foreach(T x; this.array) writeln(2*x); } } struct MyStruct(T, alias GeneratePolicy, alias WritePolicy) { private T[] array; this(size_t n) { array.length = n; generate; } mixin GeneratePolicy!T; mixin WritePolicy!T; } void main() { auto oneOne = MyStruct!(size_t, GenOne, WriteOne); auto oneTwo = MyStruct!(double, GenOne, WriteTwo); auto threeOne = MyStruct!(double, GenThree, WriteOne); auto threeTwo = MyStruct!(long, GenThree, WriteTwo); oneOne.myWrite; writeln; oneTwo.myWrite; writeln; threeOne.myWrite; writeln; threeTwo.myWrite; writeln; } /
Re: Equivalents to policy classes in D
On 4/20/12, Joseph Rushton Wakeling joseph.wakel...@webdrake.net wrote: void main() { auto oneOne = MyStruct!(size_t, GenOne, WriteOne); auto oneTwo = MyStruct!(double, GenOne, WriteTwo); auto threeOne = MyStruct!(double, GenThree, WriteOne); auto threeTwo = MyStruct!(long, GenThree, WriteTwo); } You're doing the equivalent of: auto one = Foo; but you need: auto one = Foo(); so: auto oneOne = MyStruct!(size_t, GenOne, WriteOne)(); auto oneTwo = MyStruct!(double, GenOne, WriteTwo)(); auto threeOne = MyStruct!(double, GenThree, WriteOne)(); auto threeTwo = MyStruct!(long, GenThree, WriteTwo)();
Re: Equivalents to policy classes in D
On 20/04/12 04:41, Andrej Mitrovic wrote: You're doing the equivalent of: auto one = Foo; but you need: auto one = Foo(); Ah, clear. I'm an idiot -- I wrote my own constructor requiring a number as input! That said, I'm surprised that it accepts the () given that the constructor does ask for a number. Even if I put in place an in-contract with assert(n 0), it doesn't throw an exception ...
Re: Equivalents to policy classes in D
On 4/20/12, Joseph Rushton Wakeling joseph.wakel...@webdrake.net wrote: That said, I'm surprised that it accepts the () given that the constructor does ask for a number. You can use: @disable this(); But it doesn't work in all cases: struct Foo { @disable this(); this(int i) { } } void main() { Foo foo; // error, OK auto foo = Foo(); // no error } I don't know if this is by design..