Re: First project: questions on how-to, and on language features
On Sunday, 24 January 2016 at 18:52:41 UTC, Chris Wright wrote: There is no documentation, so I have no idea what you're trying to achieve here. So your questions about why this isn't in Phobos, whether there are any other libraries that do this, and whether there's a way to simplify your contracts are impossible for me to answer. Objections have been noted and (hopefully) corrected: https://github.com/ajvincent/d-experiments/blob/master/IntervalMap/source/intervalmap.d I'm going for the concept of versioning data - first a single value, and then members of an array. (I haven't implemented the versioning of arrays yet.) That's why I said it's an inverse of Phobos ranges: each iteration call to a range could give you a different value. Here, several versions can point to one value. Feedback is still most strongly welcomed.
Re: First project: questions on how-to, and on language features
On 01/24/2016 04:26 AM, Marc Schütz wrote: >> (2) In the unittest code, I have a block that I want to rewrite using >> assertThrown, but I can't figure out from either the book or the >> website the correct usage. What's the right way to specify a >> StringException with a particular message I expect to receive? > > Here's the relevant documentation: > https://dlang.org/phobos/std_exception.html#.assertThrown > https://dlang.org/phobos/std_exception.html#.collectExceptionMsg Here is another link for completeness: http://ddili.org/ders/d.en/unit_testing.html#ix_unit_testing.assertThrown,%20std.exception Ali
Re: First project: questions on how-to, and on language features
On Sunday, 24 January 2016 at 06:07:13 UTC, Alex Vincent wrote: (1) It's not clear how to specify certain parts of a module or library as non-exportable. Is that possible? Is it desirable? (It's not that important, yet, but still...) Yes, definitely. By default symbols in a module are `public`, but you can mark them as `private`. These aren't accesible from other modules: module test; void foo() { }// public, because there's no annotation private bar() { } // private void bar2() { } // public again private: // everything from here on is private void bla() { } void blubb() { } (2) In the unittest code, I have a block that I want to rewrite using assertThrown, but I can't figure out from either the book or the website the correct usage. What's the right way to specify a StringException with a particular message I expect to receive? Here's the relevant documentation: https://dlang.org/phobos/std_exception.html#.assertThrown https://dlang.org/phobos/std_exception.html#.collectExceptionMsg `assertThrown()` doesn't allow to check the message directly, it can only check whether a particular type of exception has been thrown: assertThrown!StringException(throw new StringException("test")); Instead, you can use `collectExceptionMsg()` to check both the message and the exception type: assert( collectExceptionMsg!StringException(throw ...) == "test" ); (4) How should the scope(exit) and scope(failure) guard statements intermix with preconditions and postconditions? Pre- and postconditions are supposed to run before you enter the function, or after you left it, respectively. Therefore, and scope() blocks in the function body would already have completed when the postcondition is entered. OTOH, scope() blocks only run if control flow has passed through them. In a precondition, this hasn't happened yet, and therefore they will not run. If you mean whether you can use scope() blocks in pre- and postconditions, yes, you can. The will then run when you leave the pre- and postcondition. But usually, pre- and postconditions only consist of very little code that's not supposed to do any serious work, so they are less likely to be used there. Or, looking at it from a different angle: A scope() block only runs at the end of the lexical scope / block it appears in. Pre- and postconditions are not part of the function body, or vice versa. Therefore, see above. (5) My append() function has a postcondition that currently depends on debug-only members of the class being set in the precondition. This seems artificial - not the part about setting these variables in the precondition, but having the variables defined on the class to begin with. If they were defined only for the lifetime of the function's execution, starting in the precondition, this would be more natural. Is there a Right Way to define function-only debug variables for use in postconditions? If not, would this be a valid use-case to consider amending the language specification to clarify? I'm not an expert in contract programming, but as I see it, your precondition doesn't actually check anything, you're kinda abusing them as preparation for your postcondition. That's likely not the way it's supposed to be. I see what you're trying to achieve, and I believe it's legitimate to check for... You could either just move the assert()s into the function body just before the end, where you have access to the local variables (but you could easily miss an early return), or put them into a scope(exit) block (but then you could accidentally check it too early). Your best bet here is probably to check it in a unittest, although they are for a slightly different purpose, strictly speaking.
Re: First project: questions on how-to, and on language features
On Sun, 24 Jan 2016 06:07:13 +, Alex Vincent wrote: > Source code: > https://alexvincent.us/d-language/samples/intervalmap-rev1.d.txt There is no documentation, so I have no idea what you're trying to achieve here. So your questions about why this isn't in Phobos, whether there are any other libraries that do this, and whether there's a way to simplify your contracts are impossible for me to answer. I notice you're using identifiers that start with double underscores. I'd recommend not making a habit of that. The compiler generates symbols for some things, and those symbols start with a double underscore. For example: class Foo { this(int i) {} void __ctor(int i) {} } auto f = new Foo(1); This produces an error like: dubleuscore.d(13): Error: dubleuscore.Foo.__ctor called with argument types (int) matches both: dubleuscore.d(4): dubleuscore.Foo.this(int i) and: dubleuscore.d(7): dubleuscore.Foo.__ctor(int i) The compiler can add more such identifiers without warning, which could break your code in interesting ways. > After reading Ali Çehreli's book, "Programming in D", I wrote this > little sample up as a starting point for my explorations into D. I've > long admired the D language, but I've never actually tried to write > practical code in D. > > So I wrote this little sample up in dlangide, and as I was going, > I realized I had quite a few questions. > > (1) It's not clear how to specify certain parts of a module or library > as non-exportable. Is that possible? Is it desirable? (It's not that > important, yet, but still...) As Marc mentioned, the 'private' keyword. You can use it directly: private int f; int g; // implicitly public in blocks: private { int h; int i; } int j; // implicitly public or label style: private: int k; int m; public int n; // have to explicitly mark anything else public That's all module-local. If you need to restrict things to your package, you can use the 'package' keyword, which functions identically. All these syntax variants work everywhere. I find it handy, for instance, to write my code like: class Foo { private { // fields go here } // everything else is generally public } Aside from that, if you do not add a documentation comment to something, it will not be mentioned at all in the generated documentation. This makes it difficult for users to discover, in case you really need something to be public but don't want people to use it. But using 'package' rather than 'public' will usually suffice in those cases. > (3) How do I actually create a library in dub? How does dub determine > what files to build? I believe Dub includes all files by default. > (4) How should the scope(exit) and scope(failure) guard statements > intermix with preconditions and postconditions? Marc answered this, but while we're on the topic of preconditions, I notice your usage of enforce: enforce(index > upperEdge, new StringException("index must be greater than upperEdge")); The idiom in use in Phobos is: enforce!StringException(index > upperEdge, "index must be greater than upperEdge");
First project: questions on how-to, and on language features
Source code: https://alexvincent.us/d-language/samples/intervalmap-rev1.d.txt After reading Ali Çehreli's book, "Programming in D", I wrote this little sample up as a starting point for my explorations into D. I've long admired the D language, but I've never actually tried to write practical code in D. So I wrote this little sample up in dlangide, and as I was going, I realized I had quite a few questions. (1) It's not clear how to specify certain parts of a module or library as non-exportable. Is that possible? Is it desirable? (It's not that important, yet, but still...) (2) In the unittest code, I have a block that I want to rewrite using assertThrown, but I can't figure out from either the book or the website the correct usage. What's the right way to specify a StringException with a particular message I expect to receive? (3) How do I actually create a library in dub? How does dub determine what files to build? (4) How should the scope(exit) and scope(failure) guard statements intermix with preconditions and postconditions? (5) My append() function has a postcondition that currently depends on debug-only members of the class being set in the precondition. This seems artificial - not the part about setting these variables in the precondition, but having the variables defined on the class to begin with. If they were defined only for the lifetime of the function's execution, starting in the precondition, this would be more natural. Is there a Right Way to define function-only debug variables for use in postconditions? If not, would this be a valid use-case to consider amending the language specification to clarify? (6) Would someone please review my sample code and offer feedback? :-) (7) Naming: This code is the start of a port of a mini-library I wrote in JavaScript which I called "ObjectRange". However, in Phobos, the term "Range" has a very different meaning - in fact, almost the opposite meaning of what this code does. I asked for a better name in the D IRC channel, and someone suggested Interval, based on the mathematical definition of the word. IntervalMap seemed more accurate, since there is a payload to each interval. Does the name make sense in the context? (8) Is there a similar, more mature library out there which tries to achieve what I'm doing here? I'm rather surprised I didn't see anything like it in the standard library...