Re: First project: questions on how-to, and on language features

2016-02-02 Thread Alex Vincent via Digitalmars-d-learn

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

2016-01-25 Thread Ali Çehreli via Digitalmars-d-learn

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

2016-01-24 Thread Marc Schütz via Digitalmars-d-learn

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

2016-01-24 Thread Chris Wright via Digitalmars-d-learn
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

2016-01-23 Thread Alex Vincent via Digitalmars-d-learn

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...