Re: Exception programming difficult
On Monday, 13 August 2012 at 15:32:45 UTC, Dmitry Olshansky wrote: Back to Java: what is I find strange is the lack of sensible tools to do transactional or exception safe code within the language. No RAII objects or just at least any kludge to reliably register cleanup/rollback, only "good" old try/finally. Since Java 7, you have the same tools Haskell, Scheme, Lisp, C# and Python already offer for such cases. For example: try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readLine(); } -- Paulo
Re: Unions destructors and GC precision
On Wed, 15 Aug 2012 07:09:40 +0200, Jonathan M Davis wrote: On Wednesday, August 15, 2012 07:02:25 Simen Kjaeraas wrote: On Tue, 14 Aug 2012 22:32:58 +0200, Andrei Alexandrescu wrote: > On 8/14/12 3:25 PM, bearophile wrote: >> D2 doesn't give you that restriction, and when an union goes out of > >> scope it calls the destructors of all its fields: > That's pretty surprising. "Major bug" doesn't begin to describe it. > > Unions should call no constructors and no destructors. That means the default case is unsafe. Should it also be an error (or at least a warning) for a union containing types with destructors or complex constructors not to have a defined constructor/destructor? I wouldn't expect unions to be considered @safe in the first place. You're potentially reintrepreting one type as another with them. True, when the unioned types are or contain pointers. With POD there should be no problem. -- Simen
Re: Unions destructors and GC precision
On Wednesday, 15 August 2012 at 05:10:02 UTC, Jonathan M Davis wrote: On Wednesday, August 15, 2012 07:02:25 Simen Kjaeraas wrote: On Tue, 14 Aug 2012 22:32:58 +0200, Andrei Alexandrescu wrote: > On 8/14/12 3:25 PM, bearophile wrote: >> D2 doesn't give you that restriction, and when an union >> goes out of > >> scope it calls the destructors of all its fields: > That's pretty surprising. "Major bug" doesn't begin to > describe it. > > Unions should call no constructors and no destructors. That means the default case is unsafe. Should it also be an error (or at least a warning) for a union containing types with destructors or complex constructors not to have a defined constructor/destructor? I wouldn't expect unions to be considered @safe in the first place. You're potentially reintrepreting one type as another with them. And I would expect that anything in them is in the same boat that anything initialized to void is. e.g. Type var = void; - Jonathan M Davis I second this. That is actually one of the reasons why most languages with GC, ban pointer uses to unsafe sections, otherwise the GC would be very restricted in the ways it could work. Same thing about unions, as you wouldn't know which pointer/reference is the active one without some kind of tagging. -- Paulo
Re: Unions destructors and GC precision
On Wednesday, August 15, 2012 07:02:25 Simen Kjaeraas wrote: > On Tue, 14 Aug 2012 22:32:58 +0200, Andrei Alexandrescu > > wrote: > > On 8/14/12 3:25 PM, bearophile wrote: > >> D2 doesn't give you that restriction, and when an union goes out of > > > >> scope it calls the destructors of all its fields: > > That's pretty surprising. "Major bug" doesn't begin to describe it. > > > > Unions should call no constructors and no destructors. > > That means the default case is unsafe. Should it also be an error > (or at least a warning) for a union containing types with destructors > or complex constructors not to have a defined constructor/destructor? I wouldn't expect unions to be considered @safe in the first place. You're potentially reintrepreting one type as another with them. And I would expect that anything in them is in the same boat that anything initialized to void is. e.g. Type var = void; - Jonathan M Davis
Re: Unions destructors and GC precision
On Tue, 14 Aug 2012 22:32:58 +0200, Andrei Alexandrescu wrote: On 8/14/12 3:25 PM, bearophile wrote: D2 doesn't give you that restriction, and when an union goes out of scope it calls the destructors of all its fields: That's pretty surprising. "Major bug" doesn't begin to describe it. Unions should call no constructors and no destructors. That means the default case is unsafe. Should it also be an error (or at least a warning) for a union containing types with destructors or complex constructors not to have a defined constructor/destructor? -- Simen
Re: Which D features to emphasize for academic review article
On Wednesday, 15 August 2012 at 00:32:43 UTC, Walter Bright wrote: On 8/14/2012 3:57 PM, Mehrdad wrote: I guess they aren't really default constructors, then . I say potayto, you say potahto... :P So what happens when you allocate an array of them? For arrays, they're called automatically. Well, OK, that's a bit of a simplification. It's what happens from the user perspective, not the compiler's (or runtime's). Here's the full story. And please read it carefully, since I'm __not__ saying D should adopt what C# does word for word! In C#: - You can define a custom default constructor for classes, but not structs. - Structs _always_ have a zero-initializing default (no-parameter) constructor. - Therefore, there is no such thing as "copy construction"; it's bitwise-copied. - Ctors for _structs_ MUST initialize every field (or call the default ctor) - Ctors for _classes_ don't have this restriction. - Since initialization is "Cheap", the runtime _always_ does it, for _security_. - The above^ is IRRELEVANT to the compiler! * It enforces initialization where it can. * It explicitly tells the runtime to auto-initialize when it can't. -- You can ONLY take the address of a variable in unsafe{} blocks. -- This implies you know what you're doing, so it's not a problem. What D would do _ideally_, IMO: 1. Keep the ability to define default (no-args) and postblit constructors. 2. _Always_ force the programmer to initialize _all_ variables explicitly. * No, this is NOT what C++ does. * Yes, it is tested & DOES work well in practice. But NOT in the C++ mindset. * If the programmer _needs_ vars to be uninitialized, he can say = void. * If the programmer wants NaNs, he can just say = T.init. Bingo. It should work pretty darn well, if you actually give it a try. (Don't believe me? Put it behind a compiler switch, and see how many people start using it, and how many of them [don't] complain about it!) D could take a similar approach. It could, but default construction is better (!). Well, that's so convincing, I'm left speechless!
Re: Which D features to emphasize for academic review article
On 8/14/2012 3:57 PM, Mehrdad wrote: I know. How does that fit in with default construction? They aren't called unless the user calls them. I guess they aren't really default constructors, then . So what happens when you allocate an array of them? D could take a similar approach. It could, but default construction is better (!).
Re: Exception programming difficult
On Tuesday, 14 August 2012 at 23:13:07 UTC, Mehrdad wrote: On Monday, 13 August 2012 at 15:32:45 UTC, Dmitry Olshansky wrote: So (*yawn*) tell what kind of exception specification the following function should have: auto joiner(RoR, Separator)(RoR r, Separator sep); auto joiner(RoR, Separator)(RoR r, Separator sep) throws(?); Or even better: auto joiner(RoR, Separator)(RoR r, Separator sep) throws(auto); That way it's easy enough for the programmer to make the compiler shut up (it's certainly easier than swallowing the exception), while allowing him to write functions that are perfectly transparent toward exceptions, and which would be allowed to throw/catch as they would in any other exception-unchecked language. IMO it would work well in practice.
Re: Exception programming difficult
On Monday, 13 August 2012 at 15:32:45 UTC, Dmitry Olshansky wrote: So (*yawn*) tell what kind of exception specification the following function should have: auto joiner(RoR, Separator)(RoR r, Separator sep); auto joiner(RoR, Separator)(RoR r, Separator sep) throws(?);
Re: Which D features to emphasize for academic review article
On Tuesday, 14 August 2012 at 21:58:20 UTC, Walter Bright wrote: On 8/14/2012 2:22 PM, Mehrdad wrote: I was talking about "definite assignment", i.e. the _lack_ of automatic initialization. I know. How does that fit in with default construction? They aren't called unless the user calls them. void Bar(T value) { } void Foo() where T : new() // generic constraint for default constructor { T uninitialized; T initialized = new T(); Bar(initialized); // error Bar(uninitialized); // OK } void Test() { Foo(); Foo(); } D could take a similar approach.
Re: Which D features to emphasize for academic review article
On Tuesday, 14 August 2012 at 22:57:26 UTC, Mehrdad wrote: Bar(initialized); // error Bar(uninitialized); // OK Er, other way around I mean...
Re: Unions destructors and GC precision
Andrei Alexandrescu: That's pretty surprising. "Major bug" doesn't begin to describe it. If you want later I will add it to Bugzilla. But maybe before that other people will want to write some other comments in this thread. Unions should call no constructors and no destructors. But this doesn't address the GC precision problem. Some kind of tagging field (or equivalent information) isn't always available, but in many cases it's available, so in many practical cases I am able to put something useful inside a standard method like activeField(). If this method is available for the GC, it's not unconceivable to use it to call the right union field destructor when the union instance goes out of scope :-) The precision of the GC is not a binary thing, even a not fully precise GC is useful, and probably more precision is better than less precision. Even if activeField() is not always usable, an increase of GC precision seems an improvement to me. Bye, bearophile
Re: Which D features to emphasize for academic review article
On 8/14/2012 2:22 PM, Mehrdad wrote: I was talking about "definite assignment", i.e. the _lack_ of automatic initialization. I know. How does that fit in with default construction?
Re: Which D features to emphasize for academic review article
On Tuesday, 14 August 2012 at 21:22:14 UTC, Mehrdad wrote: C# and Java don't. Typo, scratch Java, it's N/A for Java.
Re: Which D features to emphasize for academic review article
On Tuesday, 14 August 2012 at 21:13:01 UTC, Walter Bright wrote: On 8/14/2012 3:31 AM, Mehrdad wrote: Then you get the best of both worlds: 1. You force the programmer to manually initialize the variable in most cases, forcing him to think about the default value. It's almost no trouble for 2. In the cases where it's not possible, the language helps the programmer catch bugs. Why the heck D avoids #1, I have no idea. As I've explained before, user defined types have "default constructors". If builtin types do not, then you've got a barrier to writing generic code. Just because they _have_ a default constructor doesn't mean the compiler should implicitly _call_ them on your behalf. C# and Java don't. It's one of the _major_ features of C# and Java that help promote correctness, and #1 looks orthogonal to #2 to me. I know Java doesn't have default construction - does C#? Huh? I think you completely misread my post... I was talking about "definite assignment", i.e. the _lack_ of automatic initialization. As for the 'rarity' of the error I mentioned, yes, it is unusual. The trouble is when it creeps unexpectedly into otherwise working code that has been working for a long time. It's no "trouble" in practice, that's what I'm trying to say. It only looks like "trouble" if you look at it from the C/C++ perspective instead of the C#/Java perspective.
Re: Which D features to emphasize for academic review article
On 8/14/2012 3:31 AM, Mehrdad wrote: Then you get the best of both worlds: 1. You force the programmer to manually initialize the variable in most cases, forcing him to think about the default value. It's almost no trouble for 2. In the cases where it's not possible, the language helps the programmer catch bugs. Why the heck D avoids #1, I have no idea. As I've explained before, user defined types have "default constructors". If builtin types do not, then you've got a barrier to writing generic code. Default initialization also applies to static arrays, tuples, structs and dynamic allocation. It seems a large inconsistency to complain about them only for local variables of basic types, and not for any aggregate type or user defined type. It's one of the _major_ features of C# and Java that help promote correctness, and #1 looks orthogonal to #2 to me. I know Java doesn't have default construction - does C#? As for the 'rarity' of the error I mentioned, yes, it is unusual. The trouble is when it creeps unexpectedly into otherwise working code that has been working for a long time.
Re: D Shell [was Re: A C++ interpreter]
On Monday, 13 August 2012 at 15:36:15 UTC, jerro wrote: Rdmd already has this functionality with the --eval flag. You are supposed to pass the code as a command line parameter, but you can use it with files like this: cat - test.d <<< "--eval=" | xargs -0 rdmd Wow, no wonder I never found it handy in Windows...
Re: Unions destructors and GC precision
On 8/14/12 3:25 PM, bearophile wrote: D2 doesn't give you that restriction, and when an union goes out of scope it calls the destructors of all its fields: That's pretty surprising. "Major bug" doesn't begin to describe it. Unions should call no constructors and no destructors. Andrei
Re: Which D features to emphasize for academic review article
On Tuesday, 14 August 2012 at 14:32:26 UTC, F i L wrote: Mehrdad wrote: Note to Walter: You're obviously correct that you can make an arbitrarily complex program to make it too difficult for the compiler to enforce initialization, the way C# does (and gives up in some cases). [ ... ] I think some here are mis-interpreting Walters position concerning static analysis from our earlier conversation, so I'll share my impression of his thoughts. I can't speak for Walter, of course, but I'm pretty sure that early on in our conversation he agreed that having the compiler catch local scope initialization issues was a good idea, or at least, wasn't a bad one (again, correct me if I'm wrong). I doubt he would be adverse to eventually having DMD perform this sort of static analysis to help developers, though I doubt it's a high priority for him. Ah, well if he's for it, then I misunderstood. I read through the entire thread (but not too carefully, just 1 read) and my impression was that he didn't like the idea because it would fail in some cases (and because D doesn't seem to love emitting compiler warnings in general), but if he likes it, then great. :)
Re: Which D features to emphasize for academic review article
On Tuesday, 14 August 2012 at 15:24:30 UTC, F i L wrote: On Tuesday, 14 August 2012 at 14:46:30 UTC, Simen Kjaeraas wrote: On Tue, 14 Aug 2012 16:32:25 +0200, F i L wrote: class Foo { float x; // I think this should be 0.0f // Walter thinks it should be NaN } In this situation static analysis can't help catch issues, and we're forced to rely on a default value of some kind. Really? We can catch (or, should be able to) missing initialization of stuff with @disable this(), but not floats? Classes have constructors, which lend themselves perfectly to doing exactly this (just pretend the member is a local variable). Perhaps there are problems with structs without disabled default constructors, but even those are trivially solvable by requiring a default value at declaration time. You know, I never actually thought about it much, but I think you're right. I guess the same rules could apply to type fields. C# structs, as you might recall, enforce definite initialization. :) We could do the same for structs and classes... what I said doesn't just apply to local variables.
Re: Which D features to emphasize for academic review article
On Tuesday, 14 August 2012 at 15:24:30 UTC, F i L wrote: Really? We can catch (or, should be able to) missing initialization of stuff with @disable this(), but not floats? Classes have constructors, which lend themselves perfectly to doing exactly this (just pretend the member is a local variable). Perhaps there are problems with structs without disabled default constructors, but even those are trivially solvable by requiring a default value at declaration time. You know, I never actually thought about it much, but I think you're right. I guess the same rules could apply to type fields. Mmmm... What if you added a command that has a file/local scope? perhaps following the @disable this(), it could be @disable init; or @disable .init. This would only work for built-in types, and possibly structs with variables that aren't explicitly set with default values. It sorta already fits with what's there. @disable init; //global scope in file, like @safe. struct someCipher { @disable init; //local scope, in this case the whole struct. int[][] tables; //now gives compile-time error unless @disable this() used. ubyte[] key = [1,2,3,4]; //explicitly defined as a default this(ubyte[] k, int[][] t){key=k;tables=t;} } void myfun() { someCipher x; //compile time error since struct fails (But not at this line unless @disable this() used) someCipher y = someCipher([[1,2],[1,2]]); //should work as expected. }
Unions destructors and GC precision
Before C++11 you weren't allowed to write something like: union U { int x; std::vector v; } myu; because v has an elaborate destructor. In C++11 they have added "Unrestricted unions", already present in g++ since version 4.6: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2544.pdf D2 doesn't give you that restriction, and when an union goes out of scope it calls the destructors of all its fields: import std.stdio; struct Foo1 { ~this() { writeln("Foo1.dtor"); } } struct Foo2 { ~this() { writeln("Foo2.dtor"); } } struct Foo3 { ~this() { writeln("Foo3.dtor"); } } union U { Foo1 f1; Foo2 f2; Foo3 f3; } void main() { U u; } Output: Foo3.dtor Foo2.dtor Foo1.dtor It looks cute, but I think that's wrong, and it causes problems. This program crashes, because only u.f.__dtor() should be called, because a union is just one of its fields: import std.stdio, core.stdc.stdlib; struct Foo { int* p; ~this() { writeln("Foo.dtor"); if (p) free(p); } } struct Bar { int* p; ~this() { writeln("Bar.dtor"); if (p) free(p); } } union U { Foo f; Bar b; ~this() { writeln("U.dtor"); } } void main() { U u; u.f.p = cast(int*)malloc(10 * int.sizeof); } (This code can be fixed adding a "p = null;" after the "if (p)" line in both Foo and Bar, but this is beside the point, because it means fixing the problem at the wrong level. What if I can't modify the source code of Foo and Bar?). The compiler in general can't know what dtor field to call, C++11 "solves" this problem looking at the union, if one of its fields has a destructor, it disables the automatic creation of the constructor, destructor, copy and assignment methods of the union. So you have to write those methods manually. Why D isn't doing the same? It seems a simple idea. With that idea you are forced to write a destructor and opAssign (but only if one or more fields of the union has a destructor. If all union fields are simple like an int or float, then the compiler doesn't ask you to write the union dtor): import std.stdio, core.stdc.stdlib; struct Foo { int* p; ~this() { writeln("Foo.dtor"); if (p) free(p); } } struct Bar { int* p; ~this() { writeln("Bar.dtor"); if (p) free(p); } } struct Spam { bool isBar; union { Foo f; Bar b; ~this() { writeln("U.dtor ", isBar); if (isBar) b.__dtor(); else f.__dtor(); } } } void main() { Spam s; s.f.p = cast(int*)malloc(10 * int.sizeof); } If you don't have a easy to reach tag like isBar, then things become less easy. Probably you have to call b.__dtor() or f.__dtor() manually: import std.stdio, core.stdc.stdlib; struct Foo { int* p; ~this() { writeln("Foo.dtor"); if (p) free(p); } } struct Bar { int* p; ~this() { writeln("Bar.dtor"); if (p) free(p); } } struct Spam { bool isBar; union { Foo f; Bar b; ~this() {} // empty } } void main() { Spam s; s.f.p = cast(int*)malloc(10 * int.sizeof); scope(exit) s.f.__dtor(); } -- A related problem with unions is the GC precision. We want a more precise GC, but unions reduce the precision. To face this problem time ago I have suggested to add standard method named onMark() that is called at run-time by the GC. It returns the positional number of the union field currently active. This means during the mark phase of the GC it calls onMark of the union, in this example the union has just the f and b fields, so the onMark has to return just 0 or 1: class Spam { bool isBar; union { Foo f; Bar b; ~this() { writeln("U.dtor ", isBar); if (isBar) b.__dtor(); else f.__dtor(); } size_t onMark() { return isBar ? 1 : 0; } } } onMark() is required only if the union contains one or more fields that contain pointers. I don't know if this idea is good enough (where to store the mark bits?). Again, if a nice isBar tag is not easy to reach, things become more complex. --- Maybe there is a way to merge the two solutions, creating something simpler. In this design instead of onMark it's required a method like activeField() that at runtime tells what's the field currently "active" of the union. This method is called by both the GC at runtime and when the union goes out of scope to know what field destructor to call: struct Spam { bool isBar; union { Foo f; Bar b; size_t activeField(size_t delegate() callMe=null) { return isBar ? 1 : 0; } } } So with activeField there
Re: DMD diagnostic - any way to remove identical lines from final dmd error log?
On 14-Aug-12 12:48, Don Clugston wrote: On 14/08/12 08:59, Don Clugston wrote: On 13/08/12 18:47, Dmitry Olshansky wrote: I seriously consider writing a simple postprocessor for dmd's output. Once dmd became able to recover from errors and crawl on it started to produce horrific amounts of redundant text on failure. Observe for instance that there are only 6 + 2 = 8 lines of interest: Spurious or repeated error messages should be considered to be bugs. Please put test cases in Bugzilla. A long time ago, the compiler used to spew reams of garbage all the time. Now it rarely happens. Will do. Other food for thought is to try to indicate explicitly which errors are related vs unrelated, which are collateral, like failed template instantiation that rolls out the whole path of failure (but one have to read the text carefully to get where it starts). That's already happening. Supplemental messages don't have the word 'Error' at the start of the error message. One fairly easy way to solve this, would be that once a template *instantiation* has failed, the template *definition* would be marked as doubtful, and any further instantiation using that definition would have all error messages suppressed. If an error occurred, a single error would be produced stating that the template instantiation failed. I think it would be nice to merge different template instantiation failures with identical lists of error messages (or simply same lines). In my case all of them have the same error list (2 lines), in general it may end up having few different groups of failed instantiations The downside would be that if the template instantiation failed for a completely different reason the second time, its root cause error would not be shown. Yes, see the idea above.
Re: D Shell [was Re: A C++ interpreter]
On 2012-08-13 17:36, jerro wrote: Rdmd already has this functionality with the --eval flag. You are supposed to pass the code as a command line parameter, but you can use it with files like this: cat - test.d <<< "--eval=" | xargs -0 rdmd I've only tried this on Linux. Yeah, but I need to hook it up from within TextMate, which isn't a problem. -- /Jacob Carlborg
Re: DFL
thank you very kindly! On Tuesday, 14 August 2012 at 15:17:23 UTC, Jesse Phillips wrote: On Sunday, 12 August 2012 at 16:58:08 UTC, asker wrote: hi, is there a working dfl for dmd 2060 win? thanks I pushed a branch containing most of the existing pull requests: https://github.com/JesseKPhillips/dfl/tree/acceptPulls This builds for me with dmd 2.060 and surprisingly 2.059.
Re: DFL
On Tuesday, 14 August 2012 at 15:46:40 UTC, d_follower wrote: If only using wine, DFL is too tied to Win32 and was never supposed to run on Linux. There is a GTK version which I don't think was ever completed and has received no maintenance for D2.
Re: DFL
On Tuesday, 14 August 2012 at 15:26:39 UTC, Jordi Sayol wrote: Al 14/08/12 16:45, En/na Francisco Almeida ha escrit: On Sunday, 12 August 2012 at 16:58:08 UTC, asker wrote: hi, is there a working dfl for dmd 2060 win? thanks Hi there. Not too long ago, I checked out DFL and got the library, plus most samples, to build with DMD 2.059, so I do have a local modified copy that works (for the most part). I think getting it to build on DMD 2.060 will also be feasible., I'll try that as well. Email me if you'd like to receive a zip of the fixed source. Did you get it working on Linux too? If only using wine, DFL is too tied to Win32 and was never supposed to run on Linux.
Re: DFL
Al 14/08/12 16:45, En/na Francisco Almeida ha escrit: > On Sunday, 12 August 2012 at 16:58:08 UTC, asker wrote: >> hi, >> is there a working dfl for dmd 2060 win? >> >> thanks > > Hi there. > Not too long ago, I checked out DFL and got the library, plus most samples, > to build with DMD 2.059, so I do have a local modified copy that works (for > the most part). > > I think getting it to build on DMD 2.060 will also be feasible., I'll try > that as well. Email me if you'd like to receive a zip of the fixed source. > Did you get it working on Linux too? Can you pull these modifications? -- Jordi Sayol
Re: Which D features to emphasize for academic review article
On Tuesday, 14 August 2012 at 14:46:30 UTC, Simen Kjaeraas wrote: On Tue, 14 Aug 2012 16:32:25 +0200, F i L wrote: class Foo { float x; // I think this should be 0.0f // Walter thinks it should be NaN } In this situation static analysis can't help catch issues, and we're forced to rely on a default value of some kind. Really? We can catch (or, should be able to) missing initialization of stuff with @disable this(), but not floats? Classes have constructors, which lend themselves perfectly to doing exactly this (just pretend the member is a local variable). Perhaps there are problems with structs without disabled default constructors, but even those are trivially solvable by requiring a default value at declaration time. You know, I never actually thought about it much, but I think you're right. I guess the same rules could apply to type fields.
Re: DFL
On Sunday, 12 August 2012 at 16:58:08 UTC, asker wrote: hi, is there a working dfl for dmd 2060 win? thanks I pushed a branch containing most of the existing pull requests: https://github.com/JesseKPhillips/dfl/tree/acceptPulls This builds for me with dmd 2.060 and surprisingly 2.059.
Re: DFL
On Sunday, 12 August 2012 at 16:58:08 UTC, asker wrote: hi, is there a working dfl for dmd 2060 win? thanks Hi there. Not too long ago, I checked out DFL and got the library, plus most samples, to build with DMD 2.059, so I do have a local modified copy that works (for the most part). I think getting it to build on DMD 2.060 will also be feasible., I'll try that as well. Email me if you'd like to receive a zip of the fixed source.
Re: Which D features to emphasize for academic review article
On Tue, 14 Aug 2012 16:32:25 +0200, F i L wrote: class Foo { float x; // I think this should be 0.0f // Walter thinks it should be NaN } In this situation static analysis can't help catch issues, and we're forced to rely on a default value of some kind. Really? We can catch (or, should be able to) missing initialization of stuff with @disable this(), but not floats? Classes have constructors, which lend themselves perfectly to doing exactly this (just pretend the member is a local variable). Perhaps there are problems with structs without disabled default constructors, but even those are trivially solvable by requiring a default value at declaration time. -- Simen
Re: Which D features to emphasize for academic review article
Mehrdad wrote: Note to Walter: You're obviously correct that you can make an arbitrarily complex program to make it too difficult for the compiler to enforce initialization, the way C# does (and gives up in some cases). [ ... ] I think some here are mis-interpreting Walters position concerning static analysis from our earlier conversation, so I'll share my impression of his thoughts. I can't speak for Walter, of course, but I'm pretty sure that early on in our conversation he agreed that having the compiler catch local scope initialization issues was a good idea, or at least, wasn't a bad one (again, correct me if I'm wrong). I doubt he would be adverse to eventually having DMD perform this sort of static analysis to help developers, though I doubt it's a high priority for him. The majority of the conversation after that was concerning struct/class fields defaults: class Foo { float x; // I think this should be 0.0f // Walter thinks it should be NaN } In this situation static analysis can't help catch issues, and we're forced to rely on a default value of some kind. Both Walter and I have stated our opinion's reasoning previously, so I won't repeat them here.
Re: Which D features to emphasize for academic review article
On 14/08/12 12:31, Mehrdad wrote: On Saturday, 11 August 2012 at 05:41:23 UTC, Walter Bright wrote: On 8/10/2012 9:55 PM, F i L wrote: On the first condition, without an 'else z = ...', or if the condition was removed at a later time, then you'll get a compiler error and be forced to explicitly assign 'z' somewhere above using it. So C# and D work in "similar" ways in this respect except that C# catches these issues at compile-time, whereas in D you need to: 1. run the program 2. get bad result 3. hunt down bug However, and I've seen this happen, people will satisfy the compiler complaint by initializing the variable to any old value (usually 0), because that value will never get used. Later, after other things change in the code, that value suddenly gets used, even though it may be an incorrect value for the use. Note to Walter: You're obviously correct that you can make an arbitrarily complex program to make it too difficult for the compiler to enforce initialization, the way C# does (and gives up in some cases). What you seem to be missing is that the issue you're saying is correct in theory, but too much of a corner case in practice. C#/Java programmers ___rarely___ run into the sort of issue you're mentioning, and even when they do, they don't have nearly as much of a problem with fixing it as you seem to think. The only reason you run into this sort of problem (assuming you do, and it's not just a theoretical discussion) is that you're in the C/C++ mindset, and using variables in the C/C++ fashion. If you were a "C#/Java Programmer" instead of a "C++ Programmer", you simply _wouldn't_ try to make things so complicated when coding, and you simply _wouldn't_ run into these problems the way you /think/ you would, as a C++ programmer. Regardless, it looks to me like you two are arguing for two orthogonal issues: F i L: The compiler should detect uninitialized variables. Walter: The compiler should choose initialize variables with NaN. What I'm failing to understand is, why can't we have both? 1. Compiler _warns_ about "uninitialized variables" (or scalars, at least) the same way C# and Java do, __unless__ the user takes the address of the variable, in which case the compiler gives up trying to detect the flow (like C#). Bonus points: Try to detect a couple of common cases (e.g. if/else) instead of giving up so easily. 2. In any case, the compiler initializes the variable with whatever default value Walter deems useful. Then you get the best of both worlds: 1. You force the programmer to manually initialize the variable in most cases, forcing him to think about the default value. It's almost no trouble for 2. In the cases where it's not possible, the language helps the programmer catch bugs. Why the heck D avoids #1, I have no idea. DMD detects uninitialized variables if you compile with -O. It's hard to implement the full Monty at the moment, because all that code is in the backend rather than the front-end. It's one of the _major_ features of C# and Java that help promote correctness, and #1 looks orthogonal to #2 to me. Completely agree. I always thought the intention was that assigning to NaN was simply a way of catching the difficult cases that slip through compile-time checks. Which includes the situation where the compile-time checking isn't yet implemented at all. This is the first time I've heard the suggestion that it might never be implemented. The thing which is really bizarre though, is float.init. I don't know what the semantics of it are.
Re: Which D features to emphasize for academic review article
On Tuesday, 14 August 2012 at 10:31:30 UTC, Mehrdad wrote: Note to Walter: You're obviously correct that you can make an arbitrarily complex program to make it too difficult for the compiler to enforce initialization, the way C# does (and gives up in some cases). What you seem to be missing is that the issue you're saying is correct in theory, but too much of a corner case in practice. C#/Java programmers ___rarely___ run into the sort of issue you're mentioning, and even when they do, they don't have nearly as much of a problem with fixing it as you seem to think. Completely agree. I find it quite useful in C#. It helps a lot in hairy code (nested if/foreach/try) to make sure all cases are handled when initializing variable. Compilation errors can be simply dismissed by assigning a 'default' value to variable at the beginning the functions, but is generally a sloppy programing and you loose useful help of the compiler. The rules in C# are very simple and almost verbatim can be applied to D http://msdn.microsoft.com/en-us/library/aa691172%28v=vs.71%29.aspx
Re: DMD diagnostic - any way to remove identical lines from final dmd error log?
On 8/14/12 5:32 AM, Paulo Pinto wrote: Personally I loved the way Turbo Pascal used to work with compile failure on the first error. Thanks to the fast compile times, it was easier and faster to fix-compile-find_next_error, than try to sort out the real errors from a dump of error messages. But I seem to be in the minority regarding compiler error messages. I guess the "head" command can be of use here! Andrei
Re: Which D features to emphasize for academic review article
On Saturday, 11 August 2012 at 05:41:23 UTC, Walter Bright wrote: On 8/10/2012 9:55 PM, F i L wrote: On the first condition, without an 'else z = ...', or if the condition was removed at a later time, then you'll get a compiler error and be forced to explicitly assign 'z' somewhere above using it. So C# and D work in "similar" ways in this respect except that C# catches these issues at compile-time, whereas in D you need to: 1. run the program 2. get bad result 3. hunt down bug However, and I've seen this happen, people will satisfy the compiler complaint by initializing the variable to any old value (usually 0), because that value will never get used. Later, after other things change in the code, that value suddenly gets used, even though it may be an incorrect value for the use. Note to Walter: You're obviously correct that you can make an arbitrarily complex program to make it too difficult for the compiler to enforce initialization, the way C# does (and gives up in some cases). What you seem to be missing is that the issue you're saying is correct in theory, but too much of a corner case in practice. C#/Java programmers ___rarely___ run into the sort of issue you're mentioning, and even when they do, they don't have nearly as much of a problem with fixing it as you seem to think. The only reason you run into this sort of problem (assuming you do, and it's not just a theoretical discussion) is that you're in the C/C++ mindset, and using variables in the C/C++ fashion. If you were a "C#/Java Programmer" instead of a "C++ Programmer", you simply _wouldn't_ try to make things so complicated when coding, and you simply _wouldn't_ run into these problems the way you /think/ you would, as a C++ programmer. Regardless, it looks to me like you two are arguing for two orthogonal issues: F i L: The compiler should detect uninitialized variables. Walter: The compiler should choose initialize variables with NaN. What I'm failing to understand is, why can't we have both? 1. Compiler _warns_ about "uninitialized variables" (or scalars, at least) the same way C# and Java do, __unless__ the user takes the address of the variable, in which case the compiler gives up trying to detect the flow (like C#). Bonus points: Try to detect a couple of common cases (e.g. if/else) instead of giving up so easily. 2. In any case, the compiler initializes the variable with whatever default value Walter deems useful. Then you get the best of both worlds: 1. You force the programmer to manually initialize the variable in most cases, forcing him to think about the default value. It's almost no trouble for 2. In the cases where it's not possible, the language helps the programmer catch bugs. Why the heck D avoids #1, I have no idea. It's one of the _major_ features of C# and Java that help promote correctness, and #1 looks orthogonal to #2 to me. For users who don't like #1: They can suppress the warning. Nothing lost, anyway. For users who DO like #1: They can turn it into an error. A lot to be gained.
Re: DMD diagnostic - any way to remove identical lines from final dmd error log?
On 14/08/12 11:32, Paulo Pinto wrote: On Tuesday, 14 August 2012 at 08:48:14 UTC, Don Clugston wrote: On 14/08/12 08:59, Don Clugston wrote: On 13/08/12 18:47, Dmitry Olshansky wrote: I seriously consider writing a simple postprocessor for dmd's output. Once dmd became able to recover from errors and crawl on it started to produce horrific amounts of redundant text on failure. Observe for instance that there are only 6 + 2 = 8 lines of interest: Spurious or repeated error messages should be considered to be bugs. Please put test cases in Bugzilla. A long time ago, the compiler used to spew reams of garbage all the time. Now it rarely happens. Other food for thought is to try to indicate explicitly which errors are related vs unrelated, which are collateral, like failed template instantiation that rolls out the whole path of failure (but one have to read the text carefully to get where it starts). That's already happening. Supplemental messages don't have the word 'Error' at the start of the error message. One fairly easy way to solve this, would be that once a template *instantiation* has failed, the template *definition* would be marked as doubtful, and any further instantiation using that definition would have all error messages suppressed. If an error occurred, a single error would be produced stating that the template instantiation failed. The downside would be that if the template instantiation failed for a completely different reason the second time, its root cause error would not be shown. But this latest release is the only time such errors have been shown anyway. Personally I loved the way Turbo Pascal used to work with compile failure on the first error. Thanks to the fast compile times, it was easier and faster to fix-compile-find_next_error, than try to sort out the real errors from a dump of error messages. To the best of my knowledge, DMD gives very few error messages which are not real. Every release, I eliminate a couple more spurious ones. It's starting to be difficult to find them. Seriously, if you are finding ANY error messages for things which are not real errors, that is a bug. But I seem to be in the minority regarding compiler error messages. -- Paulo
Re: DMD diagnostic - any way to remove identical lines from final dmd error log?
On Tuesday, 14 August 2012 at 08:48:14 UTC, Don Clugston wrote: On 14/08/12 08:59, Don Clugston wrote: On 13/08/12 18:47, Dmitry Olshansky wrote: I seriously consider writing a simple postprocessor for dmd's output. Once dmd became able to recover from errors and crawl on it started to produce horrific amounts of redundant text on failure. Observe for instance that there are only 6 + 2 = 8 lines of interest: Spurious or repeated error messages should be considered to be bugs. Please put test cases in Bugzilla. A long time ago, the compiler used to spew reams of garbage all the time. Now it rarely happens. Other food for thought is to try to indicate explicitly which errors are related vs unrelated, which are collateral, like failed template instantiation that rolls out the whole path of failure (but one have to read the text carefully to get where it starts). That's already happening. Supplemental messages don't have the word 'Error' at the start of the error message. One fairly easy way to solve this, would be that once a template *instantiation* has failed, the template *definition* would be marked as doubtful, and any further instantiation using that definition would have all error messages suppressed. If an error occurred, a single error would be produced stating that the template instantiation failed. The downside would be that if the template instantiation failed for a completely different reason the second time, its root cause error would not be shown. But this latest release is the only time such errors have been shown anyway. Personally I loved the way Turbo Pascal used to work with compile failure on the first error. Thanks to the fast compile times, it was easier and faster to fix-compile-find_next_error, than try to sort out the real errors from a dump of error messages. But I seem to be in the minority regarding compiler error messages. -- Paulo
Re: Gsoc Mentor summit… and fortran ;)
On 27 October 2011 21:37, Fawzi Mohamed wrote: > I came back from the Goggle Summer of Code mentor summit. > It was nice to see many people from other open source communities, and meet > David face to face ;). > > We did try to leave some notes to remember what we said and for those who > could not attend, but this wasn't the strong point of this conference, but it > did improve (at least my note taking activity did)… > Anyway if you are interested to have a glimpse on what was discussed you can > go to http://gsoc-wiki.osuosl.org/index.php/2011 > > David and me obviously did try to show how nice D is, but we also saw the > cool stuff other are doing, and discussed both the practical and the more > philosophical aspects of open source. > > For example from the unexpected interesting stuff I can tell of a discussion > that I had with Tobias Burnus that works on fortran fronted I realized that > intent(in) in fortran is very close to immutable (actually even stronger, as > it guarantees that the pointer will not escape, so the compiler is even ok in > copying stuff on entry (this also for intent(inout), which had no real > corresponding thing in D). > > intent(inout) x even guarantees that x=5; f(); assert(x==5);. f can obviously > also have x as intent(in). > Fortran does this to give the optimizer as much freedom as possible. > D doesn't have all that, but with immutable and pure, it can use some of the > same optimizations. > Indeed it is possible that gdc could use some of the fortran annotations > something that I promptly mailed Iain. > > Here the different philosophy is visible: D give safe primitives, and > behavior, and try to optimize; fortran choose fast options, define it as the > way things work, and make the programmer job to make sure he uses things > right, something that is simplified for the fact that fortran is typically > threaded only through OpenMP. > > ciao > Fawzi I've just gotten round to implementing this, and in the middle of testing it out. :-) I'll write a spec review of it in a short while if you are interested. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';
Re: DMD diagnostic - any way to remove identical lines from final dmd error log?
On 14/08/12 08:59, Don Clugston wrote: On 13/08/12 18:47, Dmitry Olshansky wrote: I seriously consider writing a simple postprocessor for dmd's output. Once dmd became able to recover from errors and crawl on it started to produce horrific amounts of redundant text on failure. Observe for instance that there are only 6 + 2 = 8 lines of interest: Spurious or repeated error messages should be considered to be bugs. Please put test cases in Bugzilla. A long time ago, the compiler used to spew reams of garbage all the time. Now it rarely happens. Other food for thought is to try to indicate explicitly which errors are related vs unrelated, which are collateral, like failed template instantiation that rolls out the whole path of failure (but one have to read the text carefully to get where it starts). That's already happening. Supplemental messages don't have the word 'Error' at the start of the error message. One fairly easy way to solve this, would be that once a template *instantiation* has failed, the template *definition* would be marked as doubtful, and any further instantiation using that definition would have all error messages suppressed. If an error occurred, a single error would be produced stating that the template instantiation failed. The downside would be that if the template instantiation failed for a completely different reason the second time, its root cause error would not be shown. But this latest release is the only time such errors have been shown anyway.
Re: Which D features to emphasize for academic review article
On 14/08/12 05:03, TJB wrote: On Monday, 13 August 2012 at 10:11:06 UTC, Don Clugston wrote: ... I have come to believe that there are very few algorithms originally designed for integers, which also work correctly for floating point. Integer code nearly always assumes things like, x + 1 != x, x == x, (x + y) - y == x. for (y = x; y < x + 10; y = y + 1) { } How many times does it loop? Don, I would appreciate your thoughts on the issue of re-implementing numeric codes like BLAS and LAPACK in pure D to benefit from the many nice features listed in this discussion. Is it feasible? Worthwhile? Thanks, TJB I found that when converting code for Special Functions from C to D, the code quality improved enormously. Having 'static if' and things like float.epsilon as built-ins makes a surprisingly large difference. It encourages correct code. (For example, it makes any use of magic numbers in the code look really ugly and wrong). Unit tests help too. That probably doesn't apply so much to LAPACK and BLAS, but it would be interesting to see how far we can get with the new SIMD support.
Re: DMD diagnostic - any way to remove identical lines from final dmd error log?
On 13/08/12 18:47, Dmitry Olshansky wrote: I seriously consider writing a simple postprocessor for dmd's output. Once dmd became able to recover from errors and crawl on it started to produce horrific amounts of redundant text on failure. Observe for instance that there are only 6 + 2 = 8 lines of interest: Spurious or repeated error messages should be considered to be bugs. Please put test cases in Bugzilla. A long time ago, the compiler used to spew reams of garbage all the time. Now it rarely happens. Other food for thought is to try to indicate explicitly which errors are related vs unrelated, which are collateral, like failed template instantiation that rolls out the whole path of failure (but one have to read the text carefully to get where it starts). That's already happening. Supplemental messages don't have the word 'Error' at the start of the error message. There are still cases where