Re: dmd 1.057 and 2.041 release
Thanks! A pleasant surprise to see interface contracts.
Re: dmd 1.057 and 2.041 release
Walter Bright newshou...@digitalmars.com wrote: Lots of meat and potatoes here, and a cookie! (spelling checker for error messages) http://www.digitalmars.com/d/1.0/changelog.html http://ftp.digitalmars.com/dmd.1.057.zip http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.041.zip Thanks to the many people who contributed to this update! I don't know what to find more awesome with this update - possibly the operator overloading. Thanks a bunch, guys! -- Simen
Re: dmd 1.057 and 2.041 release
Simen kjaeraas wrote: Walter Bright newshou...@digitalmars.com wrote: Lots of meat and potatoes here, and a cookie! (spelling checker for error messages) http://www.digitalmars.com/d/1.0/changelog.html http://ftp.digitalmars.com/dmd.1.057.zip http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.041.zip Thanks to the many people who contributed to this update! I don't know what to find more awesome with this update - possibly the operator overloading. Thanks a bunch, guys! I just noticed that Steven Schveighoffer's array append patch made it into this release. That ranks pretty high on the awesome scale too. :) -Lars
Re: dmd 1.057 and 2.041 release
Walter Bright wrote: Lots of meat and potatoes here, and a cookie! (spelling checker for error messages) http://www.digitalmars.com/d/1.0/changelog.html http://ftp.digitalmars.com/dmd.1.057.zip http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.041.zip Thanks to the many people who contributed to this update! It seems array literals have become dynamic arrays, but I can't find any mention of that in the change log. pragma(msg, typeof([1,2,3]).stringof); // Prints int[3u] with DMD 2.040 // Prints int[] with DMD 2.041 -Lars
Re: DSFML2
C:\Jpro\dpro\smallxfbuild xft.d Thread 1: compiling 1 modules Thread 0: compiling 0 modules Error: unrecognized switch '-deps=xft.moduleDeps' Build failed: dmd @xfbuild.1660e00.rsp returned 1 Yeah it still has its quirks. Feel free to contact the authors/file an issue/etc.
Re: dmd 1.057 and 2.041 release
On Mon, 08 Mar 2010 09:54:12 +0300, Walter Bright newshou...@digitalmars.com wrote: Lots of meat and potatoes here, and a cookie! (spelling checker for error messages) http://www.digitalmars.com/d/1.0/changelog.html http://ftp.digitalmars.com/dmd.1.057.zip http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.041.zip Thanks to the many people who contributed to this update! Thank! BTW, 2.0 changelog page is messed up again
Re: dmd 1.057 and 2.041 release
On Mon, 08 Mar 2010 03:45:21 -0500, Lars T. Kyllingstad pub...@kyllingen.nospamnet wrote: Simen kjaeraas wrote: Walter Bright newshou...@digitalmars.com wrote: Lots of meat and potatoes here, and a cookie! (spelling checker for error messages) http://www.digitalmars.com/d/1.0/changelog.html http://ftp.digitalmars.com/dmd.1.057.zip http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.041.zip Thanks to the many people who contributed to this update! I don't know what to find more awesome with this update - possibly the operator overloading. Thanks a bunch, guys! I just noticed that Steven Schveighoffer's array append patch made it into this release. That ranks pretty high on the awesome scale too. :) Thanks :) One note that was not mentioned on the changelog, there are three new runtime functions for arrays. They are in object.di (and the docs are there too): * setCapacity(T[] arr, int newcapacity): preallocate at least newcapacity elements. This is intended to replace the set length to zero trick. * @property capacity(T[] arr): get the capacity (yes, it's a property, ddoc does not propogate the @property attribute) * shrinkToFit(T[] arr): This one is a bit tricky and technically unsafe. It reduces the size of the allocated length to fit the length of the array. The allocated length is the length that the runtime assumes is being used of the memory block. This is what aids in preventing stomping, so use with care. You can achieve stomping if you use shrinkToFit on a slice, but still have references to the trimmed data. Example: string s = 12345.idup; string slice = s[0..2]; slice.shrinkToFit(); // tells the runtime that you will no longer use any data beyond the slice slice ~= 00; // appends in place, overwriting immutable data referenced in s! Using s after such usage results in undefined behavior (probably should be noted in the docs). The use case is when you want to reuse a buffer when you know you will not use the trimmed area again. You can consider the trimmed off data unallocated. The shrinkToFit name is not my favorite, anyone care to submit a better name? minimize is out because it has connotations of math already. setCapacity will be changed in the next release to reserve() (could not squeeze that change in), since it was pointed out that you are requesting a capacity, not setting it. -Steve
Re: dmd 1.057 and 2.041 release
Walter Bright wrote: Lots of meat and potatoes here, and a cookie! (spelling checker for error messages) http://www.digitalmars.com/d/1.0/changelog.html http://ftp.digitalmars.com/dmd.1.057.zip http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.041.zip Thanks to the many people who contributed to this update! bearophile must be very happy :-) - Add !in operator. - opCast(bool) and implicit call in if But I don't like this: This only happens, however, for instances of structs. Class references are converted to bool by checking to see if the class reference is null or not. When I do: if (x) { } I'm normally interested to enter the if branch if x is not null and it has an interesting value. For example, if I implement a String class I would implement it as not being empty. But I think the biggest problem is making a different semantic for this to structs and classes. You'll have programmers wondering why the if branch was entered even if my class implemented opBool not to enter it. But time will tell. For opCast maybe it would be better to have some examples, like: T opCast(T)() if (is(T == bool)) { } T opCast(T)() if (is(T == int)) { } (it's not very intuitive that I have to do that to implement opCast, it's different from the other operator overloading that rely on strings) But very cool that opCast to many different types is implemented! :-)
Re: dmd 1.057 and 2.041 release
Walter Bright Wrote: Lots of meat and potatoes here, and a cookie! (spelling checker for error messages) Thank you for the cookie too :-) I will need some more time to try all the new things. In the meantime I have already two small questions: 1) What does Implemented attributes for constructors in the changelog means? 2) What's the best way to translate this to the new operator regime? T foo(T)(T s) if (__traits(hasMember, T, opAdd)) { return s + s; } I will probably write something more later, bye and thank you, bearophile
Re: dmd 1.057 and 2.041 release
Ary Borenszweig wrote: Walter Bright wrote: Lots of meat and potatoes here, and a cookie! (spelling checker for error messages) http://www.digitalmars.com/d/1.0/changelog.html http://ftp.digitalmars.com/dmd.1.057.zip http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.041.zip Thanks to the many people who contributed to this update! bearophile must be very happy :-) - Add !in operator. - opCast(bool) and implicit call in if But I don't like this: This only happens, however, for instances of structs. Class references are converted to bool by checking to see if the class reference is null or not. When I do: if (x) { } I'm normally interested to enter the if branch if x is not null and it has an interesting value. For example, if I implement a String class I would implement it as not being empty. But I think the biggest problem is making a different semantic for this to structs and classes. You'll have programmers wondering why the if branch was entered even if my class implemented opBool not to enter it. But time will tell. For opCast maybe it would be better to have some examples, like: T opCast(T)() if (is(T == bool)) { } T opCast(T)() if (is(T == int)) { } (it's not very intuitive that I have to do that to implement opCast, it's different from the other operator overloading that rely on strings) But very cool that opCast to many different types is implemented! :-) And isn't it better for the spellchecker to show the closest match using levenshtein distance instead of just distance 1?
Re: dmd 1.057 and 2.041 release
The Html of the change logs seems a bit wrong, the latest version now is at the top, and in the 2.0 changelog the Bugs Fixed are divided in two different horizontal alignments.
Re: dmd 1.057 and 2.041 release
Ary Borenszweig: And isn't it better for the spellchecker to show the closest match using levenshtein distance instead of just distance 1? Walter is an engineer, and follows the KISS principle, he likes to use the simpler thing that can possibly work (especially in the first version of something). I think the current spellchecker can be good enough. Bye, bearophile
Re: dmd 1.057 and 2.041 release
Ary Borenszweig: I'm normally interested to enter the if branch if x is not null and it has an interesting value. For example, if I implement a String class I would implement it as not being empty. But I think the biggest problem is making a different semantic for this to structs and classes. You'll have programmers wondering why the if branch was entered even if my class implemented opBool not to enter it. But time will tell. A solution can be to disallow opCast!(bool) in classes. So when in your code you convert a struct (that already defines opCast!(bool)) to a class, or when you try to add opCast!(bool) to a class, the compiler gives you a nice compilation error, and saves you from possible bugs. A warning too can be better than nothing. For opCast maybe it would be better to have some examples, like: T opCast(T)() if (is(T == bool)) { } T opCast(T)() if (is(T == int)) { } (it's not very intuitive that I have to do that to implement opCast, it's different from the other operator overloading that rely on strings) This works: import std.stdio: writeln; struct Foo { int len; this(int x) { this.len = x; } T opCast(T:bool)() { return this.len != 0; } T opCast(T:int)() { return this.len; } } void main() { auto f = Foo(5); if (f) writeln(true); else writeln(false); writeln(cast(int)f); } Bye, bearophile
Re: dmd 1.057 and 2.041 release
bearophile wrote: Ary Borenszweig: I'm normally interested to enter the if branch if x is not null and it has an interesting value. For example, if I implement a String class I would implement it as not being empty. But I think the biggest problem is making a different semantic for this to structs and classes. You'll have programmers wondering why the if branch was entered even if my class implemented opBool not to enter it. But time will tell. A solution can be to disallow opCast!(bool) in classes. So when in your code you convert a struct (that already defines opCast!(bool)) to a class, or when you try to add opCast!(bool) to a class, the compiler gives you a nice compilation error, and saves you from possible bugs. A warning too can be better than nothing. For opCast maybe it would be better to have some examples, like: T opCast(T)() if (is(T == bool)) { } T opCast(T)() if (is(T == int)) { } (it's not very intuitive that I have to do that to implement opCast, it's different from the other operator overloading that rely on strings) This works: import std.stdio: writeln; struct Foo { int len; this(int x) { this.len = x; } T opCast(T:bool)() { return this.len != 0; } T opCast(T:int)() { return this.len; } } Cool! Much, much nicer. (that's why I think some examples would be fine there)
Re: dmd 1.057 and 2.041 release
Is there a better way to use the new operator overloading than string mixins? Also the following code strangely yields: dsfml\system\vector2.d(47): Error: variable dsfml.system.vector2.Vector2!(float).Vector2.op only parameters or foreach declarations can be ref /// element-wise operations, +, -, ref Vector2 opBinary(string op)(ref Vector2 v) { mixin(return Vector2!(T)( cast(T)(x ~ op ~ v.x), cast(T)(y ~ op ~ v.y) );); } Removing ref from the return type makes it compile. Furthermore the assignment operator seems to be rewritten as opBinary instead of opAssign as the docs state: Vector2f_pos = Vector2f(0.f, 0.f); yields: Error: template instance opBinary!(=) matches more than one template declaration This also shows another problem. It can't distinguish between these two: Vector2 opBinary(string op)(ref Vector2 v) if (op != *) { mixin(return Vector2!(T)( cast(T)(x ~ op ~ v.x), cast(T)(y ~ op ~ v.y) );); } Vector2 opBinary(string op)(int i) { mixin(return Vector2!(T) ( cast(T)(x ~ op ~ i), cast(T)(y ~ op ~ i) );); } even though vec1 + vec2 resp. vec + 5 is unambiguous.
Re: dmd 1.057 and 2.041 release
__traits allMembers and and derivedMembers now return a tuple of strings rather than an array of strings. Enclose __traits in [ ] to make array literal. This makes it possible for foreach statements to iterate at compile time over it. How exciting! On 3/8/10, Trass3r u...@known.com wrote: Is there a better way to use the new operator overloading than string mixins? Also the following code strangely yields: dsfml\system\vector2.d(47): Error: variable dsfml.system.vector2.Vector2!(float).Vector2.op only parameters or foreach declarations can be ref /// element-wise operations, +, -, ref Vector2 opBinary(string op)(ref Vector2 v) { mixin(return Vector2!(T)( cast(T)(x ~ op ~ v.x), cast(T)(y ~ op ~ v.y) );); } Removing ref from the return type makes it compile. Furthermore the assignment operator seems to be rewritten as opBinary instead of opAssign as the docs state: Vector2f _pos = Vector2f(0.f, 0.f); yields: Error: template instance opBinary!(=) matches more than one template declaration This also shows another problem. It can't distinguish between these two: Vector2 opBinary(string op)(ref Vector2 v) if (op != *) { mixin(return Vector2!(T)( cast(T)(x ~ op ~ v.x), cast(T)(y ~ op ~ v.y) );); } Vector2 opBinary(string op)(int i) { mixin(return Vector2!(T) ( cast(T)(x ~ op ~ i), cast(T)(y ~ op ~ i) );); } even though vec1 + vec2 resp. vec + 5 is unambiguous.
Re: dmd 1.057 and 2.041 release
Walter Bright wrote: Lots of meat and potatoes here, and a cookie! (spelling checker for error messages) http://www.digitalmars.com/d/1.0/changelog.html http://ftp.digitalmars.com/dmd.1.057.zip http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.041.zip Thanks to the many people who contributed to this update! A few changes that I made to Phobos and also put in the changelog don't appear in this release because I forgot to commit changelog.dd itself. $(WHATSNEW $(LI string, wstring are now bidirectional (not random) ranges) $(LI std.algorithm: defined move with one argument; levenshtein distance generalized to with all forward ranges; take now has swapped arguments) $(LI std.array: empty for arrays is now a @property; front and back for a string and wstring automatically decodes the first/last character; popFront, popBack for string and wstring obey the UTF stride) $(LI std.conv: changed the default array formatting from [a, b, c] to a b c) $(LI std.range: swapped order of arguments in take) $(LI std.stdio: added readln template) $(LI std.variant: now works with statically-sized arrays and const data) $(LI std.traits: added isNarrowString) ) Andrei
Re: dmd 1.057 and 2.041 release
Walter Bright wrote: Lots of meat and potatoes here, and a cookie! (spelling checker for error messages) http://www.digitalmars.com/d/1.0/changelog.html http://ftp.digitalmars.com/dmd.1.057.zip http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.041.zip Thanks to the many people who contributed to this update! A few changes that I made to Phobos and also put in the changelog don't appear in this release because I forgot to commit changelog.dd itself. $(WHATSNEW $(LI string, wstring are now bidirectional (not random) ranges) $(LI std.algorithm: defined move with one argument; levenshtein distance generalized to with all forward ranges; take now has swapped arguments) $(LI std.array: empty for arrays is now a @property; front and back for a string and wstring automatically decodes the first/last character; popFront, popBack for string and wstring obey the UTF stride) $(LI std.conv: changed the default array formatting from [a, b, c] to a b c) $(LI std.range: swapped order of arguments in take) $(LI std.stdio: added readln template) $(LI std.variant: now works with statically-sized arrays and const data) $(LI std.traits: added isNarrowString) ) Andrei
Re: dmd 1.057 and 2.041 release
Andrei Alexandrescu: $(LI std.conv: changed the default array formatting from [a, b, c] to a b c) That's a regression!!! (And I think in the past it was [a,b,c] instead of [a, b, c], because it's better to save some screen space, it costs a lot!). Bye, bearophile
Re: dmd 1.057 and 2.041 release
Walter Bright wrote: Lots of meat and potatoes here, and a cookie! (spelling checker for error messages) http://www.digitalmars.com/d/1.0/changelog.html http://ftp.digitalmars.com/dmd.1.057.zip http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.041.zip Thanks to the many people who contributed to this update! Bug 1914 Array initialisation from const array yields memory trample was fixed, in D2 only. Can we get this into D1 as well? To show what a huge difference this bug makes, try this test case for large values of N: Executable size in bytes N D2.040 D2.041 ------ -- 10 266 Kb 241 Kb 100 306 Kb 241 Kb 2000 16151 Kb 257 Kb 10K locks up 321 Kb - enum : int { N = 1000 } struct S { const float[N] BIGINIT = [7]; float a[N] = BIGINIT; } void main() {}
Re: dmd 1.057 and 2.041 release
bearophile wrote: Andrei Alexandrescu: $(LI std.conv: changed the default array formatting from [a, b, c] to a b c) That's a regression!!! (And I think in the past it was [a,b,c] instead of [a, b, c], because it's better to save some screen space, it costs a lot!). Sorry, this stays. The idea behind the change is to make 'to' a minimalistic function that makes minimum assumptions (e.g. the comma may be a decimal point in some languages, so is [1,2] in a German locale an array of double with one value or two? etc. The canonical to prints values separated by one space. Why one space? It's the most neutral thing I could think of. Why no brackets? Because of minimalism. You can very easy add them if you want them. Andrei
Re: dmd 1.057 and 2.041 release
If you compile a program like this: double[100_000] arr; void main() {} With dmd you produce a binary about 1 MB in size, because doubles in D are not filled with zero. So for n-D arrays bigger than a certain amount of memory, can DMD compile that code with a zero initialization plus filling of the Nans at run-time? Note: this produces the same very large binary, I don't know why: double[100_000] arr = void; static this() { arr[] = typeof(arr[0]).init; } void main() {} While this hangs my compiler, I don't know why: double[100_000] arr = 0.0; static this() { arr[] = typeof(arr[0]).init; } void main() {} Bye, bearophile
Re: dmd 1.057 and 2.041 release
On Mon, 08 Mar 2010 14:27:36 -0500, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: bearophile wrote: Andrei Alexandrescu: $(LI std.conv: changed the default array formatting from [a, b, c] to a b c) That's a regression!!! (And I think in the past it was [a,b,c] instead of [a, b, c], because it's better to save some screen space, it costs a lot!). Sorry, this stays. The idea behind the change is to make 'to' a minimalistic function that makes minimum assumptions (e.g. the comma may be a decimal point in some languages, so is [1,2] in a German locale an array of double with one value or two? etc. The canonical to prints values separated by one space. Why one space? It's the most neutral thing I could think of. Why no brackets? Because of minimalism. You can very easy add them if you want them. What about an array of strings with spaces in them? Or an array of arrays? Is there at least a way to force 'to' to format the way you want? I tend to side with bearophile on this one... -Steve
Re: dmd 1.057 and 2.041 release
Andrei Alexandrescu: Sorry, this stays. Then I'm not going to use the Phobos printing in all my future D2 programs. As I was not using it in D1. I'm not going to change idea on this. (e.g. the comma may be a decimal point in some languages, so is [1,2] in a German locale an array of double with one value or two? In German you need no space after the comma, and there's no [] after and before it. So [1, 2] is not a floating point value in German. Why one space? Because that's they way people print things in natural languages. It's a convention, you know. And it's a good one. It tells apart the FP numbers and it's the minimal. It's the most neutral thing I could think of. Why no brackets? Because of minimalism. You can very easy add them if you want them. The purpose of things like the square brackets is to give a less ambiguous textual representation of the most common data structures (array and strings are the most common after numbers). So you put or '' around strings and [] to know what you are printing.
Re: dmd 1.057 and 2.041 release
Steven Schveighoffer wrote: On Mon, 08 Mar 2010 14:27:36 -0500, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: bearophile wrote: Andrei Alexandrescu: $(LI std.conv: changed the default array formatting from [a, b, c] to a b c) That's a regression!!! (And I think in the past it was [a,b,c] instead of [a, b, c], because it's better to save some screen space, it costs a lot!). Sorry, this stays. The idea behind the change is to make 'to' a minimalistic function that makes minimum assumptions (e.g. the comma may be a decimal point in some languages, so is [1,2] in a German locale an array of double with one value or two? etc. The canonical to prints values separated by one space. Why one space? It's the most neutral thing I could think of. Why no brackets? Because of minimalism. You can very easy add them if you want them. What about an array of strings with spaces in them? Or an array of arrays? Is there at least a way to force 'to' to format the way you want? Yes, you may specify the separator. Andrei
Re: dmd 1.057 and 2.041 release
bearophile wrote: Andrei Alexandrescu: Sorry, this stays. Then I'm not going to use the Phobos printing in all my future D2 programs. As I was not using it in D1. I'm not going to change idea on this. (e.g. the comma may be a decimal point in some languages, so is [1,2] in a German locale an array of double with one value or two? In German you need no space after the comma, and there's no [] after and before it. So [1, 2] is not a floating point value in German. Why one space? Because that's they way people print things in natural languages. It's a convention, you know. And it's a good one. It tells apart the FP numbers and it's the minimal. It's the most neutral thing I could think of. Why no brackets? Because of minimalism. You can very easy add them if you want them. The purpose of things like the square brackets is to give a less ambiguous textual representation of the most common data structures (array and strings are the most common after numbers). So you put or '' around strings and [] to know what you are printing. Your choice of leading/trailing symbols and of separators makes 'to' friendlier for printing e.g. debug strings. My choice makes it a primitive for text serialization. I'm not 100% sure which is the more frequent use and therefore which is the most appropriate as a default, but I'm leaning towards the latter. Andrei
Re: dmd 1.057 and 2.041 release
Steven Schveighoffer wrote: On Mon, 08 Mar 2010 14:27:36 -0500, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: bearophile wrote: Andrei Alexandrescu: $(LI std.conv: changed the default array formatting from [a, b, c] to a b c) That's a regression!!! (And I think in the past it was [a,b,c] instead of [a, b, c], because it's better to save some screen space, it costs a lot!). Sorry, this stays. The idea behind the change is to make 'to' a minimalistic function that makes minimum assumptions (e.g. the comma may be a decimal point in some languages, so is [1,2] in a German locale an array of double with one value or two? etc. The canonical to prints values separated by one space. Why one space? It's the most neutral thing I could think of. Why no brackets? Because of minimalism. You can very easy add them if you want them. What about an array of strings with spaces in them? Or an array of arrays? Is there at least a way to force 'to' to format the way you want? auto s = to!string([1,2,3], [, , , ]); -Lars
Re: dmd 1.057 and 2.041 release
On Mon, 08 Mar 2010 14:49:33 -0500, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: bearophile wrote: Andrei Alexandrescu: Sorry, this stays. Then I'm not going to use the Phobos printing in all my future D2 programs. As I was not using it in D1. I'm not going to change idea on this. (e.g. the comma may be a decimal point in some languages, so is [1,2] in a German locale an array of double with one value or two? In German you need no space after the comma, and there's no [] after and before it. So [1, 2] is not a floating point value in German. Why one space? Because that's they way people print things in natural languages. It's a convention, you know. And it's a good one. It tells apart the FP numbers and it's the minimal. It's the most neutral thing I could think of. Why no brackets? Because of minimalism. You can very easy add them if you want them. The purpose of things like the square brackets is to give a less ambiguous textual representation of the most common data structures (array and strings are the most common after numbers). So you put or '' around strings and [] to know what you are printing. Your choice of leading/trailing symbols and of separators makes 'to' friendlier for printing e.g. debug strings. My choice makes it a primitive for text serialization. I'm not 100% sure which is the more frequent use and therefore which is the most appropriate as a default, but I'm leaning towards the latter. No it doesn't. Tell me how you would parse the following text serialization string for a string[]: hello world how are you What if it was a string[][]? Compare that to: [hello world, [how are, you]] That is almost completely unambiguous (you still have to account for literal commas or brackets), whereas you have a multitude of choices with the first version. The thing is, friendlier for text-based serialization is almost identical to friendlier for printing. In fact, friendlier for text-based serialization should have even more annotations to escape delimiters. In fact, I find the defaults you defined not useful in most cases. Printing or serializing, I want to see the delimiters for the arrays, elements, and subarrays. -Steve
Re: dmd 1.057 and 2.041 release
bearophile wrote: While this hangs my compiler, I don't know why: double[100_000] arr = 0.0; static this() { arr[] = typeof(arr[0]).init; } void main() {} Well, it didn't hang, it just took a while. I found the problem.
Re: dmd 1.057 and 2.041 release
Steven Schveighoffer: Tell me how you would parse the following text serialization string for a string[]: hello world how are you What if it was a string[][]? Compare that to: [hello world, [how are, you]] You are missing something: [hello world, [how are, you]] :-) (And yes, there are simple solutions if the strings contains or '). Bye, bearophile
Re: dmd 1.057 and 2.041 release
bearophile wrote: Note: this produces the same very large binary, I don't know why: double[100_000] arr = void; static this() { arr[] = typeof(arr[0]).init; } void main() {} obj2asm tells the tale. (obj2asm is an incredibly useful tool, I don't know why nobody uses it.) double[100_000] arr = void; puts arr in the thread local storage segment. Unfortunately, there is no bss for TLS. __gshared double[100_000] arr = void; puts arr in the BSS segment, which takes up space in your executable but not the executable *file*.
Re: dmd 1.057 and 2.041 release
Don wrote: Bug 1914 Array initialisation from const array yields memory trample was fixed, in D2 only. Can we get this into D1 as well? The problem is I don't think it's the right fix, and I haven't spent the time figuring it out yet.
Re: dmd 1.057 and 2.041 release
Andrei Alexandrescu: Your choice of leading/trailing symbols and of separators makes 'to' friendlier for printing e.g. debug strings. My choice makes it a primitive for text serialization. I'm not 100% sure which is the more frequent use and therefore which is the most appropriate as a default, but I'm leaning towards the latter. Sorry for losing my temper about this in my last posts. In Python they have faced this problem using two different things, str() and repr(), the first one produces a little more readable output, used for normal reading, and then second is a little more for textual serialization (But both use the []). The shell outputs using repr(), the print uses str(), the items inside collections are always represented with repr(). Objects can define the __repr__ and __str__. Print calls the __str__. If __str__ is missing it's used __repr__. I like handy defaults, they save time iff they are well chosen. Bye, bearophile
Re: dmd 1.057 and 2.041 release
On Mon, 08 Mar 2010 15:12:24 -0500, bearophile bearophileh...@lycos.com wrote: Steven Schveighoffer: Tell me how you would parse the following text serialization string for a string[]: hello world how are you What if it was a string[][]? Compare that to: [hello world, [how are, you]] You are missing something: [hello world, [how are, you]] For completely unambiguous, yes. But still, I find often that quotes are more noise than they are worth when just doing simple printouts. What we want is the most useful default. Also, the desired output I would like is: T[] = [T1, T2, ..., Tn] This would mean that strings have a special case of printing with quotes only when printed inside an array. This seems like an oddity to me. -Steve
Re: dmd 1.057 and 2.041 release
Steven Schveighoffer: For completely unambiguous, yes. But still, I find often that quotes are more noise than they are worth when just doing simple printouts. What we want is the most useful default. Quotes add a bit of noise, but I prefer to tell apart the cases of two strings from the case of one string with a comma in the middle. This would mean that strings have a special case of printing with quotes only when printed inside an array. This seems like an oddity to me. It's how Python works, that's why there are __repr__ and __str__ for objects, the repr of a string includes the quotes, its __str__ doesn't. a = [hello world, [that's right!, you]] a ['hello world', [that's right!, 'you']] print a ['hello world', [that's right!, 'you']] a[0] 'hello world' print a[0] hello world Notes: - that 'a' contains a string and an array of strings, you usually can't do this in D, so this is not a fully representative example; - Python is dynamically typed, so it's more important that what you print shows its type. In D you can often tell it looking at type of the variable you print (unless it's hidden by a labyrinth of 'auto'). Bye, bearophile
Re: dmd 1.057 and 2.041 release
Steven Schveighoffer wrote: On Mon, 08 Mar 2010 14:49:33 -0500, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: bearophile wrote: Andrei Alexandrescu: Sorry, this stays. Then I'm not going to use the Phobos printing in all my future D2 programs. As I was not using it in D1. I'm not going to change idea on this. (e.g. the comma may be a decimal point in some languages, so is [1,2] in a German locale an array of double with one value or two? In German you need no space after the comma, and there's no [] after and before it. So [1, 2] is not a floating point value in German. Why one space? Because that's they way people print things in natural languages. It's a convention, you know. And it's a good one. It tells apart the FP numbers and it's the minimal. It's the most neutral thing I could think of. Why no brackets? Because of minimalism. You can very easy add them if you want them. The purpose of things like the square brackets is to give a less ambiguous textual representation of the most common data structures (array and strings are the most common after numbers). So you put or '' around strings and [] to know what you are printing. Your choice of leading/trailing symbols and of separators makes 'to' friendlier for printing e.g. debug strings. My choice makes it a primitive for text serialization. I'm not 100% sure which is the more frequent use and therefore which is the most appropriate as a default, but I'm leaning towards the latter. No it doesn't. Tell me how you would parse the following text serialization string for a string[]: hello world how are you What if it was a string[][]? Compare that to: [hello world, [how are, you]] That is almost completely unambiguous (you still have to account for literal commas or brackets), whereas you have a multitude of choices with the first version. I said a primitive for serialization, not a serialization infrastructure. So the basic idea is that you use to in conjunctions with your own routines to serialize things. to imposes no policy. Using [, , , and ] is policy. The thing is, friendlier for text-based serialization is almost identical to friendlier for printing. In fact, friendlier for text-based serialization should have even more annotations to escape delimiters. In fact, I find the defaults you defined not useful in most cases. Printing or serializing, I want to see the delimiters for the arrays, elements, and subarrays. You can choose them no problem. std.conv gives you mechanism, you choose the policy. Andrei
Re: obj2asm
obj2asm tells the tale. (obj2asm is an incredibly useful tool, I don't know why nobody uses it.) Maybe because it's not free (and not much advertised). obconv also supports disassembling various object file formats + conversion between them and it's open source: http://www.agner.org/optimize/#objconv obj2asm might provide something fancy that objconv doesn't but its page doesn't show anything that would justify paying 10$.
Re: obj2asm
On Mon, Mar 08, 2010 at 04:12:00PM -0500, Trass3r wrote: Maybe because it's not free (and not much advertised). The linux version comes in the zip right along side dmd. -- Adam D. Ruppe http://arsdnet.net
Re: dmd 1.057 and 2.041 release
I think this bug has been squished as well. Both test cases now compile fine. http://d.puremagic.com/issues/show_bug.cgi?id=3694 Walter Bright wrote: Lots of meat and potatoes here, and a cookie! (spelling checker for error messages) http://www.digitalmars.com/d/1.0/changelog.html http://ftp.digitalmars.com/dmd.1.057.zip http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.041.zip Thanks to the many people who contributed to this update!
Re: dmd 1.057 and 2.041 release
On Mon, Mar 8, 2010 at 14:22, Steven Schveighoffer schvei...@yahoo.comwrote: The shrinkToFit name is not my favorite, anyone care to submit a better name? minimize is out because it has connotations of math already. minCapacity minimizeCapacity shrinkCapacity shrink (just shrink) releaseCapacity compacify fitCapacity minFit??? reduceToFit contract minify adjust Philippe
Re: obj2asm
The linux version comes in the zip right along side dmd. Indeed. Even the OSX folder contains obj2asm. The windows version is missing.
Re: dmd 1.057 and 2.041 release
2) What's the best way to translate this to the new operator regime? T foo(T)(T s) if (__traits(hasMember, T, opAdd)) { return s + s; } I have not found a good solution yet. This solution looks buggy (also because fixed-sized arrays have a buggy .init): import std.stdio: writeln; struct Foo { int x; this(int xx) { this.x = xx; } Foo opBinary(string s:+)(Foo other) { return Foo(this.x * other.x); } } T foo(T)(T s) if (__traits(compiles, {return T.init + T.init;})) { return s + s; // line 14 } void main() { auto f1 = Foo(2); auto f2 = Foo(3); writeln(f1 + f2); writeln(foo(f1)); int[2] a = [1, 2]; writeln(typeid(typeof(a.init))); // prints: int writeln(foo(a)); // test.d(14): Error: Array operation s + s not implemented } Bye, bearophile
Re: dmd 1.057 and 2.041 release
On Mon, 08 Mar 2010 15:56:14 -0500, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: Steven Schveighoffer wrote: On Mon, 08 Mar 2010 14:49:33 -0500, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: bearophile wrote: Andrei Alexandrescu: Sorry, this stays. Then I'm not going to use the Phobos printing in all my future D2 programs. As I was not using it in D1. I'm not going to change idea on this. (e.g. the comma may be a decimal point in some languages, so is [1,2] in a German locale an array of double with one value or two? In German you need no space after the comma, and there's no [] after and before it. So [1, 2] is not a floating point value in German. Why one space? Because that's they way people print things in natural languages. It's a convention, you know. And it's a good one. It tells apart the FP numbers and it's the minimal. It's the most neutral thing I could think of. Why no brackets? Because of minimalism. You can very easy add them if you want them. The purpose of things like the square brackets is to give a less ambiguous textual representation of the most common data structures (array and strings are the most common after numbers). So you put or '' around strings and [] to know what you are printing. Your choice of leading/trailing symbols and of separators makes 'to' friendlier for printing e.g. debug strings. My choice makes it a primitive for text serialization. I'm not 100% sure which is the more frequent use and therefore which is the most appropriate as a default, but I'm leaning towards the latter. No it doesn't. Tell me how you would parse the following text serialization string for a string[]: hello world how are you What if it was a string[][]? Compare that to: [hello world, [how are, you]] That is almost completely unambiguous (you still have to account for literal commas or brackets), whereas you have a multitude of choices with the first version. I said a primitive for serialization, not a serialization infrastructure. So the basic idea is that you use to in conjunctions with your own routines to serialize things. to imposes no policy. Using [, , , and ] is policy. Reading the documentation, it appears that setting the policy means simply passing delimiters to the to function. That means that for every call to to, you specify the policy if it differs from the default. Since the default is not useful for serialization and confusing for printing, why would anyone use the default policy (aside from the obvious because it's annoying)? If you don't use the default policy, why have a default, why not require the policy for each call? The thing is, friendlier for text-based serialization is almost identical to friendlier for printing. In fact, friendlier for text-based serialization should have even more annotations to escape delimiters. In fact, I find the defaults you defined not useful in most cases. Printing or serializing, I want to see the delimiters for the arrays, elements, and subarrays. You can choose them no problem. std.conv gives you mechanism, you choose the policy. I can choose the policy for each call, that is not going to look very good, and be very tedious to write. Plus it's not recursive (this would actually be a huge problem if using to for serialization): import std.stdio; import std.conv; void main() { int[][] x = new int[][](2, 2); writeln(to!string(x, [, ,, ])); } outputs [0 0,0 0] I would expect [[0,0],[0,0]] I'll also point out that AAs have a default policy that is much more reasonable. -Steve
Re: obj2asm
Trass3r wrote: The linux version comes in the zip right along side dmd. Indeed. Even the OSX folder contains obj2asm. The windows version is missing. The best thing is, on Linux you can use binutils objdump just fine. I'm sure OSX has tools to inspect object files as well. Only on Windows, you're having a bad time: almost nothing can understand digitalmars-omf.
Re: dmd 1.057 and 2.041 release
On 08/03/10 22:03, bearophile wrote: 2) What's the best way to translate this to the new operator regime? T foo(T)(T s) if (__traits(hasMember, T, opAdd)) { return s + s; } I have not found a good solution yet. This solution looks buggy (also because fixed-sized arrays have a buggy .init): -snip- T foo(T)(T s) if (__traits(compiles, {return T.init + T.init;})) { return s + s; // line 14 } Untested, will the following do what you need? T foo(T)(T s) if (__traits(compiles, {return s + s;})) { return s + s; } Seems like you may as well test if you can add what you're passed rather than the initial value for the type.
Re: dmd 1.057 and 2.041 release
Steven Schveighoffer wrote: On Mon, 08 Mar 2010 15:56:14 -0500, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: Steven Schveighoffer wrote: On Mon, 08 Mar 2010 14:49:33 -0500, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: bearophile wrote: Andrei Alexandrescu: Sorry, this stays. Then I'm not going to use the Phobos printing in all my future D2 programs. As I was not using it in D1. I'm not going to change idea on this. (e.g. the comma may be a decimal point in some languages, so is [1,2] in a German locale an array of double with one value or two? In German you need no space after the comma, and there's no [] after and before it. So [1, 2] is not a floating point value in German. Why one space? Because that's they way people print things in natural languages. It's a convention, you know. And it's a good one. It tells apart the FP numbers and it's the minimal. It's the most neutral thing I could think of. Why no brackets? Because of minimalism. You can very easy add them if you want them. The purpose of things like the square brackets is to give a less ambiguous textual representation of the most common data structures (array and strings are the most common after numbers). So you put or '' around strings and [] to know what you are printing. Your choice of leading/trailing symbols and of separators makes 'to' friendlier for printing e.g. debug strings. My choice makes it a primitive for text serialization. I'm not 100% sure which is the more frequent use and therefore which is the most appropriate as a default, but I'm leaning towards the latter. No it doesn't. Tell me how you would parse the following text serialization string for a string[]: hello world how are you What if it was a string[][]? Compare that to: [hello world, [how are, you]] That is almost completely unambiguous (you still have to account for literal commas or brackets), whereas you have a multitude of choices with the first version. I said a primitive for serialization, not a serialization infrastructure. So the basic idea is that you use to in conjunctions with your own routines to serialize things. to imposes no policy. Using [, , , and ] is policy. Reading the documentation, it appears that setting the policy means simply passing delimiters to the to function. That means that for every call to to, you specify the policy if it differs from the default. I think it also means that you write your function that calls to inside, and use your function throughout. Since the default is not useful for serialization and confusing for printing, why would anyone use the default policy (aside from the obvious because it's annoying)? If you don't use the default policy, why have a default, why not require the policy for each call? Printing values with spaces between them is entirely fine for e.g. all numbers. The thing is, friendlier for text-based serialization is almost identical to friendlier for printing. In fact, friendlier for text-based serialization should have even more annotations to escape delimiters. In fact, I find the defaults you defined not useful in most cases. Printing or serializing, I want to see the delimiters for the arrays, elements, and subarrays. You can choose them no problem. std.conv gives you mechanism, you choose the policy. I can choose the policy for each call, that is not going to look very good, and be very tedious to write. Write your own function and call it. Plus it's not recursive (this would actually be a huge problem if using to for serialization): import std.stdio; import std.conv; void main() { int[][] x = new int[][](2, 2); writeln(to!string(x, [, ,, ])); } outputs [0 0,0 0] I would expect [[0,0],[0,0]] I'll also point out that AAs have a default policy that is much more reasonable. I guess that should be changed too :o). Andrei
Re: dmd 1.057 and 2.041 release
Robert Clipsham wrote: On 08/03/10 22:03, bearophile wrote: 2) What's the best way to translate this to the new operator regime? T foo(T)(T s) if (__traits(hasMember, T, opAdd)) { return s + s; } I have not found a good solution yet. This solution looks buggy (also because fixed-sized arrays have a buggy .init): -snip- T foo(T)(T s) if (__traits(compiles, {return T.init + T.init;})) { return s + s; // line 14 } Untested, will the following do what you need? T foo(T)(T s) if (__traits(compiles, {return s + s;})) { return s + s; } Seems like you may as well test if you can add what you're passed rather than the initial value for the type. What I usually do is: T foo(T)(T s) if (is(typeof(s + s))) { } Andrei
Re: dmd 1.057 and 2.041 release
Robert Clipsham: Untested, will the following do what you need? T foo(T)(T s) if (__traits(compiles, {return s + s;})) { return s + s; } Seems like you may as well test if you can add what you're passed rather than the initial value for the type. Oh, nice, I didn't remember you can also use values there and not just types. It becomes like this then: import std.stdio: writeln; struct Foo { int x; this(int xx) { this.x = xx; } Foo opBinary(string s:+)(Foo other) { return Foo(this.x * other.x); } } T foo(T)(T s) if (__traits(compiles, {return s + s;})) { return s + s; // line 14 } void main() { auto f1 = Foo(2); auto f2 = Foo(3); writeln(f1 + f2); writeln(foo(f1)); int[2] a = [1, 2]; writeln(typeid(typeof(a.init))); // prints: int writeln(foo(a)); // test.d(14): Error: Array operation s + s not implemented } But now I don't know what's happening, because that trait correctly returns false, but the compiler generates a compile error at line 14 still. I think there's a new bug. Bye, bearophile
Re: dmd 1.057 and 2.041 release
But now I don't know what's happening, because that trait correctly returns false, but the compiler generates a compile error at line 14 still. I think there's a new bug. I have added a bug: http://d.puremagic.com/issues/show_bug.cgi?id=3903 Bye, bearophile
Re: dmd 1.057 and 2.041 release
Andrei Alexandrescu: What I usually do is: T foo(T)(T s) if (is(typeof(s + s))) { } Nice, thank you, I'll use that. (That solution too presents the bug 3903) Bye, bearophile
Re: dmd 1.057 and 2.041 release
Andrei Alexandrescu: I'll also point out that AAs have a default policy that is much more reasonable. I guess that should be changed too :o). -.- Bye, bearophile
Re: dmd 1.057 and 2.041 release
On 08/03/10 22:53, Andrei Alexandrescu wrote: What I usually do is: T foo(T)(T s) if (is(typeof(s + s))) { } Andrei That's far nicer, I keep forgetting about is(typeof()), thanks :)
Re: dmd 1.057 and 2.041 release
writeln(typeid(typeof(a.init))); // prints: int ?! You mean typeof(a) != typeof((typeof(a)).init) ?! Ugh... I thought (int[2]).init was [0,0] and in general (T[n]).init was [(T.init) n times] writeln(foo(a)); // test.d(14): Error: Array operation s + s not implemented } But now I don't know what's happening, because that trait correctly returns false, but the compiler generates a compile error at line 14 still. I think there's a new bug I think your bug is this discrepancy between init's type and the original type. That needs a bug report by itself; in a template constraint, any value is at its type .init value, not its runtype value (obvious in retrospect) In your example {return s+s;} becomes {return 0+0;}, since the compiler wrongly infer (int[2]).init to be 0, a regular int. And your __traits return true: auto bar(T)(T t) { return __traits(compiles, {return t+t;});} int[2] a; writeln(bar(a)); // true! Philippe
Re: dmd 1.057 and 2.041 release
Robert Clipsham wrote: On 08/03/10 22:53, Andrei Alexandrescu wrote: What I usually do is: T foo(T)(T s) if (is(typeof(s + s))) { } Andrei That's far nicer, I keep forgetting about is(typeof()), thanks :) It'll be hard to forget once TDPL will be out there, the idiom is present in several places. Man I can't wait for that book to be out. Andrei
Re: dmd 1.057 and 2.041 release
Philippe Sigaud: writeln(typeid(typeof(a.init))); // prints: int ?! You mean typeof(a) != typeof((typeof(a)).init) ?! Ugh... I thought (int[2]).init was [0,0] and in general (T[n]).init was [(T.init) n times] http://d.puremagic.com/issues/show_bug.cgi?id=3826 Bye, bearophile
Re: dmd 1.057 and 2.041 release
On 08/03/10 23:35, Andrei Alexandrescu wrote: Man I can't wait for that book to be out. I suspect you're not the only one, I was filled with excitement when I saw the expected delivery date become earlier a few days ago, I'm eagerly awaiting it so I can start playing with D2 properly rather than just dabbling :)
Re: obj2asm
Trass3r wrote: obj2asm tells the tale. (obj2asm is an incredibly useful tool, I don't know why nobody uses it.) Maybe because it's not free (and not much advertised). obconv also supports disassembling various object file formats + conversion between them and it's open source: http://www.agner.org/optimize/#objconv obj2asm might provide something fancy that objconv doesn't but its page doesn't show anything that would justify paying 10$. At first glance, obj2asm will pretty-print the codeview debug info in the object file, and will mix source lines with corresponding assembler lines. Obj2asm also comes with a bunch of other utilities, any one of which is worth the $15 if you need them: ◦chmod Change/list file attributes ◦coff2omf Convert COFF object and lib files to OMF ◦diff Compare text files ◦diffdir Compare directory trees ◦dump Dump files ◦dumpexe Dump executable files ◦dumpobj Dump object files ◦flpyimg Read/Write floppy disk image ◦grep Search files for strings ◦libunres Scan libraries for unresolved externals ◦makedep Makefile dependency generator ◦obj2asm Object file disassembler ◦patchobj Patch object files ◦smake Advanced make program ◦whereis Search for files http://www.digitalmars.com/ctg/obj2asm.html
Re: dmd 1.057 and 2.041 release
To try the new operators I have created this helper that works: auto operators(string[] items...) { struct Bunch { string[] items; bool opBinaryRight(string s:in)(string item) { foreach (el; items) if (el == item) return true; return false; } } return Bunch(items); } struct Foo { int x; this(int xx) { this.x = xx; } // Foo opBinary(string s)(Foo other) if (s in [+, -, *, /]) { Foo opBinary(string s)(Foo other) if (s in operators(+, -, *, /)) { mixin(return Foo(this.x ~ s ~ other.x);); } } But I don't like that operators(), I'd like a more generic bunch() that works at compile time. I have found a long series of bugs and limits trying to do it... :-) This works at run-time only: auto bunch(Types...)(Types itemsTuple) { static struct Bunch { Types items; bool opBinaryRight(string s:in)(string item) { foreach (el; items) if (el == item) return true; return false; } } return Bunch(itemsTuple); } This never works, I don't know why: auto bunch(Types...)(Types itemsTuple) { struct Bunch { bool opBinaryRight(string s:in)(string item) { foreach (el; itemsTuple) if (el == item) return true; return false; } } return Bunch(); } Maybe there is no way to have a reference to the input argument tuple in a nonstatic nested struct, but this works: import std.stdio: writeln; auto equals_two(Types...)(Types items) { bool foo() { return items[0] == items[1]; } return foo; } void main() { writeln(equals_two(1, 2)()); } Notes: opBinaryRight(in) for arrays is useful even at compile time :-) While doing those experiments I have seen this is not supported, because T must be known: auto bunch(T)(T[] items...) { Bye, bearophile
Re: dmd 1.057 and 2.041 release
On Mon, 08 Mar 2010 16:42:54 -0500, Philippe Sigaud philippe.sig...@gmail.com wrote: On Mon, Mar 8, 2010 at 14:22, Steven Schveighoffer schvei...@yahoo.comwrote: The shrinkToFit name is not my favorite, anyone care to submit a better name? minimize is out because it has connotations of math already. minCapacity minimizeCapacity shrinkCapacity shrink (just shrink) releaseCapacity compacify fitCapacity minFit??? reduceToFit contract minify adjust Philippe compact