digitalmars.D.announce - dmd 1.057 and 2.041 release
- Walter Bright (7/7) Mar 07 2010 Lots of meat and potatoes here, and a cookie! (spelling checker for
- Lutger (1/1) Mar 07 2010 Thanks! A pleasant surprise to see interface contracts.
- Lars T. Kyllingstad (4/15) Mar 08 2010 This is great, thank you! I'm especially looking forward to playing
- Simen kjaeraas (5/12) Mar 08 2010 I don't know what to find more awesome with this update - possibly
- Lars T. Kyllingstad (4/20) Mar 08 2010 I just noticed that Steven Schveighoffer's array append patch made it
- Steven Schveighoffer (33/51) Mar 08 2010 Thanks :)
- Philippe Sigaud (14/16) Mar 08 2010 minCapacity
- Robert Jacques (3/21) Mar 08 2010 compact
- grauzone (8/36) Mar 09 2010 Many of these names (including shrinkToFit) suggest that memory usage is...
- Philippe Sigaud (6/13) Mar 09 2010 enableStomping?
- Nick Sabalausky (3/15) Mar 09 2010 placeUnderFoot?
- Bernard Helyer (2/8) Mar 10 2010 greekWedding?
- Lars T. Kyllingstad (7/18) Mar 08 2010 It seems array literals have become dynamic arrays, but I can't find any...
- Walter Bright (2/4) Mar 13 2010 I'll fix.
- Denis Koroskin (3/10) Mar 08 2010 Thank! BTW, 2.0 changelog page is messed up again
- Ary Borenszweig (24/35) Mar 08 2010 bearophile must be very happy :-)
- Ary Borenszweig (3/49) Mar 08 2010 And isn't it better for the spellchecker to show the closest match using...
- bearophile (4/6) Mar 08 2010 Walter is an engineer, and follows the KISS principle, he likes to use t...
- bearophile (27/43) Mar 08 2010 A solution can be to disallow opCast!(bool) in classes. So when in your ...
- Ary Borenszweig (3/44) Mar 08 2010 Cool! Much, much nicer. (that's why I think some examples would be fine
- bearophile (12/14) Mar 08 2010 Thank you for the cookie too :-)
- bearophile (1/1) Mar 08 2010 The Html of the change logs seems a bit wrong, the latest version now is...
- Steven Schveighoffer (39/46) Mar 08 2010 This might belong on d.learn, but it's so specific to this release, I'll...
- Trass3r (24/24) Mar 08 2010 Is there a better way to use the new operator overloading than string mi...
- Adam Ruppe (2/37) Mar 08 2010
- Andrei Alexandrescu (19/30) Mar 08 2010 A few changes that I made to Phobos and also put in the changelog don't
- bearophile (5/7) Mar 08 2010 That's a regression!!!
- Andrei Alexandrescu (9/15) Mar 08 2010 Sorry, this stays. The idea behind the change is to make 'to' a
- Steven Schveighoffer (6/20) Mar 08 2010 What about an array of strings with spaces in them? Or an array of
- Andrei Alexandrescu (3/25) Mar 08 2010 Yes, you may specify the separator.
- Lars T. Kyllingstad (3/25) Mar 08 2010 auto s = to!string([1,2,3], "[", ", ", "]");
- bearophile (6/10) Mar 08 2010 In German you need no space after the comma, and there's no [] after and...
- Andrei Alexandrescu (7/39) Mar 08 2010 Your choice of leading/trailing symbols and of separators makes 'to'
- Steven Schveighoffer (19/50) Mar 08 2010 No it doesn't.
- bearophile (7/17) Mar 08 2010 You are missing something:
- Steven Schveighoffer (10/24) Mar 08 2010 For completely unambiguous, yes. But still, I find often that quotes ar...
- bearophile (12/22) Mar 08 2010 It's how Python works, that's why there are __repr__ and __str__ for obj...
- Alexander Suhoverhov (13/28) Mar 09 2010 SS> For completely unambiguous, yes. But still, I find often that quot...
- Fawzi Mohamed (38/74) Mar 09 2010 For a basic output one can discuss what is better, but in general, for
- Steven Schveighoffer (11/40) Mar 09 2010 If you are used to writing code, you should be used to having commas. T...
- Fawzi Mohamed (18/66) Mar 09 2010 I don't know, I have something similar
- Andrei Alexandrescu (8/68) Mar 08 2010 I said a primitive for serialization, not a serialization
- Steven Schveighoffer (24/83) Mar 08 2010 Reading the documentation, it appears that setting the policy means simp...
- Andrei Alexandrescu (8/102) Mar 08 2010 I think it also means that you write your function that calls "to"
- bearophile (4/8) Mar 08 2010 -.-
- Steven Schveighoffer (8/10) Mar 09 2010 You know what, you are right. Why should phobos cater to people wanting...
- Ellery Newcomer (2/13) Mar 09 2010 and formatted in hex
- Andrei Alexandrescu (27/46) Mar 09 2010 In wake of printing multi-dimensional arrays, I agree that start and end...
- Steven Schveighoffer (19/41) Mar 09 2010 That's great!
- Fawzi Mohamed (30/79) Mar 09 2010 charset=US-ASCII;
- Fawzi Mohamed (3/4) Mar 09 2010 sorry about that...
- Leandro Lucarella (16/29) Mar 10 2010 It's not too hard to be completely unambiguous. Just print the stuff in
- bearophile (8/13) Mar 08 2010 Sorry for losing my temper about this in my last posts.
- Don (19/30) Mar 08 2010 Bug 1914 Array initialisation from const array yields memory trample
- bearophile (19/19) Mar 08 2010 If you compile a program like this:
- Walter Bright (2/9) Mar 08 2010 Well, it didn't hang, it just took a while. I found the problem.
- Walter Bright (9/16) Mar 08 2010 obj2asm tells the tale. (obj2asm is an incredibly useful tool, I don't
- Trass3r (3/6) Mar 08 2010 Maybe because it's not free (and not much advertised).
- Adam D. Ruppe (5/6) Mar 08 2010 The linux version comes in the zip right along side dmd.
- Trass3r (1/3) Mar 08 2010 Indeed. Even the OSX folder contains obj2asm. The windows version is mis...
- grauzone (4/8) Mar 08 2010 The best thing is, on Linux you can use binutils objdump just fine. I'm
- Walter Bright (22/33) Mar 08 2010 At first glance, obj2asm will pretty-print the codeview debug info in
- grauzone (3/40) Mar 09 2010 Why not give them out to free?
- Bernard Helyer (16/18) Mar 09 2010 Maybe a minor quibble, but obj2asm is really slow. If I'm going to
- Walter Bright (4/30) Mar 09 2010 Yes, it's because I don't have a similar group of stuff I can bundle for...
- Bernard Helyer (8/10) Mar 09 2010 Obviously, I can't tell from here, but I can tell you what my system
- Bernard Helyer (3/14) Mar 09 2010 And of course, as you can see, it spends an atypical amount of time in
- Walter Bright (2/19) Mar 09 2010 It's a mystery. The only I/O it does is merely read the file.
- Walter Bright (3/6) Mar 08 2010 The problem is I don't think it's the right fix, and I haven't spent the...
- Gareth Charnock (4/15) Mar 08 2010 I think this bug has been squished as well. Both test cases now compile
- bearophile (23/28) Mar 08 2010 I have not found a good solution yet. This solution looks buggy (also be...
- Robert Clipsham (10/19) Mar 08 2010 Untested, will the following do what you need?
- Andrei Alexandrescu (5/29) Mar 08 2010 What I usually do is:
- bearophile (5/8) Mar 08 2010 Nice, thank you, I'll use that.
- Robert Clipsham (2/6) Mar 08 2010 That's far nicer, I keep forgetting about is(typeof()), thanks :)
- Andrei Alexandrescu (5/14) Mar 08 2010 It'll be hard to forget once TDPL will be out there, the idiom is
- Robert Clipsham (5/6) Mar 08 2010 I suspect you're not the only one, I was filled with excitement when I
- bearophile (25/33) Mar 08 2010 Oh, nice, I didn't remember you can also use values there and not just t...
- bearophile (4/5) Mar 08 2010 I have added a bug:
- Philippe Sigaud (14/21) Mar 08 2010 ?! You mean typeof(a) != typeof((typeof(a)).init) ?!
- bearophile (4/11) Mar 08 2010 http://d.puremagic.com/issues/show_bug.cgi?id=3826
- bearophile (64/64) Mar 08 2010 To try the new operators I have created this helper that works:
- Nick Treleaven (6/8) Mar 09 2010 Great, thanks :)
- Walter Bright (2/7) Mar 09 2010 Not any more!
- biozic (2/13) Mar 09 2010 Actually, slice.capacity *increases* from 0 to s.capacity when calling s...
- Steven Schveighoffer (9/28) Mar 09 2010 Yes, it is technically like that. shrinkToFit really looks weird as a
- Michal Minich (3/5) Mar 09 2010 kind of assumeUnique ...
- Lutger (3/11) Mar 09 2010 I like that. Or assumeNoMemoryAliasing. It should be clear that it is a
- bearophile (4/6) Mar 09 2010 This is getting there :-)
- Steven Schveighoffer (12/23) Mar 09 2010 I like this train of thought, assume is a good term for what you are
- Michal Minich (8/39) Mar 09 2010 assumeNoArrayReference does not express that there can be references to
- Steven Schveighoffer (9/16) Mar 09 2010 Actually, you can have valid references up until the slice end.
- David Gileadi (2/18) Mar 09 2010 As long as we're bikeshedding, maybe assumeUnreferencedAfter?
- Steven Schveighoffer (7/30) Mar 09 2010 This is exactly the semantic meaning we are going for. I'd like it to b...
- Don (2/39) Mar 09 2010 assumeSafeExpand ?
- Steven Schveighoffer (5/16) Mar 09 2010 That is great!
- bearophile (22/27) Mar 10 2010 Good :-)
- Ivan (26/33) Mar 12 2010 In 2.040 this worked:
- Steven Schveighoffer (4/41) Mar 12 2010 This is a bug. Any time you are specifying the exact type on the lhs of...
- bearophile (54/64) Mar 12 2010 I have seen something different, using dmd 2.041 on Windows. Here are fe...
- bearophile (4/4) Mar 13 2010 I have added some of those things to an older bug report:
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!
Mar 07 2010
Thanks! A pleasant surprise to see interface contracts.
Mar 07 2010
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!This is great, thank you! I'm especially looking forward to playing with the new operator overloading method. :) -Lars
Mar 08 2010
Walter Bright <newshound1 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
Mar 08 2010
Simen kjaeraas wrote:Walter Bright <newshound1 digitalmars.com> wrote:I just noticed that Steven Schveighoffer's array append patch made it into this release. That ranks pretty high on the awesome scale too. :) -LarsLots 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!
Mar 08 2010
On Mon, 08 Mar 2010 03:45:21 -0500, Lars T. Kyllingstad <public kyllingen.nospamnet> wrote:Simen kjaeraas wrote: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. -SteveWalter Bright <newshound1 digitalmars.com> wrote:I just noticed that Steven Schveighoffer's array append patch made it into this release. That ranks pretty high on the awesome scale too. :)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!
Mar 08 2010
On Mon, Mar 8, 2010 at 14:22, Steven Schveighoffer <schveiguy yahoo.com>wrote: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
Mar 08 2010
On Mon, 08 Mar 2010 16:42:54 -0500, Philippe Sigaud <philippe.sigaud gmail.com> wrote:On Mon, Mar 8, 2010 at 14:22, Steven Schveighoffer <schveiguy yahoo.com>wrote:compactThe 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
Mar 08 2010
Robert Jacques wrote:On Mon, 08 Mar 2010 16:42:54 -0500, Philippe Sigaud <philippe.sigaud gmail.com> wrote:Many of these names (including shrinkToFit) suggest that memory usage is reduced by freeing the left over memory after the array. This is not true: the function just enables stomping of the memory past the slice passed to the function. It's a very specialized and dangerous function (but still may be critical for good performance), and maybe it should rather have a more convoluted/long name than a simple one.On Mon, Mar 8, 2010 at 14:22, Steven Schveighoffer <schveiguy yahoo.com>wrote:compactThe 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
Mar 09 2010
On Tue, Mar 9, 2010 at 11:29, grauzone <none example.net> wrote:Many of these names (including shrinkToFit) suggest that memory usage is reduced by freeing the left over memory after the array. This is not true: the function just enables stomping of the memory past the slice passed to the function. It's a very specialized and dangerous function (but still may be critical for good performance), and maybe it should rather have a more convoluted/long name than a simple one.enableStomping? recycle? Anyway IANANES (I'm not a native English speaker), so I'll let Steven decide. Philippe
Mar 09 2010
"Philippe Sigaud" <philippe.sigaud gmail.com> wrote in message news:mailman.119.1268166534.4461.digitalmars-d-announce puremagic.com...On Tue, Mar 9, 2010 at 11:29, grauzone <none example.net> wrote:placeUnderFoot?Many of these names (including shrinkToFit) suggest that memory usage is reduced by freeing the left over memory after the array. This is not true: the function just enables stomping of the memory past the slice passed to the function. It's a very specialized and dangerous function (but still may be critical for good performance), and maybe it should rather have a more convoluted/long name than a simple one.enableStomping?
Mar 09 2010
On 10/03/10 11:06, Nick Sabalausky wrote:"Philippe Sigaud"<philippe.sigaud gmail.com> wrote in message news:mailman.119.1268166534.4461.digitalmars-d-announce puremagic.com...greekWedding?enableStomping?placeUnderFoot?
Mar 10 2010
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
Mar 08 2010
Lars T. Kyllingstad wrote:It seems array literals have become dynamic arrays, but I can't find any mention of that in the change log.I'll fix.
Mar 13 2010
On Mon, 08 Mar 2010 09:54:12 +0300, Walter Bright <newshound1 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
Mar 08 2010
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! :-)
Mar 08 2010
Ary Borenszweig wrote:Walter Bright wrote:And isn't it better for the spellchecker to show the closest match using levenshtein distance instead of just distance 1?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! :-)
Mar 08 2010
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
Mar 08 2010
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
Mar 08 2010
bearophile wrote:Ary Borenszweig:Cool! Much, much nicer. (that's why I think some examples would be fine there)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; } }
Mar 08 2010
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
Mar 08 2010
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.
Mar 08 2010
On Mon, 08 Mar 2010 01:54:12 -0500, Walter Bright <newshound1 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!This might belong on d.learn, but it's so specific to this release, I'll ask here: The implementation of opEquals(Object, Object) contains the following implementation (according to docs and source): bool opEquals(Object a, Object b) { if (a is b) return true; if (a is null || b is null) return false; if (typeid(a) == typeid(b)) return a.opEquals(b); return a.opEquals(b) && b.opEquals(a); } The third line seems to be a recursive call into opEquals, since the typeinfos are objects. But because the two typeid classes have the same typeinfo (TypeInfo_Class with class name "TypeInfo_Class") it will only go 2 levels deep since the first if clause will be true. However, it seems a bit redundant to verify that the typeids are not null (they will always be non-null) and have the same typeinfo (they will). Wouldn't it be more efficient and correct to just do: if(typeid(a).opEquals(typeid(b))) Also, there is a function inside object implementation to compare two typeinfos (commented out in interface file), is that used? Does the compiler allow overloading the global opEquals? Also, const is not respected: class C { int x; bool opEquals(Object other){ ++x; return false;} } void main() { const c = new C; const d = new D; assert(c != d); } compiles without complaint. I would argue that opEquals should be const in both Object and the global function, but I'm not sure of the ramifications. At the very least, the above should not compile. -Steve
Mar 08 2010
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.
Mar 08 2010
__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 <un 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.
Mar 08 2010
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
Mar 08 2010
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
Mar 08 2010
bearophile wrote:Andrei Alexandrescu: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$(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!).
Mar 08 2010
On Mon, 08 Mar 2010 14:27:36 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:bearophile wrote: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... -SteveAndrei Alexandrescu: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.$(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!).
Mar 08 2010
Steven Schveighoffer wrote:On Mon, 08 Mar 2010 14:27:36 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Yes, you may specify the separator. Andreibearophile wrote: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?Andrei Alexandrescu: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.$(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!).
Mar 08 2010
Steven Schveighoffer wrote:On Mon, 08 Mar 2010 14:27:36 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:auto s = to!string([1,2,3], "[", ", ", "]"); -Larsbearophile wrote: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?Andrei Alexandrescu: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.$(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!).
Mar 08 2010
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.
Mar 08 2010
bearophile wrote: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. AndreiSorry, 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.
Mar 08 2010
On Mon, 08 Mar 2010 14:49:33 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:bearophile wrote: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. -SteveAndrei 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, 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.
Mar 08 2010
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
Mar 08 2010
On Mon, 08 Mar 2010 15:12:24 -0500, bearophile <bearophileHUGS lycos.com> wrote: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. 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. -SteveTell 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"]]
Mar 08 2010
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.['hello world', ["that's right!", 'you']]a = ["hello world", ["that's right!", "you"]] a['hello world', ["that's right!", 'you']]print a'hello world'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, bearophileprint a[0]
Mar 08 2010
Steven Schveighoffer at "Mon, 08 Mar 2010 15:23:51 -0500" wrote: SS> On Mon, 08 Mar 2010 15:12:24 -0500, bearophile <bearophileHUGS lycos.com> wrote:SS> For completely unambiguous, yes. But still, I find often that quotes are more noise than SS> they are worth when just doing simple printouts. What we want is the most useful SS> default. Commas are even more noise than than quotes. erlang: [{app, "app1"}, {user, "user1"}, {score, 123456}, {date, 5000000}, {misc, "foo"}] But if you just drop commas: [{app "app1"} {user "user1"} {score 123456} {date 5000000} {misc "foo"}] SS> -Steve -- Best regards, Alexander Suhoverhov mailto: alexander suhoverhov.selfip.netSteven 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"]]
Mar 09 2010
On 2010-03-09 09:09:51 +0100, Alexander Suhoverhov <alexander suhoverhov.selfip.net> said:Steven Schveighoffer at "Mon, 08 Mar 2010 15:23:51 -0500" wrote: SS> On Mon, 08 Mar 2010 15:12:24 -0500, bearophile <bearophileHUGS 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"]] SS> For completely unambiguous, yes. But still, I find often that quotes are more noise than SS> they are worth when just doing simple printouts. What we want is the most useful SS> default. Commas are even more noise than than quotes. erlang: [{app, "app1"}, {user, "user1"}, {score, 123456}, {date, 5000000}, {misc, "foo"}] But if you just drop commas: [{app "app1"} {user "user1"} {score 123456} {date 5000000} {misc "foo"}] SS> -SteveFor a basic output one can discuss what is better, but in general, for a serialization approach I feel that the basic approach of the discussion is flawed. A much better approach (that for example I did use in my serialization routines) is following the C++ philosophy that these details are handled by the target stream, not by the function sending the data. For example I have implemented two serializers, one that serializes to json (with [,]""), and one that serializes to a binary format. You write just one function, and then you can (even at runtime) change the details on the output, even from textual to binary, without changing anything in the serialization functions. You don't want to write a different serialization function for each format, or go around hunting for all calls to add " to strings... Now in my serialization routines I have a couple of design choices that maybe not everybody would share, but that I like: - it is possible to get a meta information describing what will be serialized *before* serializing (this helps in dumping the meta information once at the beginning, and then serialize arrays with minimal overhead in binary mode, but makes serializing slightly more complex. - it if possible (and not too difficult) to write serialization routines fully by hand, without any template, something very useful for objects that need special serialization. This method can also be fully customized. < shameless bug promotion> By the way as I have some horrible code due to http://d.puremagic.com/issues/show_bug.cgi?id=3472 and similar bugs in mixing interfaces and templates, I had written a much nicer version only to find out that it did not work... </ shameless bug promotion> I am transitioning the whole i/o in blip to a more abstract model based on simple delegates (sink/readers) that should make it easier to use it with either phobos or tango or any other source, but at the moment the input part still requires tango InputStreams (output part already transitioned). Fawzi
Mar 09 2010
On Tue, 09 Mar 2010 03:09:51 -0500, Alexander Suhoverhov <alexander suhoverhov.selfip.net> wrote:Steven Schveighoffer at "Mon, 08 Mar 2010 15:23:51 -0500" wrote: SS> On Mon, 08 Mar 2010 15:12:24 -0500, bearophile <bearophileHUGS 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"]] SS> For completely unambiguous, yes. But still, I find often that quotes are more noise than SS> they are worth when just doing simple printouts. What we want is the most useful SS> default. Commas are even more noise than than quotes. erlang: [{app, "app1"}, {user, "user1"}, {score, 123456}, {date, 5000000}, {misc, "foo"}] But if you just drop commas: [{app "app1"} {user "user1"} {score 123456} {date 5000000} {misc "foo"}]If you are used to writing code, you should be used to having commas. The two major use cases for 'to!string' are debugging and maybe serialization, both programmer tasks. Plus, in your examples, you have quotes for strings. That negates the need for commas, but I don't know if having 'to' convert strings to having quotes only for arrays makes sense. Outputting an array should be a recursive thing. At the very least, we need either a non-whitespace separator or quotes to delineate strings. Brackets are a must to see the separation for multi-dimensional arrays. -Steve
Mar 09 2010
On 9-mar-10, at 13:00, Steven Schveighoffer wrote:On Tue, 09 Mar 2010 03:09:51 -0500, Alexander Suhoverhov <alexander suhoverhov.selfip.netI don't know, I have something similar writeOut(sink,type,formatting...), which is more flexible and efficient, not just to string. That is supposed to write out something for the user (no serialization), and well it does not put "", but it does put "," in arrays, but I can understand other choices (matlab for example has no commas). For dictionaries ":" and "," is nice I think. It really come down to the meaning of to!(x), if it should be without loss then one should have enough information to recover the original value. That is possible also without commas, but C/D programmers are used to them... lisp, or other functional languages programmers might feel more at home with spaces... both are possible. I find it slightly funny that D would choose spaces, but in the end any convention works Fawziwrote:Steven Schveighoffer at "Mon, 08 Mar 2010 15:23:51 -0500" wrote: SS> On Mon, 08 Mar 2010 15:12:24 -0500, bearophile <bearophileHUGS lycos.comIf you are used to writing code, you should be used to having commas. The two major use cases for 'to!string' are debugging and maybe serialization, both programmer tasks. Plus, in your examples, you have quotes for strings. That negates the need for commas, but I don't know if having 'to' convert strings to having quotes only for arrays makes sense. Outputting an array should be a recursive thing. At the very least, we need either a non-whitespace separator or quotes to delineate strings. Brackets are a must to see the separation for multi-dimensional arrays. -Stevewrote:string for aSteven Schveighoffer:Tell me how you would parse the following text serializationSS> For completely unambiguous, yes. But still, I find often that quotes are more noise than SS> they are worth when just doing simple printouts. What we want is the most useful SS> default. Commas are even more noise than than quotes. erlang: [{app, "app1"}, {user, "user1"}, {score, 123456}, {date, 5000000}, {misc, "foo"}] But if you just drop commas: [{app "app1"} {user "user1"} {score 123456} {date 5000000} {misc "foo"}]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"]]
Mar 09 2010
Steven Schveighoffer wrote:On Mon, 08 Mar 2010 14:49:33 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote: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.bearophile wrote: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.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, 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.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
Mar 08 2010
On Mon, 08 Mar 2010 15:56:14 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Steven Schveighoffer wrote: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?On Mon, 08 Mar 2010 14:49:33 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote: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.bearophile wrote: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.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, 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.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. -SteveThe 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.
Mar 08 2010
Steven Schveighoffer wrote:On Mon, 08 Mar 2010 15:56:14 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I think it also means that you write your function that calls "to" inside, and use your function throughout.Steven Schveighoffer wrote: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.On Mon, 08 Mar 2010 14:49:33 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote: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.bearophile wrote: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.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, 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.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.Write your own function and call it.I can choose the policy for each call, that is not going to look very good, and be very tedious to write.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.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
Mar 08 2010
Andrei Alexandrescu:-.- Bye, bearophileI'll also point out that AAs have a default policy that is much more reasonable.I guess that should be changed too :o).
Mar 08 2010
On Mon, 08 Mar 2010 17:52:25 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Printing values with spaces between them is entirely fine for e.g. all numbers.You know what, you are right. Why should phobos cater to people wanting to print something as arcane as a string array, or a multi-dimensional array. People have no business using such constructs, they should be punished by having to write their own routines. It's all one-dimensional arrays of numbers for me from now on! -Steve
Mar 09 2010
On 03/09/2010 05:53 AM, Steven Schveighoffer wrote:On Mon, 08 Mar 2010 17:52:25 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:and formatted in hexPrinting values with spaces between them is entirely fine for e.g. all numbers.You know what, you are right. Why should phobos cater to people wanting to print something as arcane as a string array, or a multi-dimensional array. People have no business using such constructs, they should be punished by having to write their own routines. It's all one-dimensional arrays of numbers for me from now on! -Steve
Mar 09 2010
Ellery Newcomer wrote:On 03/09/2010 05:53 AM, Steven Schveighoffer wrote:In wake of printing multi-dimensional arrays, I agree that start and end delimiters should be present by default. If delimiters are present, it only makes sense to make the array look like a D array, so the ", " becomes an acceptable proposition. I'm unsure about strings - should "to" go all gung-ho on quoting and escaping quotes etc.? That's a bit odd. Consider: auto str = to!string("hello world"); I'd expect the call to be an identity application that makes str equal to "hello world". So far so good. Then say I convert with "to" an array of strings to a string: auto str2 = to!string(["hello world"]); Now str2 is "\"hello world\"", i.e. has an extra pair of quotes. So "to" applied to an array does not always use "to" applied to each element of the array - it has a completely different behavior. I wonder whether that's a desirable behavior. (For the record, I agree that there are ambiguities if the quotes are not added and escaped etc. I just wonder whether that should be part of "to"s charter.) Another thing that's unclear to me is whether writeln and "to" should be defined such that write(to!string(stuff)) and writeln(stuff) produce the same text. Currently that's the general plan, but I wonder whether we should change the approach. AndreiOn Mon, 08 Mar 2010 17:52:25 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:and formatted in hexPrinting values with spaces between them is entirely fine for e.g. all numbers.You know what, you are right. Why should phobos cater to people wanting to print something as arcane as a string array, or a multi-dimensional array. People have no business using such constructs, they should be punished by having to write their own routines. It's all one-dimensional arrays of numbers for me from now on! -Steve
Mar 09 2010
On Tue, 09 Mar 2010 12:33:01 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:In wake of printing multi-dimensional arrays, I agree that start and end delimiters should be present by default. If delimiters are present, it only makes sense to make the array look like a D array, so the ", " becomes an acceptable proposition.That's great!I'm unsure about strings - should "to" go all gung-ho on quoting and escaping quotes etc.? That's a bit odd. Consider: auto str = to!string("hello world"); I'd expect the call to be an identity application that makes str equal to "hello world". So far so good. Then say I convert with "to" an array of strings to a string: auto str2 = to!string(["hello world"]); Now str2 is "\"hello world\"", i.e. has an extra pair of quotes.I think you mean "[\"hello world\"]"So "to" applied to an array does not always use "to" applied to each element of the array - it has a completely different behavior. I wonder whether that's a desirable behavior.I would say no. I guess you could make the argument that strings are already arrays treated specially, but I don't think it adds much to put the quotes there. Plus, it allows simpler code and documentation, you can define the conversion of an array as a purely recursive function, even if it may not be implemented that way. Note that ranges should convert identically to arrays, making arrays special would make things odd.Another thing that's unclear to me is whether writeln and "to" should be defined such that write(to!string(stuff)) and writeln(stuff) produce the same text. Currently that's the general plan, but I wonder whether we should change the approach.I like that, it shows consistency. If you want to change the format, you can via to's parameters. But the most useful defaults should be the same in writeln. Even though to is a way to get a crude serialization function, I don't know if it will be sufficient or efficient for a serious serialization library (i.e. I don't think it's worth making 'to' that smart). But it is sufficient as a debug tool, it just needs better defaults. -Steve
Mar 09 2010
charset=US-ASCII; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit On 9-mar-10, at 18:56, Steven Schveighoffer wrote:On Tue, 09 Mar 2010 12:33:01 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.orgwell the thing is again str vs repr (string, or representation), repr should output something that is basically valid D code that reproduces the same value, whereas str not, what should to! do?wrote:In wake of printing multi-dimensional arrays, I agree that start and end delimiters should be present by default. If delimiters are present, it only makes sense to make the array look like a D array, so the ", " becomes an acceptable proposition.That's great!I'm unsure about strings - should "to" go all gung-ho on quoting and escaping quotes etc.? That's a bit odd. Consider: auto str = to!string("hello world"); I'd expect the call to be an identity application that makes str equal to "hello world". So far so good. Then say I convert with "to" an array of strings to a string: auto str2 = to!string(["hello world"]); Now str2 is "\"hello world\"", i.e. has an extra pair of quotes.I think you mean "[\"hello world\"]"then I find it much better to base everything on something like my void writeOut(T,S...)(void delegate char[]sink, T object,S formatting) that outputs to a sink, so that you can have output without memory allocation. (well my version is little more complex because I want to accept also other stuff not just a sink http://github.com/fawzi/blip/blob/master/blip/io/BasicIO.d ) If you want a single string you can easily write helpers like T[] collectAppender(T)(void delegate(void delegate(T[])) appender,char[] buf=null) or similar ( http://github.com/fawzi/blip/blob/master/blip/conta ner/GrowableArray.d ) that convert sink based stuff to a single string. I think that that design is very efficient and clean, well I have to admit that I *hate* toString and methods that convert stuff to string, because they are unnecessarily inefficent.So "to" applied to an array does not always use "to" applied to each element of the array - it has a completely different behavior. I wonder whether that's a desirable behavior.I would say no. I guess you could make the argument that strings are already arrays treated specially, but I don't think it adds much to put the quotes there. Plus, it allows simpler code and documentation, you can define the conversion of an array as a purely recursive function, even if it may not be implemented that way. Note that ranges should convert identically to arrays, making arrays special would make things odd.Another thing that's unclear to me is whether writeln and "to" should be defined such that write(to!string(stuff)) and writeln(stuff) produce the same text. Currently that's the general plan, but I wonder whether we should change the approach.I like that, it shows consistency. If you want to change the format, you can via to's parameters. But the most useful defaults should be the same in writeln. Even though to is a way to get a crude serialization function, I don't know if it will be sufficient or efficient for a serious serialization library (i.e. I don't think it's worth making 'to' that smart). But it is sufficient as a debug tool, it just needs better defaults.as I said serialization is a different beast (at least what I want from serialization), and the "how" should be in the target serializer, the serialization function should given enough information to the serializer, so that it might serialize how it pleases to him (in particular meaningful labels should be given for serialization to json,xml,...). Fawzi
Mar 09 2010
On 2010-03-09 20:15:44 +0100, Fawzi Mohamed <fawzi gmx.ch> said: [...]some html spamsorry about that...
Mar 09 2010
Steven Schveighoffer, el 8 de marzo a las 14:57 me escribiste: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]]What about [1, 2]?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.It's not too hard to be completely unambiguous. Just print the stuff in a way that is parseable for D: ["hello \"world\"", "nice \\"] [1, 2, 3] [1.0, 2.0, 3.0] Thiis is good for both serialization and debugging (it' unambiguous, mandatory for serialization, and a littl verbose but clear for debugging). And if sometime in the future we get a D parser in the stdlib, deserialization is trivial =). -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ----------------------------------------------------------------------
Mar 10 2010
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
Mar 08 2010
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() {}
Mar 08 2010
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
Mar 08 2010
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.
Mar 08 2010
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*.
Mar 08 2010
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$.
Mar 08 2010
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
Mar 08 2010
The linux version comes in the zip right along side dmd.Indeed. Even the OSX folder contains obj2asm. The windows version is missing.
Mar 08 2010
Trass3r wrote: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.The linux version comes in the zip right along side dmd.Indeed. Even the OSX folder contains obj2asm. The windows version is missing.
Mar 08 2010
Trass3r wrote: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.htmlobj2asm 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$.
Mar 08 2010
Walter Bright wrote:Trass3r wrote:Why not give them out to free? Especially coff2omf seems to be critical, if you want D to be a success.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.htmlobj2asm 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$.
Mar 09 2010
On 09/03/10 09:12, Walter Bright wrote:obj2asm tells the tale. (obj2asm is an incredibly useful tool, I don't know why nobody uses it.)Maybe a minor quibble, but obj2asm is really slow. If I'm going to disassemble something, I am never going to reach for obj2asm: `ds` is a dmdscript testscript.d executable: [~]$ time objdump -d ~/bin/ds >ds.s real 0m1.139s user 0m0.912s sys 0m0.052s with '/'), obj2asm tries to interpret it as an argument. >_< real 0m55.809s user 0m11.009s sys 0m31.094s And out of curiosity, why do you charge for it on Windows, but provide it on Linux for free? Because the rest of the utilities are fairly windows-centric?
Mar 09 2010
Bernard Helyer wrote:On 09/03/10 09:12, Walter Bright wrote:Hmm, I never noticed it being slow at all. I wonder what's going on.obj2asm tells the tale. (obj2asm is an incredibly useful tool, I don't know why nobody uses it.)Maybe a minor quibble, but obj2asm is really slow. If I'm going to disassemble something, I am never going to reach for obj2asm:`ds` is a dmdscript testscript.d executable: [~]$ time objdump -d ~/bin/ds >ds.s real 0m1.139s user 0m0.912s sys 0m0.052s with '/'), obj2asm tries to interpret it as an argument. >_< real 0m55.809s user 0m11.009s sys 0m31.094s And out of curiosity, why do you charge for it on Windows, but provide it on Linux for free? Because the rest of the utilities are fairly windows-centric?Yes, it's because I don't have a similar group of stuff I can bundle for Linux.
Mar 09 2010
On 10/03/10 07:54, Walter Bright wrote:Obviously, I can't tell from here, but I can tell you what my system says obliquely. It spends that minute at 100% CPU, and about 100 megs resident (which it allocates quickly, and then hovers about at). It isn't spending a lot (almost none, AFAICT via iotop, it just does its reading and writing in a couple of big chunks) doing IO.Hmm, I never noticed it being slow at all. I wonder what's going on.
Mar 09 2010
On 10/03/10 08:57, Bernard Helyer wrote:On 10/03/10 07:54, Walter Bright wrote:And of course, as you can see, it spends an atypical amount of time in kernel space. Large blocking syscall?Obviously, I can't tell from here, but I can tell you what my system says obliquely. It spends that minute at 100% CPU, and about 100 megs resident (which it allocates quickly, and then hovers about at). It isn't spending a lot (almost none, AFAICT via iotop, it just does its reading and writing in a couple of big chunks) doing IO.Hmm, I never noticed it being slow at all. I wonder what's going on.
Mar 09 2010
Bernard Helyer wrote:On 10/03/10 08:57, Bernard Helyer wrote:It's a mystery. The only I/O it does is merely read the file.On 10/03/10 07:54, Walter Bright wrote:And of course, as you can see, it spends an atypical amount of time in kernel space. Large blocking syscall?Obviously, I can't tell from here, but I can tell you what my system says obliquely. It spends that minute at 100% CPU, and about 100 megs resident (which it allocates quickly, and then hovers about at). It isn't spending a lot (almost none, AFAICT via iotop, it just does its reading and writing in a couple of big chunks) doing IO.Hmm, I never noticed it being slow at all. I wonder what's going on.
Mar 09 2010
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.
Mar 08 2010
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!
Mar 08 2010
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
Mar 08 2010
On 08/03/10 22:03, bearophile wrote:-snip-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):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.
Mar 08 2010
Robert Clipsham wrote:On 08/03/10 22:03, bearophile wrote:What I usually do is: T foo(T)(T s) if (is(typeof(s + s))) { } Andrei-snip-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):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.
Mar 08 2010
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
Mar 08 2010
On 08/03/10 22:53, Andrei Alexandrescu wrote:What I usually do is: T foo(T)(T s) if (is(typeof(s + s))) { } AndreiThat's far nicer, I keep forgetting about is(typeof()), thanks :)
Mar 08 2010
Robert Clipsham wrote:On 08/03/10 22:53, Andrei Alexandrescu wrote: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. AndreiWhat I usually do is: T foo(T)(T s) if (is(typeof(s + s))) { } AndreiThat's far nicer, I keep forgetting about is(typeof()), thanks :)
Mar 08 2010
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 :)
Mar 08 2010
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
Mar 08 2010
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
Mar 08 2010
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 bugI 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
Mar 08 2010
Philippe Sigaud:http://d.puremagic.com/issues/show_bug.cgi?id=3826 Bye, bearophilewriteln(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]
Mar 08 2010
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
Mar 08 2010
On Sun, 07 Mar 2010 22:54:12 -0800, Walter Bright wrote:http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.041.zipGreat, thanks :) BTW on this page: http://www.digitalmars.com/d/2.0/operatoroverloading.html The 'Index Operator Overloading' link text at the top is duplicated for the link to the 'Slice Operator Overloading' section ;-)
Mar 09 2010
Nick Treleaven wrote:BTW on this page: http://www.digitalmars.com/d/2.0/operatoroverloading.html The 'Index Operator Overloading' link text at the top is duplicated for the link to the 'Slice Operator Overloading' section ;-)Not any more!
Mar 09 2010
Steven Schveighoffer Wrote:* 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 referencedActually, slice.capacity *increases* from 0 to s.capacity when calling shrinkToFit, doesn't it? So "stomp" or "prepare_for_stomping" could be a better name.
Mar 09 2010
On Tue, 09 Mar 2010 10:10:10 -0500, biozic <biozic free.fr> wrote:Steven Schveighoffer Wrote:Yes, it is technically like that. shrinkToFit really looks weird as a property of the slice you are shrinking to because it really is operating on the array data itself (which has no concrete type or reference). I don't like anything that talks about stomping, because we are not trying to say this is a stomping operation. I want to focus more on the fact that you are declaring the data after the slice as being no longer used. It's definitely a harder function to name... -Steve* 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 referencedActually, slice.capacity *increases* from 0 to s.capacity when calling shrinkToFit, doesn't it? So "stomp" or "prepare_for_stomping" could be a better name.
Mar 09 2010
On Tue, 09 Mar 2010 10:23:07 -0500, Steven Schveighoffer wrote:I want to focus more on the fact that you are declaring the data after the slice as being no longer used.kind of assumeUnique ... assumeNoArrayReference ?
Mar 09 2010
Michal Minich wrote:On Tue, 09 Mar 2010 10:23:07 -0500, Steven Schveighoffer wrote:I like that. Or assumeNoMemoryAliasing. It should be clear that it is a potentially very unsafe function.I want to focus more on the fact that you are declaring the data after the slice as being no longer used.kind of assumeUnique ... assumeNoArrayReference ?
Mar 09 2010
Lutger:Or assumeNoMemoryAliasing. It should be clear that it is a potentially very unsafe function.This is getting there :-) Bye, bearophile
Mar 09 2010
On Tue, 09 Mar 2010 12:54:16 -0500, Lutger <lutger.blijdestijn gmail.com> wrote:Michal Minich wrote:I like this train of thought, assume is a good term for what you are doing, and it is consistent with assumeUnique. The only thing I don't like about it is you aren't really assuming anything about the slice, you are assuming the data after the slice is no longer used. It looks weird that you are assuming something about the slice. assumeEndOfData ? assumeAllocation ? I don't 100% like those either. -SteveOn Tue, 09 Mar 2010 10:23:07 -0500, Steven Schveighoffer wrote:I like that. Or assumeNoMemoryAliasing. It should be clear that it is a potentially very unsafe function.I want to focus more on the fact that you are declaring the data after the slice as being no longer used.kind of assumeUnique ... assumeNoArrayReference ?
Mar 09 2010
On Tue, 09 Mar 2010 14:07:10 -0500, Steven Schveighoffer wrote:On Tue, 09 Mar 2010 12:54:16 -0500, Lutger <lutger.blijdestijn gmail.com> wrote:assumeNoArrayReference does not express that there can be references to the original array before slice start. probably better expressing, if rather long name could be assumeNoOriginArrayReferencesPastSliceEnd assumeNoOriginArrayReferencesAfter or probably somthing like this: unsafeDeletePastSliceMichal Minich wrote:I like this train of thought, assume is a good term for what you are doing, and it is consistent with assumeUnique. The only thing I don't like about it is you aren't really assuming anything about the slice, you are assuming the data after the slice is no longer used. It looks weird that you are assuming something about the slice. assumeEndOfData ? assumeAllocation ? I don't 100% like those either. -SteveOn Tue, 09 Mar 2010 10:23:07 -0500, Steven Schveighoffer wrote:I like that. Or assumeNoMemoryAliasing. It should be clear that it is a potentially very unsafe function.I want to focus more on the fact that you are declaring the data after the slice as being no longer used.kind of assumeUnique ... assumeNoArrayReference ?
Mar 09 2010
On Tue, 09 Mar 2010 14:36:41 -0500, Michal Minich <michal.minich gmail.com> wrote:assumeNoArrayReference does not express that there can be references to the original array before slice start. probably better expressing, if rather long name could beActually, you can have valid references up until the slice end.assumeNoOriginArrayReferencesPastSliceEnd assumeNoOriginArrayReferencesAfterThese are too long. As much as this is an unsafe to-be-used-with-care function, we don't want to torture those who need it :) I prefer a name with 1-3 terms in it.or probably somthing like this: unsafeDeletePastSlicealso a little long, and I don't like the term delete, it's not actually deleting the memory. -Steve
Mar 09 2010
On 3/9/2010 12:44 PM, Steven Schveighoffer wrote:On Tue, 09 Mar 2010 14:36:41 -0500, Michal Minich <michal.minich gmail.com> wrote:As long as we're bikeshedding, maybe assumeUnreferencedAfter?assumeNoArrayReference does not express that there can be references to the original array before slice start. probably better expressing, if rather long name could beActually, you can have valid references up until the slice end.assumeNoOriginArrayReferencesPastSliceEnd assumeNoOriginArrayReferencesAfterThese are too long. As much as this is an unsafe to-be-used-with-care function, we don't want to torture those who need it :) I prefer a name with 1-3 terms in it.or probably somthing like this: unsafeDeletePastSlicealso a little long, and I don't like the term delete, it's not actually deleting the memory. -Steve
Mar 09 2010
On Tue, 09 Mar 2010 14:54:11 -0500, David Gileadi <foo bar.com> wrote:On 3/9/2010 12:44 PM, Steven Schveighoffer wrote:This is exactly the semantic meaning we are going for. I'd like it to be shorter... synonyms for unreferenced? assumeUnusedAfter Any others ideas? -SteveOn Tue, 09 Mar 2010 14:36:41 -0500, Michal Minich <michal.minich gmail.com> wrote:As long as we're bikeshedding, maybe assumeUnreferencedAfter?assumeNoArrayReference does not express that there can be references to the original array before slice start. probably better expressing, if rather long name could beActually, you can have valid references up until the slice end.assumeNoOriginArrayReferencesPastSliceEnd assumeNoOriginArrayReferencesAfterThese are too long. As much as this is an unsafe to-be-used-with-care function, we don't want to torture those who need it :) I prefer a name with 1-3 terms in it.or probably somthing like this: unsafeDeletePastSlicealso a little long, and I don't like the term delete, it's not actually deleting the memory.
Mar 09 2010
Steven Schveighoffer wrote:On Tue, 09 Mar 2010 14:54:11 -0500, David Gileadi <foo bar.com> wrote:assumeSafeExpand ?On 3/9/2010 12:44 PM, Steven Schveighoffer wrote:This is exactly the semantic meaning we are going for. I'd like it to be shorter... synonyms for unreferenced? assumeUnusedAfter Any others ideas? -SteveOn Tue, 09 Mar 2010 14:36:41 -0500, Michal Minich <michal.minich gmail.com> wrote:As long as we're bikeshedding, maybe assumeUnreferencedAfter?assumeNoArrayReference does not express that there can be references to the original array before slice start. probably better expressing, if rather long name could beActually, you can have valid references up until the slice end.assumeNoOriginArrayReferencesPastSliceEnd assumeNoOriginArrayReferencesAfterThese are too long. As much as this is an unsafe to-be-used-with-care function, we don't want to torture those who need it :) I prefer a name with 1-3 terms in it.or probably somthing like this: unsafeDeletePastSlicealso a little long, and I don't like the term delete, it's not actually deleting the memory.
Mar 09 2010
On Tue, 09 Mar 2010 15:29:04 -0500, Don <nospam nospam.com> wrote:Steven Schveighoffer wrote:That is great! Do you think assumeSafeAppend is better, since we do call the operation append? -SteveOn Tue, 09 Mar 2010 14:54:11 -0500, David Gileadi <foo bar.com> wrote:assumeSafeExpand ?As long as we're bikeshedding, maybe assumeUnreferencedAfter?This is exactly the semantic meaning we are going for. I'd like it to be shorter... synonyms for unreferenced? assumeUnusedAfter Any others ideas? -Steve
Mar 09 2010
Sorry for the delayed answer. Andrei Alexandrescu:In wake of printing multi-dimensional arrays, I agree that start and end delimiters should be present by default. If delimiters are present, it only makes sense to make the array look like a D array, so the ", " becomes an acceptable proposition.<Good :-)I wonder whether that's a desirable behavior.<I like it this way (but str2 is "[\"hello world\"]", as Steven Schveighoffer says), because my programming experience has taught me that explicit is better than implicit (also as said by Python Zen), and quotation marks make the output a little more unambigous. It's a matter of balance between being fully unambigous (useful for people, but also for the computer) and being nice and readable (useful for people). It's how I have designed the put/putr functions in my dlibs, the function they both use take an extra boolean argument named "repr", that tells apart the repr/str cases. When called inside a collection then repr=true, and it's true for all successive nested recursive calls. And ["hello world"] is you write such array in normal D code, so you can perform a copy & paste from one outout into a D source code, this is a very common thing done in Python, and it's the base for the doctest module: http://docs.python.org/library/doctest.html Extra note: Python avoids many of those \ using a bit smarter quotation strategy, that involves four different symbols: " """ ' ''' While D spares the need of the """ ''' because D strings are multi line, and D uses '' to represent char literals. D1 has naked escaped char literals too but they were not appreciated much.Currently that's the general plan, but I wonder whether we should change the approach.<If you or someone else shows some alternative possibilities we can discuss what is the better one. ---------------- Steven Schveighoffer:I like that, it shows consistency. If you want to change the format, you can via to's parameters. But the most useful defaults should be the same in writeln.<sensible defults can help a *lot* the programmers/users. ---------------- Fawzi Mohamed:I think that that design is very efficient and clean, well I have toadmit that I *hate* toString and methods that convert stuff to string, because they are unnecessarily inefficent.< In many cases in my code toString is used for small/medium outputs in debug mode, so performance is not so important. Computers can today generate even MB of strings in a short time. But if you want more performance, then the built-in object/struct toString may take an optional argument (that defaults to null, that means the behavour currently used), that is the sink you talk about. If you like this simple idea (that is backwards compatible if you don't add such sink arguments) you can talk about this in the main D newsgroup. Bye and thank you very much Andrei for changing your mind a little, bearophile
Mar 10 2010
On 8.3.2010 7:54, 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!In 2.040 this worked: real x = 1.2; real[4][4] M2 = [ [1, 0, 0, x], [0, 1, 0, x], [0, 0, 1, x], [0, 0, 0, 1] ]; In 2.041 it has to be written like this: real x = 1.2; real[4][4] M2 = [ [1, 0, 0, x], [0, 1, 0, x], [0, 0, 1, x], [0, 0, 0, cast(real)1] ]; Don't know if the first one should still work and this is a bug or is the new behaviour ok so I am checking here. The error on the first array initialization in 2.041 is Error: incompatible types for (([cast(real)1,cast(real)0,cast(real)0,x]) ? ([0,0,0,1])): 'real[]' and 'int[]' ArraysTest.d(23): Error: cannot implicitly convert expression ([0L,1L,0L,x]) of type real[] to int ArraysTest.d(23): Error: cannot implicitly convert expression ([0L,0L,1L,x]) of type real[] to int
Mar 12 2010
On Fri, 12 Mar 2010 09:14:26 -0500, Ivan <ivan.senji gmail.com> wrote:On 8.3.2010 7:54, Walter Bright wrote:This is a bug. Any time you are specifying the exact type on the lhs of a literal assignment, the literal should be typed that way. -SteveLots 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!In 2.040 this worked: real x = 1.2; real[4][4] M2 = [ [1, 0, 0, x], [0, 1, 0, x], [0, 0, 1, x], [0, 0, 0, 1] ]; In 2.041 it has to be written like this: real x = 1.2; real[4][4] M2 = [ [1, 0, 0, x], [0, 1, 0, x], [0, 0, 1, x], [0, 0, 0, cast(real)1] ]; Don't know if the first one should still work and this is a bug or is the new behaviour ok so I am checking here. The error on the first array initialization in 2.041 is Error: incompatible types for (([cast(real)1,cast(real)0,cast(real)0,x]) ? ([0,0,0,1])): 'real[]' and 'int[]' ArraysTest.d(23): Error: cannot implicitly convert expression ([0L,1L,0L,x]) of type real[] to int ArraysTest.d(23): Error: cannot implicitly convert expression ([0L,0L,1L,x]) of type real[] to int
Mar 12 2010
In 2.041 it has to be written like this: real x = 1.2; real[4][4] M2 = [ [1, 0, 0, x], [0, 1, 0, x], [0, 0, 1, x], [0, 0, 0, cast(real)1] ];I have seen something different, using dmd 2.041 on Windows. Here are few cases of code followed by the error messages dmd outputs to me. A good way to write code that contains a little less bugs is to try all possible corner cases, systematically, orthogonally, trying all the little boxes you can find in the matrix/tensor of possibilities (like Guy Steele did when he designed Java attributes). I think dmd will need few more tons of tests. ----------------------- real x = 1.2; real[4][4] M2 = [[1, 0, 0, x], [0, 1, 0, x], [0, 0, 1, x], [0, 0, 0, cast(real)1]]; void main() {} test.d(5): Error: non-constant expression x test.d(5): Error: non-constant expression x test.d(5): Error: non-constant expression x ----------------------- real x = 1.2; real[4][4] M2 = [[1, 0, 0, x], [0, 1, 0, x], [0, 0, 1, x], [0, 0, 0, 1]]; void main() {} bug1.d(5): Error: non-constant expression x bug1.d(5): Error: non-constant expression x bug1.d(5): Error: non-constant expression x ----------------------- const real x = 1.2; real[4][4] M2 = [[1, 0, 0, x], [0, 1, 0, x], [0, 0, 1, x], [0, 0, 0, 1]]; void main() {} No errors with const, immutable, enum. ----------------------- const real x = 1.2; real[4][4] M2 = [[0, 0, 1, x], [0, 0, 0, 1]]; void main() {} No errors. ----------------------- const real x = 1.2; real[4][2] M2 = [[0, 0, 1, x], [0, 0, 0, 1]]; void main() {} No errors. ----------------------- const real x = 1.2; real[2][4] M2 = [[0, 0, 1, x], [0, 0, 0, 1]]; void main() {} bug1.d(3): Error: cannot implicitly convert expression ([0,0,0,1]) of type int[] to real[2u] This seems a wrong error message at best. ----------------------- Can't x be mutable? So are array literals kinda constant now? Do you see something that needs to go to Bugzilla? Bye, bearophile
Mar 12 2010
I have added some of those things to an older bug report: http://d.puremagic.com/issues/show_bug.cgi?id=3948 Bye, bearophile
Mar 13 2010