Re: How does import work?

2010-10-19 Thread Jens Mueller
Steven Schveighoffer wrote:
> On Tue, 19 Oct 2010 05:04:03 -0400, Jens Mueller   
> wrote:
>
>> Hi,
>>
>> I have a simply example using imports that confuses me. Unfortunately I
>> cannot find explanation on the web site.
>> File a.d:
>> module a;
>>
>> // some import here
>> //import std.conv;
>>
>> File b.d:
>> module b;
>> import a;
>>
>> void main() {
>> }
>>
>> I do a
>> $ dmd -run b.d
>> and that works as expected.
>> If I commented in 'import std.conv;' in file a.d and do
>> $ dmd -run b.d
>> linking fails with
>> "b.o:(.data+0xc): undefined reference to `_D1a12__ModuleInfoZ'"
>>
>> I figured out that I need to add a.d like this
>> $ dmd a.d -run b.d
>> Because the ModuleInfo for a.d needs to be generated.
>>
>> So much for my limited understanding.
>> In my use case I want to do unit testing like this
>> $ dmd -unittest -run b.d
>>
>> It seems that I always have to built a library to make sure that an
>> import works. Can somebody explain the rational behind that? What is
>> ModuleInfo? And why is it needed? How can I make the unit testing work
>> per module? How do you do it?
>> I think I missed something essential about imports.
>
> ModuleInfo is the runtime representation of the module.  Modules can have 
> their own constructors and destructors to initialize global and  
> thread-local data.  You can also get the name of the module from the  
> module info.  They are stored by the compiler in an array that is  
> accessible at runtime.  A module's unit tests are also stored in the  
> module info.
>
> To answer your other questions, just unit test everything at once.  There 
> is no need to run each individual file.  In other words, just do:
>
> dmd -unittest -run b.d a.d
>
> And that will test all unittests in b and a.
>
> If you insist on only testing unittests in b, you still need a complete  
> program.  So a's module info must be included.  Therefore you need to do 
> a partial compilation:
>
> dmd -c a.d
>
> this creates a.o (or a.obj depending on your platform).  If a has  
> unittests they are *not* included in the object file.
>
> dmd -unittest -run b.d a.o
>
> Note that I'm passing the already-compiled version of a, this means it  
> will not be recompiled to add a's unit tests.  Why you'd want to do it  
> this way, I have no idea.

Thanks very much for your explanation. It just seemed natural to me to
test them separately. Often I do not know even which modules a module
depends on. And assuming there are many tests that might take long,
picking a specific one seemed the better option to me. In general if the
test suite is large and something fails then after the problem is fixed
or while fixing I want to run only the depended tests.
But admittedly this does not come up in practice, does it? I mean phobos
does not need it. Testing everything is fast.
So then I'll just test all.

Jens


Passing dynamic arrays

2010-11-08 Thread Jens Mueller
Hi,

I do not understand what's going on behind the scene with this code. Or
better said I have some idea but maybe I do not see the whole point.

void foo(int[] array) {
array.length += 1000; // may copy the array
array[0] = 1;
}

auto a = new int[1];
foo(a);
assert(a[0] == 1); // fails if a needs to copied inside foo

I do understand that array.length += 1000 may copy the array. Page 98 of
The D Programming Language and
http://www.digitalmars.com/d/2.0/arrays.html#resize shed some light on
this matter. Passing a to foo is achieved by copying let's say a begin
and an end pointer. Now due to array.length += 1000 new memory might be
needed and that's why the begin and end pointer change and array[0]
works now on different data. That's why the assert fails. Right?

I find this behavior rather strange. Arrays are neither passed by value
(copying the whole array) nor by reference. I see reasons for doing it
like this, e.g. doing array = array[1..$] inside should not affect the
outside.
But I wonder whether these semantics are well enough documented?
I think I should use ref int[] in the example above, shouldn't I?

Jens


Re: Passing dynamic arrays

2010-11-08 Thread Jens Mueller
Jesse Phillips wrote:
> Jens Mueller Wrote:
> 
> > Hi,
> > 
> > I do not understand what's going on behind the scene with this code. Or
> > better said I have some idea but maybe I do not see the whole point.
> > 
> > void foo(int[] array) {
> > array.length += 1000; // may copy the array
> > array[0] = 1;
> > }
> > 
> > auto a = new int[1];
> > foo(a);
> > assert(a[0] == 1); // fails if a needs to copied inside foo
> > 
> ...
> > I find this behavior rather strange. Arrays are neither passed by value
> > (copying the whole array) nor by reference. I see reasons for doing it
> > like this, e.g. doing array = array[1..$] inside should not affect the
> > outside.
> > But I wonder whether these semantics are well enough documented?
> > I think I should use ref int[] in the example above, shouldn't I?
> > 
> > Jens
> 
> But they are past by reference. You can modify the data all you want, but 
> cannot reassign the reference itself. Resizing the array may cause a 
> reassignment of that reference. It is not different from the following code 
> except resizing does not guarantee a reference change.
> 
> import std.stdio;
> 
> void assignValue(A a) {
>   a = new A();
>   a.value = 6;
> }
> class A {
>   int value;
> }
> void main() {
>   A a = new A();
>   assignValue(a);
>   writeln(a.value);
> }

I like that explanation. Jonathan is saying the same, I think. I'll
guess my misunderstanding is mainly caused by figuring out that a
reassign is happening and that a reassign to a reference changes the
reference. In C++ you cannot change a reference (I hope I'm right
here.). When using a std::vector one does not need to think about this.
What's the general use of a = new A() in the above code? Where is it
useful?

Jens


Re: Passing dynamic arrays

2010-11-08 Thread Jens Mueller
Kagamin wrote:
> Jens Mueller Wrote:
> 
> > I find this behavior rather strange. Arrays are neither passed by value
> > (copying the whole array) nor by reference. I see reasons for doing it
> > like this, e.g. doing array = array[1..$] inside should not affect the
> > outside.
> > But I wonder whether these semantics are well enough documented?
> 
> It may take some effort to explain it. Does it help, if you think about T[] 
> as not an array but a slice?

Yes. This behavior is well explained when one thinks about passing a
slice of data instead of an dynamic array. With a dynamic array I think
about the std::vector. But passing a reference to a std::vector is not
the same as passing a slice.

Jens


Re: Passing dynamic arrays

2010-11-09 Thread Jens Mueller
> > What's the general use of a = new A() in the above code? Where is it
> > useful?
> > 
> > Jens
> 
> I don't really have any good use-case examples. Maybe an initialization 
> function? Developed your own number object (big int) and were thinking in 
> terms of it being a refrence you thought 
> 
> a = a + BigInt(7);
> 
> would result in a being resigned in the calling function. Or maybe just a 
> function that swaps two class references:
> 
> void swap(T)(T a, T b) { // Correct void swap(T)(ref T a, ref T b) {
> auto tmp = a; a = b; b = tmp;
> }
> 
> Actually that turned out to be a pretty good one.

I do see why a = new A() is useful. But it makes only sense if I passed
a/b as ref a/b. Basically I wonder why I do not get a warning when
changing the reference in that situation. So my question is more why am
I allowed to change the reference even though I didn't pass it as ref a.
I was looking for a use of that. Assuming there is good use then there
is no reason to forbid it. But if there is no good use I'd like to be
warned when compiling the above swap. Because it's an error.
For dynamic arrays slicing is a good example to allow it. But why should
it be allowed for objects?

Jens


Re: Passing dynamic arrays

2010-11-09 Thread Jens Mueller
> > > I don't really have any good use-case examples. Maybe an initialization
> > > function? Developed your own number object (big int) and were thinking
> > > in terms of it being a refrence you thought
> > > 
> > > a = a + BigInt(7);
> > > 
> > > would result in a being resigned in the calling function. Or maybe just a
> > > function that swaps two class references:
> > > 
> > > void swap(T)(T a, T b) { // Correct void swap(T)(ref T a, ref T b) {
> > > 
> > > auto tmp = a; a = b; b = tmp;
> > > 
> > > }
> > > 
> > > Actually that turned out to be a pretty good one.
> > 
> > I do see why a = new A() is useful. But it makes only sense if I passed
> > a/b as ref a/b. Basically I wonder why I do not get a warning when
> > changing the reference in that situation. So my question is more why am
> > I allowed to change the reference even though I didn't pass it as ref a.
> > I was looking for a use of that. Assuming there is good use then there
> > is no reason to forbid it. But if there is no good use I'd like to be
> > warned when compiling the above swap. Because it's an error.
> > For dynamic arrays slicing is a good example to allow it. But why should
> > it be allowed for objects?
> 
> Why wouldn't you be able to change it? You can change any parameter as long 
> as 
> it's not const or immutable (or in, which implies const). The fact that it's 
> a 
> referenc is irrelevant. I can assign whatever I want to references and 
> pointers 
> in a function whether they were passed in or not. Sure, if you want to alter 
> the 
> original pointer or reference, that's not going to work unless it was passed 
> as 
> ref, but that's the same as any other parameter. Why would you expect 
> altering  
> a reference to alter the original? Sure, altering what it _refers to_ should 
> alter what the original refers to because they refer to the same thing, but 
> altering the reference itself shouldn't alter the original because they're 
> two 
> different references.
> 
> There is no reason why parameters should have to stay the same as what they 
> were 
> passed in as - regardless of whether they're value types or reference types. 
> If 
> you want that behavior, use const, in, or immutable.

I see your point. You argue that the behavior is consistent. My point is
that this consistency can lead to bugs. I may forget the ref. But I'll
keep in mind to never forget the ref if it is needed.

Jens


Re: Passing dynamic arrays

2010-11-10 Thread Jens Mueller
> > I see your point. You argue that the behavior is consistent. My point is
> > that this consistency can lead to bugs. I may forget the ref. But I'll
> > keep in mind to never forget the ref if it is needed.
> > 
> > Jens
> 
> Well, in the case of classes, I don't think it would be very common.
> 
> For arrays it can be nice since you can assign back a slice of the array that 
> you want to work with.
> 
> void main(string args) {
> args = args[1..$];
> }
> 
> Otherwise I suggest you start labeling all parameters with in. Then you are 
> prevented from modifying the reference, and can decide if it should be a ref 
> parameter. Who knows, maybe you'll find a reason to leave it off.

With dynamic arrays I totally agree. Slicing is very useful. I just want
a safe rule to work with it. Maybe that's not needed anymore because by
now I spend enough time on this that probably I'll never forget.
With in I also disallow changing the object itself, right? I want to
only forbid the changing of the reference of an argument inside the
function. With in/const I disallow every change. I may want to change
data of an array.

Jens

PS
The more we talk about it, the more I come to the conclusion that this
is just something you need to know. I can live with that.


Call to immutable method during immutable construction

2010-11-10 Thread Jens Mueller
Hi,

according to TDPL p. 294 the following call to fun should not be
allowed. But it compiles and I see not why that shouldn't be allowed. I think
it's a bug in TDPL but I'm unsure.

class A {
int a;
int[] b;
this() immutable {
a = 5;
b = [ 1, 2, 3 ];
fun();
}
void fun() immutable {
}
}

Any opinions?

Jens


Re: Call to immutable method during immutable construction

2010-11-10 Thread Jens Mueller
Jonathan M Davis wrote:
> On Wednesday, November 10, 2010 06:14:07 Jens Mueller wrote:
> > Hi,
> > 
> > according to TDPL p. 294 the following call to fun should not be
> > allowed. But it compiles and I see not why that shouldn't be allowed. I
> > think it's a bug in TDPL but I'm unsure.
> > 
> > class A {
> > int a;
> > int[] b;
> > this() immutable {
> > a = 5;
> > b = [ 1, 2, 3 ];
> > fun();
> > }
> > void fun() immutable {
> > }
> > }
> > 
> > Any opinions?
> 
> Well, regardless of what the correct behavior is, dmd is not entirely in line 
> with TDPL yet, so there's a good chance that dmd just hasn't been updated to 
> match TDPL yet.
> 
> Now, I'd have to read the appropriate section of the book again (and I don't 
> have it on me at the moment) to be sure, but IIRC, the reasoning as to why 
> calling fun() was illegal was because all member variables must be 
> initialized 
> in an immutable constructor only once, and they cannot be accessed before 
> they 
> are used, so you'd have to be sure that any other functions which  were 
> called 
> didn't access them (including any pre or post-conditions or the invariant), 
> and 
> the compiler is supposed to take the easy and simple route of simply 
> disallowing 
> calls to other member functions in an immutable constructor rather than 
> trying 
> to verify that the functions being called didn't access those variables 
> (particularly since even if the functions being called didn't access any 
> member 
> variables, the functions that _they_ call could, and it could get pretty 
> nasty 
> to verify).

Right. That is why calling fun shouldn't be possible. So you say it's
not handled by dmd yet.

> Now, it could be that this particular situation is still legal, because the 
> compiler is able to see that you initialized all of the member variables 
> _before_ calling fun().

Right. That could also be the case. And my question is what is the case.
Is it the simple route that is not implemented at all or is it this more
advanced route that is already implemented?
I just checked by moving fun() to the beginning. Still works. Further
initializing a member in fun() is not allowed. But accessing a member in
fun works irrespective when it is called.
Actually I find this behavior better than the one defined in TDPL.

> If it's straightforward enough for the compiler to verify that you never call 
> any member functions prior to initializing all member variables in an 
> immutable 
> constructor (and the compiler may _have_ to be able to be that smart anyway 
> to 
> guarantee that it initializes each member variable exactly once), then I 
> don't 
> see why it shouldn't be legal to call them after all member variables have 
> been 
> initalized, but I don't know if the compiler has to be that smart, and in 
> reality, it's not actually valuable when you think about it. What could fun() 
> actually do which would be useful? You're not returning anything from either 
> it 
> or the constructor, and it's immutable, so it can't alter any state anywhere. 

You mean alter A's state. It could change something outside of A, couldn't it?

> It would only make sense for it to be legal if all member variables
> had already been initialized, but at that point, there's no point to
> calling any other functions, since they'd have to be immutable and if
> they're immutable, you can't do anything with them except return a
> result, and since you're in an immutable constructor, and all member
> variables are already initialized, you can't do anything useful with
> that result.

See above.

> So, while I don't necessarily see anything wrong with calling fun() in this 
> situation being legal, I don't see the point.

My main point is that I'd like to know what is implemented as in
mentioned TDPL and what isn't.
But I agree with you that calling an immutable member function from the
immutable constructor is probably less useful.

Jens


Re: Call to immutable method during immutable construction

2010-11-11 Thread Jens Mueller
Jonathan M Davis wrote:
> On Wednesday 10 November 2010 13:01:55 Jens Mueller wrote:
> > > So, while I don't necessarily see anything wrong with calling fun() in
> > > this situation being legal, I don't see the point.
> > 
> > My main point is that I'd like to know what is implemented as in
> > mentioned TDPL and what isn't.
> 
> I suspect that someone like Don or Walter would have to answer in this case. 
> They're the most likely to know what the compiler is actually doing vs what 
> they 
> intend it to do. A bug report on it should likely be opened though, since it 
> doesn't match TDPL. Either it needs to be fixed to match TDPL (which is 
> likely in 
> this case), or it needs to be made clear what behavior it's supposed to have, 
> at 
> which point the TDPL errata should be updated.

I added a report.
http://d.puremagic.com/issues/show_bug.cgi?id=5200
Thanks for your help.

Jens


assert(false) with -unittest

2010-11-16 Thread Jens Mueller
Hi,

assert(false) should generate the hlt instruction in release mode.
I.e.
assert.d:
void hlt() {
assert(false);
}

$ dmd -release -c assert.d
$ obj2asm assert.o | grep -w hlt

works. But

$ dmd -unittest -release -c assert.d
$ obj2asm assert.o | grep -w hlt

fails.

Can't one have hlt together with unittest? Is it a bug in the compiler
or correct behavior?

Jens


Re: assert(false) with -unittest

2010-11-16 Thread Jens Mueller
dsimcha wrote:
> == Quote from Jens Mueller (jens.k.muel...@gmx.de)'s article
> > Hi,
> > assert(false) should generate the hlt instruction in release mode.
> > I.e.
> > assert.d:
> > void hlt() {
> > assert(false);
> > }
> > $ dmd -release -c assert.d
> > $ obj2asm assert.o | grep -w hlt
> > works. But
> > $ dmd -unittest -release -c assert.d
> > $ obj2asm assert.o | grep -w hlt
> > fails.
> > Can't one have hlt together with unittest? Is it a bug in the compiler
> > or correct behavior?
> > Jens
> 
> I think this is correct.  The -unittest switch implicitly turns on asserts, 
> and as
> far as I can tell makes the -release switch ignored.  This means that
> assert(false) is no longer special and works just like a regular assert as 
> per TDPL.

I see.

> Is this a problem in practice?  If so, please explain.

Haven't thought about it. Found this by accident.

Jens


Re: modulus and array.length

2010-11-16 Thread Jens Mueller
Hi,

> I've noticed that the modulus operator acts differently when the divisor is
> the length of an array and the dividend is negative.
> For instance, this code:
> 
> import std.stdio;
> const int x = 4;
> void main(){
> int[x] arr = [0, 1, 2, 3];
> 
> writeln("Using arr.length");
> for(int i = -3; i <= 0; i++){
> writefln("%d mod %d = %d", i, arr.length, i % arr.length);
> }
> writeln("Using x");
> for(int i = -3; i <= 0; i++){
> writefln("%d mod %d = %d", i, x, i % x);
> }
> }
> 
> Produces this output:
> 
> Using arr.length
> -3 mod 4 = 1
> -2 mod 4 = 2
> -1 mod 4 = 3
> 0 mod 4 = 0
> Using x
> -3 mod 4 = -3
> -2 mod 4 = -2
> -1 mod 4 = -1
> 0 mod 4 = 0
>
>  Which is a useful (but undocumented?) feature that lets you loop through
> arrays backwards.

arr.length is type size_t.
size_t length = 4;

writeln("Using size_t");
for(int i = -3; i <= 0; i++){
writefln("%d mod %d = %d", i, length, i % length);
}

So it's due to the size_t. Because it's unsigned.

> However, when the length of the array is odd...
> const int x = 3;
> ...
> int[x] arr = [0, 1, 2];
> It looks like this:
> 
> Using arr.length
> -3 mod 3 = 1  <-- this should be 0
> -2 mod 3 = 2  <-- this should be 1
> -1 mod 3 = 0  <-- this should be 2
> 0 mod 3 = 0
> Using x
> -3 mod 3 = 0
> -2 mod 3 = -2
> -1 mod 3 = -1
> 0 mod 3 = 0
> 
> Does anyone know of a reason for this? It doesn't seem like a bug, but I
> don't know why it would do something like that.

Here I have no idea.

Jens


Debugging with gdb on Posix but setAssertHandler is deprecated

2010-11-17 Thread Jens Mueller
Hi,

I've written a small module for debugging on Posix systems.
It uses raise(SIGTRAP) and a custom errorHandlerType with
setAssertHandler. But setAssertHandler is deprecated.
Why is it deprecated? How should I do it instead?

I want to do it generally for Error and Exception. Don't know how yet.
How do you debug your programs? I've read that gdb has catch throw for
C++ to break when exceptions are thrown. I don't like changing gdb for
this.
My idea is that instead of throwing an Error/Exception I print it and
then raise SIGTRAP.

Jens


Invariants for methods

2010-11-18 Thread Jens Mueller
Hi,

I'm wondering what's a good way to do invariants for methods. In my
example I have a rectangle and one of its methods moves the upper left
of the rectangle. I have two invariants when moving a rectangle: The
width and the height do not change. I could do something like the
following:

void move(...) {
int currentWidth = width;
int currentHeight = height;
// moving the rectangle here
assert(currentWidth == width);
assert(currentHeight == height);
}

I do not like it because it won't be completely compiled away in release
mode. The problem is that in the out contract I cannot access variables
of the in contract. If that was possible it just becomes:
in {
int currentWidth = width;
int currentHeight = height;
}
out {
assert(currentWidth == width);
assert(currentHeight == height);
}
body {
// moving the rectangle here
}

Is there a solution that works right now? Are their plans to support
something like the above? Or should I do it differently?

Jens


Re: Invariants for methods

2010-11-18 Thread Jens Mueller
Jonathan M Davis wrote:
> On Thursday 18 November 2010 06:09:33 Jens Mueller wrote:
> > Hi,
> > 
> > I'm wondering what's a good way to do invariants for methods. In my
> > example I have a rectangle and one of its methods moves the upper left
> > of the rectangle. I have two invariants when moving a rectangle: The
> > width and the height do not change. I could do something like the
> > following:
> > 
> > void move(...) {
> > int currentWidth = width;
> > int currentHeight = height;
> > // moving the rectangle here
> > assert(currentWidth == width);
> > assert(currentHeight == height);
> > }
> > 
> > I do not like it because it won't be completely compiled away in release
> > mode. The problem is that in the out contract I cannot access variables
> > of the in contract. If that was possible it just becomes:
> > in {
> > int currentWidth = width;
> > int currentHeight = height;
> > }
> > out {
> > assert(currentWidth == width);
> > assert(currentHeight == height);
> > }
> > body {
> > // moving the rectangle here
> > }
> > 
> > Is there a solution that works right now? Are their plans to support
> > something like the above? Or should I do it differently?
> 
> in blocks define prefix conditions. They can test arguments to the function, 
> global variables, and members of the class/struct that the function is a 
> member 
> of (if it's a member of one).
> 
> out blocks define postfix conditions. They can test the return value of a 
> function 
> (assuming that you use out(result) instead of just out), global variables, 
> and 
> members of the class/struct that the function is a member of (if it's a 
> member 
> of one).
> 
> An invariant() block defines an invariant for a class or struct and is called 
> before and after every public member function call. It has access to the 
> class/struct and global variables (why it requires parens, I don't know).
> 
> It makes no sense to talk about an invariant for a function however. All of a 
> function's input can be tested with its in block (including global variables 
> and 
> member variables if you need to), and all of a function's output can be 
> tested 
> with its out block (including global variables and member variables if you 
> need 
> to). The only thing left would be checking the function's local variables, 
> but 
> they obviously don't exist in the in or out block, and they don't matter 
> outside 
> of the function itself. If you care about testing them as you do whatever 
> calculations that you're doing in the function, then you can use asserts 
> within 
> the function.

Does it make more sense to talk about an invariant for a member
function? I mean the member function changes the state of the instance
but there may be some invariant when changing it. Basically some change
is allowed but the other isn't.
struct Rectangle {
// state is only allowed to change in a certain way
// width and height of this Rectangle need to be preserved
public void move(...) {
}

private:
State state;
}

I'm very thankful for your feedback. At the moment I'm not sure whether
you see my point.
I think of an member function invariant as something more fine-grained
than a class invariant. Of course calling move() needs to preserve the
class invariant but actually in case of move() it should also do
something more, namely before calling and after the call the width and
height should be the same. That's an invariant for the computation of
move(). How do I express it such that it will be compiled away when
disabling contracts (i.e. in release mode)?

Jens


Re: Invariants for methods

2010-11-18 Thread Jens Mueller
Andrei Alexandrescu wrote:
> On 11/18/10 9:48 AM, Jens Mueller wrote:
> >I think of an member function invariant as something more fine-grained
> >than a class invariant. Of course calling move() needs to preserve the
> >class invariant but actually in case of move() it should also do
> >something more, namely before calling and after the call the width and
> >height should be the same. That's an invariant for the computation of
> >move(). How do I express it such that it will be compiled away when
> >disabling contracts (i.e. in release mode)?
> 
> There is a limitation of the current system in that the out contract
> can't see the scope of the in contract. Walter and I tried to find a
> solution, but it was technically difficult in the presence of
> inheritance.

Yes. I read the part about about inheritance and constructors and when I
tried my simple fix I struggled when I read about the inheritance part.
Because it does not fit in there properly.

> What I suggest you do is:
> 
> void move(...) {
> debug {
> const currentWidth = width;
> const currentHeight = height;
> scope (exit) {
> assert(currentWidth == width);
> assert(currentHeight == height);
> }
> }
> ... body ...
> }

I like it.
Thanks.
What I'd even like better (because contracts are release specific):
release {
const currentWidth = width;
const currentHeight = height;
scope (exit) {
assert(currentWidth == width);
assert(currentHeight == height);
}
}
But that does not work. Why do we have special syntax for debug but not for
release. Both seem to me very similar. In the end I tend to think
release/debug as a shorthand for version(release/debug). But that's not
quite right. Somehow it's allowed to write version(unittest) {}
equivalently for unittest {}. But for debug/release there is no such
thing. Why this asymmetry?

Jens


Re: Invariants for methods

2010-11-18 Thread Jens Mueller
bearophile wrote:
> Jens Mueller:
> 
> > I have a rectangle and one of its methods moves the upper left
> > of the rectangle. I have two invariants when moving a rectangle: The
> > width and the height do not change. I could do something like the
> > following:
> > 
> > void move(...) {
> > int currentWidth = width;
> > int currentHeight = height;
> > // moving the rectangle here
> > assert(currentWidth == width);
> > assert(currentHeight == height);
> > }
> 
> Probably you need one basic feature of DesignByContract that is missing still 
> in D2, the "old" that allows at the end of a method to know the originals. It 
> was discussed two or more times:
> 
> http://www.digitalmars.com/d/archives/digitalmars/D/why_no_old_operator_in_function_postconditions_as_in_Eiffel_54654.html
> 
> http://www.digitalmars.com/d/archives/digitalmars/D/Communicating_between_in_and_out_contracts_98252.html
> 
> Once the feature is implemented you may solve your problem like this (minus 
> syntax changes, but other solutions are possible):

Oh. I should have done better research.
I don't like the "old" approach.

> void move(...)
> in {
> // ...
> } out {
> assert(width == old.width);
> assert(height == old.height);
> } body {
> // moving the rectangle here
> }
> 
> 
> The problem of implementing the old was solved in C#4, it is named 
> PrestateValues(OldValue), see page 8 here:
> http://research.microsoft.com/en-us/projects/contracts/userdoc.pdf
> So probably this problem may be solved in D2 too.
> 
> To solve this problem currently you may need to use ghost fields in your 
> struct/class that memorize the older values... ghost fields wrapped in 
> version(unittest) {...} or some version(debug). This is a bad solution.

Don't get your point here. You neither like the ghost fields (old) nor
the debug {} approach as Andrei suggested? I mean after all the problem
is not that important that one should bother too much. Maybe I'm too
pragmatic. I'll try using it and see how it feels.

Jens


Re: Invariants for methods

2010-11-18 Thread Jens Mueller
Andrei Alexandrescu wrote:
> On 11/18/10 12:08 PM, Jens Mueller wrote:
> >What I'd even like better (because contracts are release specific):
> >release {
> > const currentWidth = width;
> > const currentHeight = height;
> > scope (exit) {
> > assert(currentWidth == width);
> > assert(currentHeight == height);
> > }
> >}
> >But that does not work. Why do we have special syntax for debug but not for
> >release. Both seem to me very similar. In the end I tend to think
> >release/debug as a shorthand for version(release/debug). But that's not
> >quite right. Somehow it's allowed to write version(unittest) {}
> >equivalently for unittest {}. But for debug/release there is no such
> >thing. Why this asymmetry?
> >
> >Jens
> 
> I think it's just for pragmatic reasons (avoid allocating a keyword
> for something you can do a different way). Also, it's more often
> that you want to insert extra code in debug builds. It's odd that
> you don't want the checks in debug mode, for example.

Sorry. I shouldn't have said release {}. That was wrong.
Basically I want the check to behave the same as a normal contract does.
So actually I want
non-release { // goes only away in release mode
...
}
I mean if I compile with -release all contracts should go away. With
debug { } I'm now mixing things. Because my contract will only be
checked if compiled with -debug.

Jens


Re: Invariants for methods

2010-11-18 Thread Jens Mueller
Jonathan M Davis wrote:
> On Thursday 18 November 2010 12:08:19 Jens Mueller wrote:
> > 
> > I like it.
> > Thanks.
> > What I'd even like better (because contracts are release specific):
> > release {
> > const currentWidth = width;
> > const currentHeight = height;
> > scope (exit) {
> > assert(currentWidth == width);
> > assert(currentHeight == height);
> > }
> > }
> > But that does not work. Why do we have special syntax for debug but not for
> > release. Both seem to me very similar. In the end I tend to think
> > release/debug as a shorthand for version(release/debug). But that's not
> > quite right. Somehow it's allowed to write version(unittest) {}
> > equivalently for unittest {}. But for debug/release there is no such
> > thing. Why this asymmetry?
> 
> One thing that you need to realize is that the -release and -debug flags are 
> _completely_ unrelated. You can use none, or one, or even both.
> 
> -release disables assertions (other than assert(0)) - including removing all 
> pre-conditions, post-condition, and invariants - and removes array bounds 
> checking for @system and @trusted functions.
> 
> -debug enables all debug blocks.
> 
> So, you can have
> 
> * Neither flag: All assertions, contracts, and array bounds checking are 
> enabled, 
> and debug blocks are not compiled in.
> 
> * -release only: All assertions, contracts, and array bounds checking for 
> @system and @trusted functions are removed. debug blocks are not compiled in.
> 
> * -debug only: All assertions, contracts, and array bounds checking are 
> enabled, 
> and debug blocks are compiled in.
> 
> * Both flags: All assertions, contracts, and array bounds checking in @system 
> and 
> @trusted functions are removed. debug blocks are compiled in.

I think unittest should be added to this list. Because it can cause more
confusion.

> So, the flags in question are quite confusing really, and talking about debug 
> mode doesn't actually make sense when you think about it. You have release 
> mode 
> and non-release mode. And you either have debug blocks enabled or you don't. 
> And 
> on top of that, you have whether debug symbols are enabled or not (even 
> worse, 
> there are two different flags for enabling debug symobls: -g and -gc). So, 
> the 
> flags as they are make the whole release vs debug build thing really 
> confusing, 
> and they're probably not terms that really should be used unless you're 
> talking 
> about your specific build process and the specific set of flags that you use 
> for 
> building for release builds and the specific set of flags that you use for 
> debug 
> builds. But talking about release and debug builds is so ingrained in people, 
> that they keep using the terms anyway, and most people probably don't quite 
> understand the imprecision of the terms with regards to dmd.

I totally agree with you and I think one should fix dmd's help message.
I would love to see
-release   same as -nocontracts -noasserts -noboundscheck
-debugging same as -debug -unittest -contracts -asserts -boundscheck
-testing   same as -unittest -contracts, -asserts, -boundscheck

These switches basically configure your software (which code to
compile). And above you find the typical configurations for release,
testing and debugging. One could leave out the defaults.

Having orthogonal command line switches:
-(no)boundscheckcompile in array bound checks
-(no)contracts  compile in contracts
-(no)debug  compile in debug
-(no)unittest   compile in unittest
-(no)assert -noassert causes assert()
to be translated to hlt
with some sensible default (but only disabling the default might be
implemented) e.g.
-nounittest
This we have already. Because we -unittest.
-nodebug
This we have as well via -debug.
-boundscheck
This too (-noboundscheck).
-contracts
Missing: -nocontracts
-assert
Missing: -noasserts

But I think this can lead to something like -unittest -noassert which is
rather strange. Don't know. Would still go for it.

And now as you say one can specify -g for debug symbols or -O for
optimization.
In summary there are two things to consider:
1. What code will be included? (debug, unittest, contracts, assertions,
   boundschecking, and version=xxx)
2. How will the code be generated? (with debug symbols -g, -gc;
   optimized -0)

Typical release code is built via -release -O I'll guess. It's true
-release does not do a release build as one expects. Same for
-debugging. Because -g is missing. Better names would help here. But
it's difficult to change that now, isn't it? That's why better dmd
--help output should be sufficient.

Jens


Re: Invariants for methods

2010-11-18 Thread Jens Mueller
bearophile wrote:
> Jens Mueller:
> 
> > I don't like the "old" approach.
> 
> Why?
> (It's the canonical way to solve the problem you have had. It is present in 
> Eiffel and C# and probably something similar is present in the DbC for Java. 
> But surely other solutions are possible.)

Somehow it doesn't feel right to me. It should just copy what is needed.
Let's say I have some very big object. Now old is a copy before the
execution of my member function. But I only check some little detail but
I end of with having this big copy. I think the programmer knows what
she's doing and she should have control about it. This copying behind the
scenes seems surprising to me. Maybe I do not fully understand the
approach.

> > Don't get your point here. You neither like the ghost fields (old) nor
> > the debug {} approach as Andrei suggested?
> 
> I have written that answer of mine before reading Andrei answer.

I see.

> > I mean after all the problem
> > is not that important that one should bother too much.
> 
> The problem is important enough. In DbC it's very useful to have a 
> safe¬bugprone way to test if a method has changed the precedent state 
> correctly.

I've seen the Java's Request for Enhancements you mentioned. DbC is
number one. You're right one should do this properly but it seems to me
that right now there are more important problems. I mean I do not know
when people started complaining about Java missing proper DbC but I'll
guess it was a lot later. If it starts itching then scratch it. I hope
there is no inherent design problem. I think this problem does not
prevent D's success. I might be wrong here but nobody is not switching
to D because this does not work. It's more the bugs/API changes/tools
that keep people away. At least that's my impression. It does not seem
mature enough for some people.

Jens


Re: Invariants for methods

2010-11-18 Thread Jens Mueller
Andrei Alexandrescu wrote:
> On 11/18/10 1:57 PM, Jens Mueller wrote:
> >bearophile wrote:
> >>Jens Mueller:
> >>
> >>>I don't like the "old" approach.
> >>
> >>Why?
> >>(It's the canonical way to solve the problem you have had. It is present in 
> >>Eiffel and C# and probably something similar is present in the DbC for 
> >>Java. But surely other solutions are possible.)
> >
> >Somehow it doesn't feel right to me. It should just copy what is needed.
> >Let's say I have some very big object. Now old is a copy before the
> >execution of my member function. But I only check some little detail but
> >I end of with having this big copy. I think the programmer knows what
> >she's doing and she should have control about it. This copying behind the
> >scenes seems surprising to me. Maybe I do not fully understand the
> >approach.
> 
> The technique could be achieved by making "old" a keyword and
> copying only the fields accessed via "old". This approach was on the
> table. It has enough vagaries for me to dislike it.
> 
> One approach that I very much prefer is that the "out" contract sees
> the scope of the "in" contract. That way, the user can define state
> in the "in" contract and then check it in the "out" contract. The
> approach is more general and easier to understand than the one based
> on the "old" object.

I see. bearophile even has a bug for this problem
(http://d.puremagic.com/issues/show_bug.cgi?id=5027). Somehow that does
not surprise me. But I like it.

Even though there seems to be some disagreement on a proper solution
(right?) I think for the moment it's enough to have this bug report. In
particular I'm not sure whether bearophile agrees with having the out
contract seeing the in contract's scope. But if that's a valid solution
maybe he can add it to his bug report.

Jens


Re: Debugging with gdb on Posix but setAssertHandler is deprecated

2010-11-21 Thread Jens Mueller
Sean Kelly wrote:
> Jens Mueller  wrote:
> > Hi,
> > 
> > I've written a small module for debugging on Posix systems.
> > It uses raise(SIGTRAP) and a custom errorHandlerType with
> > setAssertHandler. But setAssertHandler is deprecated.
> > Why is it deprecated? How should I do it instead?
> > 
> > I want to do it generally for Error and Exception. Don't know how yet.
> > How do you debug your programs? I've read that gdb has catch throw for
> > C++ to break when exceptions are thrown. I don't like changing gdb for
> > this.
> > My idea is that instead of throwing an Error/Exception I print it and
> > then raise SIGTRAP.
> 
> It's deprecated because DMD doesn't generate a valid call stack when
> generating an assert, so if you try to return from the assert handler
> instead of throwing the app will crash.

Thanks.
That explains my segmentation fault. Is there going to be an alternative
way of doing it? Shouldn't one fix the problem in dmd instead of
deprecating the handler? In the meantime I will try using gdb reverse
debugging.

Jens


const a storage class or a type modifier?

2010-11-25 Thread Jens Mueller
Hi,

I'm converting a .h to a d module. I'm following the guide on
http://www.digitalmars.com/d/2.0/htomodule.html
It says
"D has const as a storage class, not a type modifier. Hence, just drop
any const used as a type modifier"

I do not understand the first sentence nor do I find dropping the const
right. Why should I drop a const?
In TDPL const/immutable are type qualifiers. Type qualifier is a
synonym for type modifier, isn't it? And I know storage classes like
static/ref. In C you have the type qualifiers const, volatile, and
restrict and the storage classes auto, register, static, extern. Now
const in D is a storage class?

Jens


Re: const a storage class or a type modifier?

2010-11-26 Thread Jens Mueller
Walter Bright wrote:
> Jens Mueller wrote:
> >I'm converting a .h to a d module. I'm following the guide on
> >http://www.digitalmars.com/d/2.0/htomodule.html
> >It says
> >"D has const as a storage class, not a type modifier. Hence, just drop
> >any const used as a type modifier"
> >
> >I do not understand the first sentence nor do I find dropping the const
> >right. Why should I drop a const?
> >In TDPL const/immutable are type qualifiers. Type qualifier is a
> >synonym for type modifier, isn't it? And I know storage classes like
> >static/ref. In C you have the type qualifiers const, volatile, and
> >restrict and the storage classes auto, register, static, extern. Now
> >const in D is a storage class?
> 
> const in D1 is a storage class, in D2 it's a type modifier. The web
> page needs updating.

I'm attaching an svn diff. Can you apply it? Since one doesn't need to
care about const then maybe one should drop the complete section. What
do you think?
I find this converting tutorial quite useful. Is there anything else
missing or wrong? I'd like to adjust it because it helps people to add C
libraries to D.

Jens
Index: docsrc/htomodule.dd
===
--- docsrc/htomodule.dd	(revision 2200)
+++ docsrc/htomodule.dd	(working copy)
@@ -246,8 +246,8 @@
 
 Const Type Modifiers
 
-	D has $(TT const) as a storage class, not a type modifier. Hence, just
-	drop any $(TT const) used as a type modifier:
+	D has $(TT const) as a type modifier like C. Hence, the $(TT
+	const) type modifier should be preserved.
 
 $(CCODE
 void foo(const int *p, char *const q);
@@ -256,7 +256,7 @@
 	becomes:
 
 ---
-void foo(int* p, char* q);
+void foo(const int* p, char *const q);
 ---
 
 Extern Global C Variables


Re: const a storage class or a type modifier?

2010-11-26 Thread Jens Mueller
Trass3r wrote:
> >In TDPL const/immutable are type qualifiers. Type qualifier is a
> >synonym for type modifier, isn't it? And I know storage classes like
> >static/ref. In C you have the type qualifiers const, volatile, and
> >restrict and the storage classes auto, register, static, extern. Now
> >const in D is a storage class?
> 
> I also think const char* x in D2 is equal to const(char*) x while a
> direct translation would be const(char)* x
> So you might use the former version to keep compatibility with D1.

Haven't thought about that.
Right. In D2 const T* is equal to const(T*).

Let's check all the possible cases:
void foo(const int *non_const_ptr_to_const,
 char *const const_ptr_to_non_const,
 const float *const const_ptr_to_const);

In D2 you cannot express char *const. That's due to the transitivity of
const. You can only do a const char* which is a constant pointer to
constant.
That's why I think foo should become in D2
void foo(const int*, char *, const(float*));

What do you think?
I do not know much about D1. Is const transitive in D1?

I think the page http://www.digitalmars.com/d/2.0/const3.html should not
talk about storage class in regard to const and immutable.

Jens


Re: const a storage class or a type modifier?

2010-11-26 Thread Jens Mueller
Trass3r wrote:
> >Let's check all the possible cases:
> >void foo(const int *non_const_ptr_to_const,
> > char *const const_ptr_to_non_const,
> > const float *const const_ptr_to_const);
> >
> >In D2 you cannot express char *const. That's due to the transitivity of
> >const. You can only do a const char* which is a constant pointer to
> >constant.
> >That's why I think foo should become in D2
> >void foo(const int*, char *, const(float*));
> 
> Don't you mean foo(const(int)*, char*, const float*)?

Right. Found this out myself a minute ago.
Thanks.
And as you say const float* is equivalent to const(float*). You're
right const float* is better than const(float*).

Jens


Re: const a storage class or a type modifier?

2010-11-26 Thread Jens Mueller
Michel Fortin wrote:
> On 2010-11-26 07:51:20 -0500, Jens Mueller  said:
> 
> >Trass3r wrote:
> >>>In TDPL const/immutable are type qualifiers. Type qualifier is a
> >>>synonym for type modifier, isn't it? And I know storage classes like
> >>>static/ref. In C you have the type qualifiers const, volatile, and
> >>>restrict and the storage classes auto, register, static, extern. Now
> >>>const in D is a storage class?
> >>
> >>I also think const char* x in D2 is equal to const(char*) x while a
> >>direct translation would be const(char)* x
> >>So you might use the former version to keep compatibility with D1.
> >
> >Haven't thought about that.
> >Right. In D2 const T* is equal to const(T*).
> >
> >Let's check all the possible cases:
> >void foo(const int *non_const_ptr_to_const,
> > char *const const_ptr_to_non_const,
> > const float *const const_ptr_to_const);
> >
> >In D2 you cannot express char *const. That's due to the transitivity of
> >const. You can only do a const char* which is a constant pointer to
> >constant.
> >That's why I think foo should become in D2
> >void foo(const int*, char *, const(float*));
> >
> >What do you think?
> 
> const(float*) or const(float)* are pretty much equivalent as a
> function parameter type. That's because the pointer is being passed
> to the function by copy. So whether it is const or not only matter
> when you are writing the function's body (can't mutate the local
> variable). It doesn't change anything for the caller.

That's true.
So how do you like it to be?
void foo(const(int)*, char *, const(float)*);
or
void foo(const int*, char *, const float*);

I still like the fixed original one namely
void foo(const(int)*, char *, const float*);

Because it's the most explicit one and one should know the difference.
Even though one is not implementing the function. But the signature
tells you something. If you do const float* it tells you that the
implementation isn't changing its copied pointer. If you do
const(float)* then it may change its copied value of the pointer.
But I agree it's rather artificial because it's a copy anyway. But I
like it to be explicit. In general I prefer the const() notation more
than the one without round brackets when dealing with types.

Jens


Re: const a storage class or a type modifier?

2010-11-26 Thread Jens Mueller
Michel Fortin wrote:
> On 2010-11-26 09:12:53 -0500, Jens Mueller  said:
> 
> >So how do you like it to be?
> >void foo(const(int)*, char *, const(float)*);
> >or
> >void foo(const int*, char *, const float*);
> >
> >I still like the fixed original one namely
> >void foo(const(int)*, char *, const float*);
> 
> I don't really have a preference. Note that for function arguments,
> you can also use 'in' to mean const:
> 
>   void foo(in int*, char *, in float*);
> 
> My opinion is that we have too much choice. When everyone can write
> the same thing differently it can easily become confusing.

Right. Definitely too much choice. So it becomes a matter of style and I
think the documentation should be in one consistent style. For
interfacing with C I prefer the const version over in. Because I
consider in and out to be like one pair of shoes. And since out doesn't
make sense when interfacing with C I don't like it.
But for non interfacing code one should use in/out because they are more
explicit than const.

Jens


Re: const a storage class or a type modifier?

2010-11-27 Thread Jens Mueller
Trass3r wrote:
> >I don't really have a preference. Note that for function
> >arguments, you can also use 'in' to mean const:
> >
> > void foo(in int*, char *, in float*);
> 
> Isn't "in" the default (even if nothing is specified)?

I don't know. I never read this. I don't think that's the case.
For example
void foo(in int a) {
//a = 1; // won't compile
}
Whereas
void foo(int a) {
a = 1; // this compiles
}
compiles.
So in is definitely not the default.

Jens


Re: const a storage class or a type modifier?

2010-11-28 Thread Jens Mueller
Don wrote:
> Jens Mueller wrote:
> >Walter Bright wrote:
> >>const in D1 is a storage class, in D2 it's a type modifier. The web
> >>page needs updating.
> >
> >I'm attaching an svn diff. Can you apply it? Since one doesn't need to
> >care about const then maybe one should drop the complete section. What
> >do you think?
> >I find this converting tutorial quite useful. Is there anything else
> >missing or wrong? I'd like to adjust it because it helps people to add C
> >libraries to D.
> >
> >Jens
> 
> I removed the section entirely for D2. It remains unaltered for D1.
> http://www.dsource.org/projects/phobos/changeset/2201

Removing it leaves some questions open. At least the current thread
revealed some problems. What about the attached update?

Jens
Index: docsrc/htomodule.dd
===
--- docsrc/htomodule.dd	(revision 2200)
+++ docsrc/htomodule.dd	(working copy)
@@ -246,17 +246,18 @@
 
 Const Type Modifiers
 
-	D has $(TT const) as a storage class, not a type modifier. Hence, just
-	drop any $(TT const) used as a type modifier:
+	D has $(TT const) as a type modifier almost like C. Additionally (to C's
+	$(TT const)) $(TT const) in D is transitive (see $(LINK2 const3.html,
+	Const and Immutable)). Hence,
 
 $(CCODE
-void foo(const int *p, char *const q);
+void foo(const int *p, char *const q, const float *const r);
 )
 
 	becomes:
 
 ---
-void foo(int* p, char* q);
+void foo(const(int)* p, char* q, const float* r);
 ---
 
 Extern Global C Variables


Re: Please vote on std.datetime

2010-12-10 Thread Jens Mueller
Andrei Alexandrescu wrote:
> Jonathan M. Davis has diligently worked on his std.datetime
> proposal, and it has been through a few review cycles in this
> newsgroup.
> 
> It's time to vote. Please vote for or against inclusion of datetime
> into Phobos, along with your reasons.

I cannot say anything regarding the datetime module but I'd like to say
something about the unittest module. First it is really great having
these asserts with improved output.
I do not understand why one needs assertOpCmp!"=="(). According to TDPL
there should be <, <=, >=, and >. == will be rewritten using opEquals.
So I think <= and >= are missing and I do not know why there is
assertOpCmp!"==".
Further I'll find the following implementation of assertOpCmp better.

immutable result = mixin("lhs" ~ op ~ "rhs");
if(!result)
{   
if(msg.empty)
throw new AssertError(format("[%s] %s [%s] failed", lhs, op, 
rhs), file, line);
else
throw new AssertError(format("[%s] %s [%s] failed: %s", %lhs, 
op, rhs, msg), %file, line);
}

It is shorter and gives the similar diagnostics than the current
version. But I haven't tested the code above.
The actual version is hard coded to lhs.opCmp(rhs). Better leave the
decision lhs.opCmp(rhs) vs rhs.opCmp(lhs) to the compiler.

Not sure about the following but maybe having something spelled out like
this assertLessThan, assertLessEqual, etc. is also nice.

For assertEqual I'd like it to mirror opEqual similar to as I did it
above for opCmp. So have something like assertOpEquals() and then maybe
also the name assertEquals as a synonym. I have to admit I do not know
how to integrate !=.

Why the binary predicate?
With the current version I can write something like
assertEqual!"a != b"(1, 2)
which I find strange. Why not only do the check for equality.
I.e.
if(!(mixin("actual" ~ op ~ "expected"))
{
if(msg.empty)
throw new AssertError(format("assertEquals() failed: actual 
[%s], expected [%s].", actual, expected), file, line);
else
throw new AssertError(format("assertEquals() failed: actual 
[%s], expected [%s]: %s", actual, expected, msg), file, line);
}

What's the benefit of the binary predicate? Clearly it makes it more
flexible but I dislike allowing something like assertEqual!"a != b"(1,
2).

In summary: I really like the unittest module. It's a great step forward
for writing test. The assertions feel much like in google-test. A great
module. I hope that I managed to explain my minor annoyance. I'll do my
very best. Jonathan, thanks for this great module. +1 for std.unittest.

Jens


Re: std.unittests for (final?) review

2011-01-03 Thread Jens Mueller
bearophile wrote:
> Jonathan M Davis:
> 
> > While improvements can be 
> > made to how unit tests work in D, I believe that that should be addressed 
> > by 
> > actually making those improvements to the core language as opposed to using 
> > a 
> > module in Phobos to change things. You shouldn't _need_ std.unittests to 
> > write 
> > unit testing code.
> 
> I think it's wrong to design a built-in unit test system able to do most of 
> the things a real unit test system is expected to work, because it's a lot of 
> stuff and because 10-15 years from now the best design for an unit test 
> system may be different, and there are different ways to create tests. So I 
> prefer the built-in unit test features to allow the creation of a good 
> standard library unit test system based on the built-in one, working as an 
> extension. In little programs you are free to use the built-in one.

I agree with bearophile. Unit testing can be implemented on top of the
language and shouldn't be put into it. Somehow I have the feeling that
too often one tries to extend the language even though the feature could
be implemented in a library. I like the basic built-in support for
unit testing in D but more advanced testing should be implemented in a
module ideally leading to something like GoogleTest for D. I think
unittest.d does a good step into that direction. More will be needed, if
there is consensus.

Jens


Re: std.unittests for (final?) review

2011-01-03 Thread Jens Mueller
Jonathan M Davis wrote:
> On Monday 03 January 2011 01:38:29 Vladimir Panteleev wrote:
> > On Mon, 03 Jan 2011 06:44:50 +0200, Jonathan M Davis 
> > 
> > wrote:
> > > So, please have a look at the code.
> > 
> > Just one thing: wouldn't these functions also be useful in contract
> > programming (invariants etc.)? Perhaps they should just be added to
> > std.exception?
> 
> Well, they're written with unit tests in mind rather than contracts. Unit 
> tests 
> and contracts have similar but different purposes. I wouldn't really want to 
> conflate the two. Also, it's std.exception now rather than std.contracts 
> specifically because it doesn't really relate to contracts, so even if you 
> did 
> want to use unit testing functions in contracts, I'm not sure that 
> std.exception 
> is the right place to put such functions anyway.
> 
> As it stands, the entire module is in a version(unittest) block, so the 
> functions can't be used outside of unit tests.
> 
> If a lot of people really thought that unit testing functions would be useful 
> and reasonable to use inside of contracts, then it would make some sense for 
> the 
> unit testing functions to no longer be in a version(unittest) block. But 
> personally, I'd be a bit worried to see more than simple assertions inside of 
> contracts. Contracts should be efficient, since they're going to be run while 
> the 
> code is running normally, whereas unit tests don't have to worry about 
> efficiency 
> quite as much. I believe that the functions that I have are efficient, but I 
> can 
> easily see functions intended to aid in unit testing being totally 
> inappropriate 
> in a contract due to efficiency concerns. And of course, a number of the unit 
> testing functions just don't make sense in contracts regardless - like 
> assertExThrown.

What do you mean by "running normally"? I think since they are compiled
away with -release they are not run normally.

> Howevr, regardless of whether the functions are deemed reasonable for use in 
> contracts, I do think that having a module of functions designed specifically 
> for 
> use in unit tests is of definite value, and regardless of the current size of 
> the 
> module, it's quite possible that it could become fairly large at some point 
> if 
> enough useful unit testing functions are devised. Merging that in with 
> std.exception seems ill-advised to me. Not to mention, it's a lot more 
> obvious 
> that you're dealing with functions intended to aid in unit tests when the 
> module 
> is named std.unittests than if those functions are lumped in with the stuff 
> in 
> std.exception.

I think you're right. It definitely should stay in it's own module. I do
it as follows:
Build with -release -noboundscheck and no -unittest to get the
production version. I.e. all contracts, asserts, boundschecks, and
unittests go away.
Further I have a build with -unittest which is for testing. Now I can
use Jonathan's assertions with better error messages even in contracts.

Jens


Re: std.unittests for (final?) review

2011-01-03 Thread Jens Mueller
bearophile wrote:
> Jens Mueller:
> 
> > I agree with bearophile. Unit testing can be implemented on top of the
> > language and shouldn't be put into it.
> 
> This is not what I have said. I was talking about option IV I have explained 
> here:
> http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=107997
> 
> This means I accept the built-in unit test system, but I think it's wrong to 
> make it do everything you want from an unit test system. So the built-in one 
> has to give the basic features (like giving a name to each unit test) that 
> are later used by the library-defined unit test system.

I mean the same.
"I like the basic built-in support for unit testing in D but more
advanced testing should be implemented in a module ideally leading to
something like GoogleTest for D."

Advanced features should be implemented on top of the built-in one.
Specifically they should not be put into the core language.
Sorry for my bad wording.

Jens


Re: std.unittests for (final?) review

2011-01-03 Thread Jens Mueller
bearophile wrote:
> Jens Mueller:
> 
> > I agree with bearophile. Unit testing can be implemented on top of the
> > language and shouldn't be put into it.
> 
> This is not what I have said. I was talking about option IV I have explained 
> here:
> http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=107997

Not sure but is this compatible with your option IV:
Built advanced unit testing capabilities on top of the existing ones in
a module.

You want to add hooks. If you just need them because right now some
things cannot be implemented (e.g. because a unit test has no name) then
we perfectly agree. There might be things in the current built-in unit
testing that prevent implementing some advanced feature on top of them.
That needs to be done.

Jens


Re: std.unittests for (final?) review

2011-01-03 Thread Jens Mueller
> On Monday 03 January 2011 02:39:59 Jens Mueller wrote:
> > Jonathan M Davis wrote:
> > 
> > What do you mean by "running normally"? I think since they are compiled
> > away with -release they are not run normally.
> 
> I mean when the program is running. If you're running a debug version of your 
> program (which is perfectly normal and common), the contracts are going to 
> run. 
> They're _supposed_ to run while the program is running. That's the point. 
> Naturally, you compile them out for release, but contracts need to be written 
> in 
> way that the program works just fine with them compiled in.

I see. You're right. If one uses unittest.d in contracts than they won't
work in all builds, namely the build with no -release and no -unittest.

Jens


Re: std.unittests for (final?) review

2011-01-03 Thread Jens Mueller
> >>In fact (without looking at std.unittest) I think it should be grouped
> >>with a simple benchmark facility. That's what the homonym frameworks in
> >>Google's and Facebook's code base do.
> >
> >I'm afraid that I don't see what unit test helper functions have to do with
> >benchmarking.
> 
> They both help the decision: "Is this module good to go?" At work we
> almost always put benchmarks in the same file as the unit tests, and
> run them together (subject to a --benchmark flag because benchmarks
> tend to take a fair amount of time). I find that very natural,
> although I should add that the unittest and benchmark libraries are
> nominally distinct.

How do you do it? I had similar thoughts. When I do testing I also want
to add some performance tests. In D I thought about having
version(performance) (maybe better version(benchmark)) inside a unittest
{} to assess performance. This way compiling with -unittest
-version=performance will execute the benchmarking code.

> >And I don't believe that we have a benchmarking module at the
> >moment regardless, so if you want to do that, we'd need to create one. The 
> >only
> >benchmarking stuff that I'm aware of is the bencharking stuff in 
> >std.datetime that
> >SHOO did, which isn't all that much code. I would have thought that unit test
> >helper functions would merit their own module, particularly when I don't see
> >what they have to do with benchmarks.
> 
> Adding basic support for benchmarking shouldn't be difficult and
> does not entail a lot of code, but I understand it if you're not all
> that motivated to work on that.

What do you think is needed for basic support? I found std.perf and used
it but I think it's deprecated. But std.datetime will do it as well (I
haven't looked at it though).

Jens


Re: std.unittests for (final?) review

2011-01-03 Thread Jens Mueller
Walter Bright wrote:
> Jens Mueller wrote:
> >Unit testing can be implemented on top of the
> >language and shouldn't be put into it. Somehow I have the feeling that
> >too often one tries to extend the language even though the feature could
> >be implemented in a library.
> 
> On the other hand, the built-in D unit test ability has been a huge success.
> 
> A unit test facility that is not used is worthless, no matter how
> capable it is. The advantage of it being simple and built-in is it
> gets used, and I think there's strong evidence that this is true for
> D.

Yes. I do not disagree. I like having unittest in the language.
Extending the basic built-in unit testing support should not be done
inside the language, if it can be done conveniently as a library.
And the built-in unit testing is very helpful and necessary. But it
should be possible to build extended testing frameworks (as there are in
Java, C++, etc.) on top of these.

Sorry. My very first sentence was very misleading. I wanted to say that
further/advanced unit testing shouldn't be put into the language. We all
agree on that, don't we?
Maybe we can get a discussion what features are considered useful in a
testing framework library and what needs to be changed in the built-in
testing to make such a library happen.

Jens


Re: std.unittests for (final?) review

2011-01-05 Thread Jens Mueller
Nick Sabalausky wrote:
> "Jonathan M Davis"  wrote in message 
> news:mailman.405.1294111260.4748.digitalmar...@puremagic.com...
> > Well, it's not possible to overload assert, so that sort of thing really 
> > doesn't
> > work. You're kind of stuck with something JUnit-ish in terms of names, 
> > though
> > assertCmp and assertOpCmp both take a string for the operator, so you 
> > don't have
> > assertLessThan, assertGreaterThan, etc. And what's there uses lazy instead 
> > of
> > string mixins, because it's cleaner that way. lazy does the job just fine.
> >
> > And even if you could overload assert, you'd likely run into the same sort 
> > of
> > problems that come up when you try and overload constructors and the like 
> > and
> > the parameters aren't different enough to allow you to do all of the 
> > overloads
> > that you want to do. At least JUnit-like naming is clear, and you're only 
> > going
> > to use it unit tests, so it's fairly confined. So, if it bothers you, at 
> > least it
> > doesn't affect your actual program code.
> >
> 
> The actual name "assert" isn't really what I was getting at. I realize 
> that's not usable, and that's fine. What I meant was, for instance, your 
> documentatin includes the example:
> 
> assertOpBinary!"+"(Foo(5), 7, Foo(12));
> 
> (Although it doesn't seem to compile for me...) That's quite a mess compared 
> to the following:
> 
> assert(Foo(5) + 7 == Foo(12));

I had the same impression. But I think it should be there for
consistency reasons. Because there is also assertOpOpAssign.
But you're right in case of assertOpBinary I prefer writing
assertEqual(Foo(5) + 7, Foo(12));
Becaues it's one line and it gives enough information for me.
But this does not hold for assertOpOpAssign anymore.

> That can currently be done, of course, but it's output on failure obviously 
> doesn't give as much useful information as assertOpBinary.
> 
> I think a middle ground is needed. For instance, with the assert utils in my 
> SemiTwist D Tools library, you can do this:
> 
> mixin(deferEnsure!(`Foo(12)`, `_ == Foo(5) + 7`));
> 
> And the output upon failure still gives you this information:
> 
> Expression 'Foo(12)':
> Expected: _ == Foo(5) + 7
> Actual: 999
> 
> And, though I haven't done so yet, that can be generalized to allow it to 
> display what Foo(5) evaluated to. Admittedly, there's lots of room for 
> improvement in my syntax there, but the point is that you write an actual 
> expression and still get all the same useful information.
> 
> So, just as one off-the-top-of-my-head idea, your lib could have something 
> like:
> 
> assertExpression(`#Foo(5)# + 7 == #Foo(12)#`);
> 
> The # delimiters (or whatever system of delimiters would make sense) 
> indicate what sub-expression should be displayed, ex:
> 
> Assert failed: [Foo(5) + 7 == Foo(12)]
> Foo(5): 6
> Foo(12): 12
> 
> Or:
> 
> assertExpression(q(a + 7 == b}, Foo(5), Foo(12));
> // (same output as before)
> 
> The whole things may or may not need to be wrapped in a "mixin()", I don't 
> know.
> 
> Ie, something like that.

Sounds useful and could be added later.

Jens


Re: std.unittests for (final?) review

2011-01-05 Thread Jens Mueller
Lars T. Kyllingstad wrote:
> Sorry for not commenting on earlier iterations of this module.  For the 
> most part, I think it looks pretty good, and I also think it will be 
> useful.  Often, I find myself writing stuff like
> 
>   assert (someVar == someVal,
> text("Wrong value for someVar: ", someVar));
> 
> and assertEqual() will be nice to have for those cases. :)  I just have 
> some minor comments.
> 
> 1. I think assertExThrown() and assertExNotThrown() should be named 
> assertThrown() and assertNotThrown(), because they can intercept any 
> subclass of Throwable, not just Exception, and because you rarely throw 
> anything else, so it seems redundant.

I think this is a good renaming. assertThrown and assertNotThrown are
better names.

> 2. I think the name getMsg() is too non-specific.  I'd prefer if it was 
> renamed to throwableMsg(), thrownMsg(), or something similar.  The 
> function should also be moved upwards a bit so its documentation follows 
> that of the assert*Thrown() functions.  Then, the various functions will 
> be nicely grouped in the documentation -- all the exception handling 
> tests come first, followed by the value tests.

Right. getMsg() is a too general name. Of the given ones I like
thrownMsg() best because it's concise.

Jens


Re: Learning D

2011-01-14 Thread Jens Mueller
Get "The D Programming Language"
http://www.amazon.com/D-Programming-Language-Andrei-Alexandrescu/dp/0321635361/ref=sr_1_1?ie=UTF8&s=books&qid=1295033396&sr=8-1

Jens

Adrian Mercieca wrote:
> Hi folks,
> 
> What's the best way to learn D please?
> 
> Thanks.


filter!(not!(predicate))(someInputRange) does not compile

2011-01-19 Thread Jens Mueller
Hi,

I cannot make the following compile.

import std.functional;
import std.array;
import std.algorithm;
import std.stdio;

void main() {
auto numbers = [0, 1, 2, 3, 4, 5];

bool alwaysTrue(uint a) { return true; }
alias not!(alwaysTrue) alwaysFalse;

numbers = array(filter!(alwaysTrue)(numbers));
writeln(numbers);
numbers = array(filter!(alwaysFalse)(numbers)); // does not compile
writeln(numbers);
}

The line with alwaysFalse fails with:
/path/to/../src/phobos/std/algorithm.d(854): Error: constructor
std.algorithm.Filter!(not,int[]).Filter.this cannot get frame pointer to
not

Any ideas what I'm doing wrong or workarounds?

Jens


Re: filter!(not!(predicate))(someInputRange) does not compile

2011-01-19 Thread Jens Mueller
Andrei Alexandrescu wrote:
> On 1/19/11 5:53 PM, Jens Mueller wrote:
> >Hi,
> >
> >I cannot make the following compile.
> >
> >import std.functional;
> >import std.array;
> >import std.algorithm;
> >import std.stdio;
> >
> >void main() {
> > auto numbers = [0, 1, 2, 3, 4, 5];
> >
> > bool alwaysTrue(uint a) { return true; }
> > alias not!(alwaysTrue) alwaysFalse;
> >
> > numbers = array(filter!(alwaysTrue)(numbers));
> > writeln(numbers);
> > numbers = array(filter!(alwaysFalse)(numbers)); // does not compile
> > writeln(numbers);
> >}
> >
> >The line with alwaysFalse fails with:
> >/path/to/../src/phobos/std/algorithm.d(854): Error: constructor
> >std.algorithm.Filter!(not,int[]).Filter.this cannot get frame pointer to
> >not
> >
> >Any ideas what I'm doing wrong or workarounds?
> >
> >Jens
> 
> Place the call to not!alwaysTrue in a local function inside main:
> 
> bool alwaysFalse(uint a) { return not!alwaysTrue(a); }

Thanks. Can you elaborate a bit please? I wonder why the alias won't
work.

Jens


Re: filter!(not!(predicate))(someInputRange) does not compile

2011-01-20 Thread Jens Mueller
Andrei Alexandrescu wrote:
> On 1/19/11 7:19 PM, Jens Mueller wrote:
> >Andrei Alexandrescu wrote:
> >>Place the call to not!alwaysTrue in a local function inside main:
> >>
> >> bool alwaysFalse(uint a) { return not!alwaysTrue(a); }
> >
> >Thanks. Can you elaborate a bit please? I wonder why the alias won't
> >work.
> 
> I thought of it for a bit. It's a limitation of the compiler that's
> worth a bug report. The explanation is a bit involved. Let me start
> by remarking that if you prepend "static" to alwaysTrue, the alias
> works as expected:
> 
> static bool alwaysTrue(uint a) { return true; }
> alias not!(alwaysTrue) alwaysFalse;
> 
> Without "static", alwaysTrue has access to a hidden pointer to the
> stack frame of the function is in.

Yeah. That makes sense.
It has this hidden pointer to access variables from the function it is
defined in.

> In theory a template should be unable to manipulate alwaysTrue
> because of that frame pointer. But Walter has had this great idea of
> instantiating templates in the context of the function they're in,
> so they gain access to the frame pointer too. However, that
> instantiation mechanism still has a few limitations. I think the
> code above runs into one of them.

I see.
I can file a bug report if it is considered important and should not be
forgotten.

Jens


Re: const/immutable member functions

2011-01-24 Thread Jens Mueller
Simen kjaeraas wrote:
> Trass3r  wrote:
> 
> >class F
> >{
> >const Foo bar();
> >}
> >
> >Isn't this ambiguous? "returns a const Foo object" vs. "is a const
> >member function that returns a Foo object"?
> 
> Only to humans. const applies to everything after it, unless there
> are parentheses. In this case, 'everything' is Foo bar();
> 
> I do agree it is ambiguous though, and should be disallowed, or at
> very least, discouraged.

Very true.
Preferred style is to write
Foo bar() const;

Jens


Showing unittest in documentation (Was Re: std.unittests [updated] for review)

2011-01-24 Thread Jens Mueller
Jonathan M Davis wrote:
> In case you didn't know, I have a set of unit test helper functions which 
> have 
> been being reviewed for possible inclusion in phobos. Here's an update.
> 
> Most recent code: http://is.gd/F1OHat
> 
> Okay. I took the previous suggestions into consideration and adjusted the 
> code a 
> bit more. However, most of the changes are to the documentation (though there 
> are some changes to the code). Some of the code duplication was removed, and 
> the 
> way that some of the assertPred functions' errors are formatted has been 
> altered 
> so that values line up vertically, making them easier to compare. The big 
> change 
> is the docs though. There's now a fake version of assertPred at the top with 
> an 
> overall description for assertPred followed by the individual versions with 
> as 
> little documentation as seemed appropriate while still getting all of the 
> necessary information across. A couple of the functions still have 
> irritatingly 
> long example sections, but anything less wouldn't get the functionality 
> across.
> 
> In any case. Here's the updated code. Review away. Andrei set the vote 
> deadline 
> for February 7th, at which point, if it passes majority vote, then it will go 
> into Phobos. The number of functions is small enough now (thanks to having 
> consolidated most of them into the fantastically versatile assertPred) that 
> it 
> looks like it will likely go in std.exception if the vote passes rather than 
> becoming a new module. So, the std.unittests title has now become a bit of a 
> misnomer, but that's what I've been calling it, so it seemed appropriate to 
> continue to label it that way in the thread's title.

I wonder whether there is a nice way to have unittests included in the
documentation but also executed. There are lots of examples in the
module (search for 'Verify Examples').
I like to avoid this duplication. Has anybody an idea how to achieve
this? Often the unittests themselves are a pretty good code
documentation.

Jens


Re: Showing unittest in documentation (Was Re: std.unittests [updated] for review)

2011-01-24 Thread Jens Mueller
Jonathan M Davis wrote:
> On Monday, January 24, 2011 09:55:52 Jens Mueller wrote:
> > Jonathan M Davis wrote:
> > > In case you didn't know, I have a set of unit test helper functions which
> > > have been being reviewed for possible inclusion in phobos. Here's an
> > > update.
> > > 
> > > Most recent code: http://is.gd/F1OHat
> > > 
> > > Okay. I took the previous suggestions into consideration and adjusted the
> > > code a bit more. However, most of the changes are to the documentation
> > > (though there are some changes to the code). Some of the code
> > > duplication was removed, and the way that some of the assertPred
> > > functions' errors are formatted has been altered so that values line up
> > > vertically, making them easier to compare. The big change is the docs
> > > though. There's now a fake version of assertPred at the top with an
> > > overall description for assertPred followed by the individual versions
> > > with as little documentation as seemed appropriate while still getting
> > > all of the necessary information across. A couple of the functions still
> > > have irritatingly long example sections, but anything less wouldn't get
> > > the functionality across.
> > > 
> > > In any case. Here's the updated code. Review away. Andrei set the vote
> > > deadline for February 7th, at which point, if it passes majority vote,
> > > then it will go into Phobos. The number of functions is small enough now
> > > (thanks to having consolidated most of them into the fantastically
> > > versatile assertPred) that it looks like it will likely go in
> > > std.exception if the vote passes rather than becoming a new module. So,
> > > the std.unittests title has now become a bit of a misnomer, but that's
> > > what I've been calling it, so it seemed appropriate to continue to label
> > > it that way in the thread's title.
> > 
> > I wonder whether there is a nice way to have unittests included in the
> > documentation but also executed. There are lots of examples in the
> > module (search for 'Verify Examples').
> > I like to avoid this duplication. Has anybody an idea how to achieve
> > this? Often the unittests themselves are a pretty good code
> > documentation.
> 
> I think that it's been discussed a time or two, but nothing has been done 
> about 
> it. It wouldn't be entirely straightforward to do. Essentially, either a 
> unittest block would have to be generated from the Examples section in the 
> documentation, or you'd have to have some way to indicate that a particular 
> unittest block got put into the documentation as an Examples section. It's 
> certainly true that it would be ideal to have a way to avoid the duplication, 
> but we don't have one at the moment, and it hasn't yet been a high enough 
> priority to sort out how to do it and implement it.

I see. I understand that it does not have high priority. Just wondered
whether ...

Jens


Re: Showing unittest in documentation (Was Re: std.unittests [updated] for review)

2011-01-24 Thread Jens Mueller
Andrei Alexandrescu wrote:
> On 1/24/11 1:50 PM, Jens Mueller wrote:
> >Jonathan M Davis wrote:
> >>I think that it's been discussed a time or two, but nothing has been done 
> >>about
> >>it. It wouldn't be entirely straightforward to do. Essentially, either a
> >>unittest block would have to be generated from the Examples section in the
> >>documentation, or you'd have to have some way to indicate that a particular
> >>unittest block got put into the documentation as an Examples section. It's
> >>certainly true that it would be ideal to have a way to avoid the 
> >>duplication,
> >>but we don't have one at the moment, and it hasn't yet been a high enough
> >>priority to sort out how to do it and implement it.
> >
> >I see. I understand that it does not have high priority. Just wondered
> >whether ...
> >
> >Jens
> 
> The change is much simpler than what Jonathan suggests. A change can
> be made such that any unittest preceded by a documentation comment
> is automatically considered an example.
> 
> /**
>  Example:
> */
> unittest
> {
> writeln("This is how it works.");
> }

That does not work for me.
$ dmd -unittest -D -Dftest.html test.d

I get an empty example.
void __unittest2();

Example:





Jens


Re: Showing unittest in documentation (Was Re: std.unittests [updated] for review)

2011-01-24 Thread Jens Mueller
Daniel Gibson wrote:
> Am 24.01.2011 21:39, schrieb Jens Mueller:
> >Andrei Alexandrescu wrote:
> >>On 1/24/11 1:50 PM, Jens Mueller wrote:
> >>>Jonathan M Davis wrote:
> >>>>I think that it's been discussed a time or two, but nothing has been done 
> >>>>about
> >>>>it. It wouldn't be entirely straightforward to do. Essentially, either a
> >>>>unittest block would have to be generated from the Examples section in the
> >>>>documentation, or you'd have to have some way to indicate that a 
> >>>>particular
> >>>>unittest block got put into the documentation as an Examples section. It's
> >>>>certainly true that it would be ideal to have a way to avoid the 
> >>>>duplication,
> >>>>but we don't have one at the moment, and it hasn't yet been a high enough
> >>>>priority to sort out how to do it and implement it.
> >>>
> >>>I see. I understand that it does not have high priority. Just wondered
> >>>whether ...
> >>>
> >>>Jens
> >>
> >>The change is much simpler than what Jonathan suggests. A change can
> >>be made such that any unittest preceded by a documentation comment
> >>is automatically considered an example.
> >>
> >>/**
> >>  Example:
> >>*/
> >>unittest
> >>{
> >> writeln("This is how it works.");
> >>}
> >
> >That does not work for me.
> >$ dmd -unittest -D -Dftest.html test.d
> >
> >I get an empty example.
> >void__unittest2();
> >
> >Example:
> >
> >
> >
> >
> >
> >Jens
> 
> "A change can be made" - this is a proposal, not an implemented feature.

Stupid me. I was so excited that this may be possible that I didn't read
carefully.

Jens


Re: const/immutable member functions

2011-01-24 Thread Jens Mueller
Jonathan M Davis wrote:
> On Monday 24 January 2011 12:08:29 Don wrote:
> > Steven Schveighoffer wrote:
> > > On Mon, 24 Jan 2011 13:36:36 -0500, bearophile
> > > 
> > >  wrote:
> > >> There are six, seven or more people that wish to do something about
> > >> this situation. TDPL is the D2 reference, but few little changes over
> > >> its first edition are acceptable if they improve the D language a
> > >> little.
> > >> 
> > >> - Trass3r: asks if the code is ambiguous
> > >> - Jonathan M Davis: does't like it and puts const/etc on the right
> > >> - Simen kjaeraas thinks it's ambiguous though, and should be
> > >> disallowed, or at very least, discouraged.
> > >> - Jens Mueller: Preferred style is to write const on the right
> > >> - Andrej Mitrovic suggests to use @ but says it clutters up source code.
> > >> - I agree with Jonathan M Davis.
> > >> 
> > >> What other people think about this situation? Do you want
> > >> const/immutable to be required on the right, or do you prefer the
> > >> current situation, or do you prefer some other solution?
> > > 
> > > I wouldn't say that I *prefer* the current solution, but the current
> > > solution is not so bad that I need it changed.
> > > 
> > > It works fine, despite being confusing.  If it wasn't consistent with
> > > the rest of the attributes, I'd say it was in need of changes, but it
> > > fits within the scheme already outlined.
> > 
> > It's a problem for all of the other attributes as well. I wish it were
> > disallowed for all of them.
> > Incidentally, putting it afterwards always works. Putting it before
> > doesn't always work, due to compiler bugs (for example, prefix 'pure'
> > doesn't work for inner functions).
> 
> There there is a bug that attributes on constructors don't show up in 
> generated 
> .di files if they're on the right.
> 
> I think that the real problem with putting them all on the right is that 
> attributes such as static, public, and private are on the left in other 
> languages, so it would be really weird to require that they be on the right. 
> Still, it might be worth it.

Can't one have only the type qualifiers on the right? I mean it's only
confusing for those.
pure/nothrow int foo();
causes no confusion at all.
The access qualifiers also work fine in the beginning. On the right they
won't even compile.

Jens


Re: const/immutable member functions

2011-01-25 Thread Jens Mueller
Jonathan M Davis wrote:
> On Monday 24 January 2011 13:52:49 Jens Mueller wrote:
> > Jonathan M Davis wrote:
> > > On Monday 24 January 2011 12:08:29 Don wrote:
> > > > Steven Schveighoffer wrote:
> > > > > On Mon, 24 Jan 2011 13:36:36 -0500, bearophile
> > > > > 
> > > > >  wrote:
> > > > >> There are six, seven or more people that wish to do something about
> > > > >> this situation. TDPL is the D2 reference, but few little changes
> > > > >> over its first edition are acceptable if they improve the D
> > > > >> language a little.
> > > > >> 
> > > > >> - Trass3r: asks if the code is ambiguous
> > > > >> - Jonathan M Davis: does't like it and puts const/etc on the right
> > > > >> - Simen kjaeraas thinks it's ambiguous though, and should be
> > > > >> disallowed, or at very least, discouraged.
> > > > >> - Jens Mueller: Preferred style is to write const on the right
> > > > >> - Andrej Mitrovic suggests to use @ but says it clutters up source
> > > > >> code. - I agree with Jonathan M Davis.
> > > > >> 
> > > > >> What other people think about this situation? Do you want
> > > > >> const/immutable to be required on the right, or do you prefer the
> > > > >> current situation, or do you prefer some other solution?
> > > > > 
> > > > > I wouldn't say that I *prefer* the current solution, but the current
> > > > > solution is not so bad that I need it changed.
> > > > > 
> > > > > It works fine, despite being confusing.  If it wasn't consistent with
> > > > > the rest of the attributes, I'd say it was in need of changes, but it
> > > > > fits within the scheme already outlined.
> > > > 
> > > > It's a problem for all of the other attributes as well. I wish it were
> > > > disallowed for all of them.
> > > > Incidentally, putting it afterwards always works. Putting it before
> > > > doesn't always work, due to compiler bugs (for example, prefix 'pure'
> > > > doesn't work for inner functions).
> > > 
> > > There there is a bug that attributes on constructors don't show up in
> > > generated .di files if they're on the right.
> > > 
> > > I think that the real problem with putting them all on the right is that
> > > attributes such as static, public, and private are on the left in other
> > > languages, so it would be really weird to require that they be on the
> > > right. Still, it might be worth it.
> > 
> > Can't one have only the type qualifiers on the right? I mean it's only
> > confusing for those.
> > pure/nothrow int foo();
> > causes no confusion at all.
> > The access qualifiers also work fine in the beginning. On the right they
> > won't even compile.
> 
> I'm surprised that they don't work on the right. The argument for allowing 
> const 
> on the left-hand side has always been consistency - that all function 
> attributes 
> work the same. If that's not the case, then it seems to me like a definite 
> argument for disallowing const on the left.

I do not know what are you referring to when you say function attributes.
I distinguish the following:
type qualifiers: const, immutable, maybe also inout
function attributes: pure, nothrow
storage class: ref, in, out, static
access qualifiers: private, package, protected, public, export

Storage class and access qualifies should go left only in my opinion and
that's how dmd behaves.
Function attributes can go left and right and I think there is nothing
wrong with allowing that because there is no confusion. Even though I
like them to be right as well. But this is matter of style.
There is only confusion for type qualifies. Namely does the qualifier
apply to the return type or the function (better said the type of this).
Now it is consistent in the sense that
const:
int foo();
const {
int foo();
}
const int foo();

all mean the same. And Walter seems to be unsure whether forbidding
const void foo() is worth the trouble, isn't it?
I see and felt the pain for newcomers to decipher the meaning of
const void foo();
I see two options:
Either we clarify the documentation (e.g. examples) to help newcomers or
we fix it in the front end. Picking the second option means to provide a
patch and send it to review. Picking the first option means improving
http://www.digitalmars.com/d/2.0/const3.html

Jens


Re: Showing unittest in documentation (Was Re: std.unittests

2011-01-25 Thread Jens Mueller
Jonathan M Davis wrote:
> On Monday 24 January 2011 15:27:08 foobar wrote:
> > Steven Schveighoffer Wrote:
> > > 
> > > This only makes sense if:
> > > 
> > > 1. The unit test immediately follows the item being documented
> > > 2. The unit test *only* tests that item.
> > > 
> > > The second one could be pretty annoying.  Consider cases where several
> > > functions interact (I've seen this many times on Microsoft's
> > > Documentation), and it makes sense to make one example that covers all of
> > > them.  Having them 'testable' means creating several identical unit
> > > tests.
> > > 
> > > One way to easily fix this is to allow an additional parameter to the
> > > comment:
> > > 
> > > /**
> > > Example(Foo.foo(int), Foo.bar(int)):
> > > */
> > > unittest
> > > {
> > > 
> > > auto foo = new Foo;
> > > foo.foo(5);
> > > foo.bar(6);
> > > assert(foo.toString() == "bazunga!");
> > > 
> > > }
> > > 
> > > The above means, copy the example to both Foo.foo(int) and Foo.bar(int)
> > > 
> > > An alternative that is more verbose, but probably more understandable:
> > > 
> > > /**
> > > Example:
> > > Covers Foo.foo(int)
> > > Covers Foo.bar(int)
> > > */
> > > 
> > > Of course, a lack of target just means it applies to the item just
> > > documented.
> > > 
> > > One other thing, using writefln is considered bad form in unit tests (you
> > > want *no* output if the unit test works).  But many examples might want
> > > to demonstrate how e.g. an object interacts with writefln.  Any
> > > suggestions? The assert line above is not very pretty for example...
> > > 
> > > -Steve
> > 
> > Unit-tests are defined on a module level, not a function level, hence I
> > would expect to see the unit-tests that serve as examples to appear in an
> > examples section on the page the documents the module itself. In the
> > online docs I would expect the function names used in the example to be
> > links to the individual function doc and for each function have a list of
> > links to examples it participated in. This should be automatic and the
> > user shouldn't need to provide the "list of functions documented in this
> > example".
> > 
> > Just my two cents..
> 
> Examples almost always go with functions. The whole point is to avoid having 
> to 
> have the function examples both in the documentation and in a unittest block. 
> It 
> would be a huge mess to try and put all of the examples in the module 
> documentation. I shudder to think what that would look like for std.algorithm 
> - 
> or even worse (_far_ worse), std.datetime. The simple syntax of
> 
> /++ Example +/
> unittest
> {
> }
> 
> 
> making that unittest block go in the documentation of the preceding function 
> should work just fine. We already have /++ Ditto +/ which puts a function in 
> with 
> the preceding function's documentation. So, having /++ Example +/ on top of 
> that 
> isn't much of a stretch.

I feel the same.
When I propose how it should be and how it is right to me I feel a bit
bad. Because I have not contributed anything besides talking. That's why
in the end I always will follow the people's advice who actually do the
work. I mean if Walter decides to leave it as it is, it's his decision
until somebody provides a patch. He does the work. Who am I to tell him
what he should do.

Jens


Re: const/immutable member functions

2011-01-25 Thread Jens Mueller
Jonathan M Davis wrote:
> On Tuesday 25 January 2011 01:45:49 Jens Mueller wrote:
> > 
> > I do not know what are you referring to when you say function attributes.
> > I distinguish the following:
> > type qualifiers: const, immutable, maybe also inout
> > function attributes: pure, nothrow
> > storage class: ref, in, out, static
> > access qualifiers: private, package, protected, public, export
> > 
> > Storage class and access qualifies should go left only in my opinion and
> > that's how dmd behaves.
> > Function attributes can go left and right and I think there is nothing
> > wrong with allowing that because there is no confusion. Even though I
> > like them to be right as well. But this is matter of style.
> > There is only confusion for type qualifies. Namely does the qualifier
> > apply to the return type or the function (better said the type of this).
> > Now it is consistent in the sense that
> > const:
> > int foo();
> > const {
> > int foo();
> > }
> > const int foo();
> > 
> > all mean the same. And Walter seems to be unsure whether forbidding
> > const void foo() is worth the trouble, isn't it?
> > I see and felt the pain for newcomers to decipher the meaning of
> > const void foo();
> > I see two options:
> > Either we clarify the documentation (e.g. examples) to help newcomers or
> > we fix it in the front end. Picking the second option means to provide a
> > patch and send it to review. Picking the first option means improving
> > http://www.digitalmars.com/d/2.0/const3.html
> 
> Anything that modifies a function could be considered a function attribute: 
> public, static, nothrow, pure, @property, const, etc. Something that modifies 
> the 
> return value of a function or a function parameter isn't a function 
> attribute. 

You want to make a distinction regarding the modification. Those ones
are called function attributes because they change a function in that
regard. I'm not sure whether this clarifies things.
I just think const/immutable as type qualifiers and you can apply those
to member functions because the type of this object can be qualified as
const/immutable.

> In the past, Walter's argument for const working as it is is that it is 
> consistent with the other function attributes and that requiring that it be 
> on 
> the right would be inconsistent.

I didn't have that impression reading the mentioned bug reports. It
seems there is more that I'm missing.

Jens


Re: const/immutable member functions

2011-01-25 Thread Jens Mueller
bearophile wrote:
> Jens Mueller:
> 
> > I didn't have that impression reading the mentioned bug reports. It
> > seems there is more that I'm missing.
> 
> See Walter answers here:
> http://d.puremagic.com/issues/show_bug.cgi?id=4070

I'm not getting it. In comment 1 Walter refers to const:, const {} and
const (let's say inline) and they are all consistent (all are written
left). That's his point.
And forcing now const for the last syntax to be on the right makes it
inconsistent. So he weighs consistency against the possible confusion
and favors consistency in the end. That is a valid point. I do not see
Walter arguing for consistency with non-type qualifiers. Meaning
Walter's argument is valid but most of us weigh things here differently.
Most favor inconsistency over possible confusion in this case. That's
why the problem is currently solved as a matter of good style. I'd love
to see that change but I think it's unfair to force it on Walter.
Because he is not convinced yet. Next step is either propose a patch
(i.e. trying harder to convince Walter, hoping that a patch may change
things for him.) or document a preferred style in this regard clarifying
the confusion.

Jens


Re: std.unittests [updated] for review

2011-01-30 Thread Jens Mueller
Masahiro Nakagawa wrote:
> 
> I vote Andrei's suggestion, std.exception is better than new std.unittests.
> I think testing module should provide more features(e.g. Mock, Stub...).
> Your helpers help assert writing style but not help testing.
> In addition, std.exception already defined similar functions.

I do not like putting it in std.exception. Maybe the name std.unittest
is also not good. I would propose std.assert if assert wasn't a keyword.
When I use std.exception I want to handle situations that are part of
the spec (i.e. exceptions) whereas Jonathan's module helps me writing
asserts (that's most of the time unittests).
Basically it helps me verifying behavior according to a spec. I want to
keep the dichotomy of errors and exceptions. Putting both things in one
module is rather strange to me. What are the arguments for putting it in
std.exception? I find the size a rather weak argument. I thought about
providing an assertDeath ones std.process is redone.
And even though enforce and assert are mirroring each other they are
used in different contexts. I would _not_ expect helpers for writing
assertions (Assert_Error_) in a module named std.exception.

Jens


Re: std.unittests for (final?) review

2011-01-30 Thread Jens Mueller
Andrei Alexandrescu wrote:
> On 1/5/11 8:54 PM, Ary Borenszweig wrote:
> >I prefer assert, assertFalse, assertEqual and assertNotEqual.
> >
> >Compare this:
> >assertPredicate!"a<  b"(1 + 1, 3);
> >
> >To this:
> >assert(1 + 1<  3)
> >
> >Or to this:
> >
> >assertLess(1 + 1, 3)
> >
> >Ok, the first one is more generic. But so the error message for the 
> >assertion failure will be more generic, when you want exactly the opposite 
> >to happen.
> >Plus your brain has to think more to read it (starting from the point that 
> >it's longer).
> >
> >assertPredicate!"<"(1 + 1, 3) reminds me of polish notation, which is very 
> >good for machines but not very good for humans.
> 
> One problem with using distinct names is the explosion thereof.
> Google unittests have EXPECT_EQ, EXPECT_NE, EXPECT_LT, EXPECT_GT,
> EXPECT_LE, EXPECT_GE, EXPECT_TRUE, EXPECT_FALSE and probably others.
> I was able to write these from memory because I used to know
> Fortran, which uses the same two-letter conventions for comparisons.
> At that point I think we can say, wait a minute, why not use the
> respective symbols which are impossible to forget?

I partly share this. But there may be users who are not that deeply into
the template stuff. Even though they miss a lot. I'd like to have
testing easy and assertEqual is easy. I mean Jonathan started with those
names. When I look now at the documentation the name assertPred alone
does not tell much. I feel a bit lost.
Why not define an alias? I mean there are people who master assertPred.
Why not giving others a slow start using assertEqual and friends.

Jens


Re: std.unittests [updated] for review

2011-01-30 Thread Jens Mueller
Jonathan M Davis wrote:
> On Sunday 30 January 2011 04:13:59 Jens Mueller wrote:
> > I do not like putting it in std.exception. Maybe the name std.unittest
> > is also not good. I would propose std.assert if assert wasn't a keyword.
> > When I use std.exception I want to handle situations that are part of
> > the spec (i.e. exceptions) whereas Jonathan's module helps me writing
> > asserts (that's most of the time unittests).
> > Basically it helps me verifying behavior according to a spec. I want to
> > keep the dichotomy of errors and exceptions. Putting both things in one
> > module is rather strange to me. What are the arguments for putting it in
> > std.exception? I find the size a rather weak argument. I thought about
> > providing an assertDeath ones std.process is redone.
> > And even though enforce and assert are mirroring each other they are
> > used in different contexts. I would _not_ expect helpers for writing
> > assertions (Assert_Error_) in a module named std.exception.
> 
> Would you expect assumeUnique or pointsTo to be in std.exception? I sure 
> wouldn't, but for whatever reason, they're there. std.exception is a bit of a 
> an 
> odd module anyway. enforce and collectException are the only two which are 
> exception related, and there aren't many functions in there at all.
> 
> collectExceptionMsg, which is one of my proposed functions, definitely 
> belongs in 
> std.exception, since it's similar to collectException. The others are more 
> debatable. They all throw AssertErrors on failure, and two of them - 
> assertThrown and assertNotThrown - test for exceptions, but they aren't 
> really 
> exception-related overall. However, std.exception is by far the best fit of 
> the 
> currently existing modules, and enforce is essentially an assert that throws 
> an 
> exception instead of an AssertError, and it's in std.exception.
> 
> So, yeah. It's a bit odd to stick them in std.exception, but std.exception is 
> already rather odd, and if we don't want to create a new module, it's by far 
> the 
> best place to put them. And unless we forsee added a bunch of new unit 
> testing 
> functions to Phobos, creating a new std.unittests would mean having a pretty 
> small module. Ignoring overloads, std.unittests would have only 4 functions 
> in 
> it. And if we put collectExceptionMsg in std.exception where it belongs, then 
> std.unittests would have only 3 functions. And unless we really expect a 
> bunch 
> of new unit testing functions, that really doesn't seem like a good idea to 
> me. 
> And virtually every unit testing function that I've come up with has been 
> merged 
> into assertPred. So, don't forsee there being much in the way of additions to 
> std.unittests unless someone comes up with something drastically different 
> which 
> makes it into Phobos.
> 
> So, while I don't think that std.exception is a great fit, I do think that 
> it's a 
> reasonable fit. If anything, I think that it would be better to come up with 
> a 
> better name for std.exception than it would be to stick my new functions in a 
> separate module. But we _already_ rename std.contracts to std.exception, so 
> that 
> would mean renaming that module _again_, and I have no idea what a better 
> name 
> would be anyway.

My preference for distinct modules follows that line of separating
errors and exceptions.
The only argument against putting in its own module is it's size. That
seems to be your main point. I think putting something in new module
should mainly be concerned with separating stuff logically. Later on it
should be easy to add a new module that imports std.exception and let's
say std.assertion.
But all you say is valid. I just fear that fixing names later will be
costly. Having two modules allows us to handle this better. Just because
std.exception is already kind of messy doesn't justify putting in
there.

Jens


Re: std.unittests [updated] for review

2011-01-30 Thread Jens Mueller
Jonathan M Davis wrote:
> On Sunday 30 January 2011 05:13:19 Jens Mueller wrote:
> > 
> > My preference for distinct modules follows that line of separating
> > errors and exceptions.
> > The only argument against putting in its own module is it's size. That
> > seems to be your main point. I think putting something in new module
> > should mainly be concerned with separating stuff logically. Later on it
> > should be easy to add a new module that imports std.exception and let's
> > say std.assertion.
> > But all you say is valid. I just fear that fixing names later will be
> > costly. Having two modules allows us to handle this better. Just because
> > std.exception is already kind of messy doesn't justify putting in
> > there.
> 
> I think that it makes perfect sense for the likes of assertPred and 
> assertThrown 
> to be in the same module as enforce. They serve similar functions. It's just 
> that one throws an assertError on failure, whereas the other usually throws 
> an 
> Exception.

Somehow I'm a bit off here. Because assert throws an error and enforce
an exception make them not similar for me. I mean that's the whole point
of distinguishing error and exceptions.

> What is odd is sticking them in a module named std.exception. But while 
> assertPred might be similar to enforce, it definitely wouldn't make even less 
> sense to put enforce in a module named std.unittests. I have no idea what a 
> good 
> name would be.

That's true. Since we do not have a good name for assert and enforce
together I wouldn't put them in the same module. I suppose there is a
reason why we are having difficulties finding a name.

> So, yes, it's a bit odd that std.exception would have assertPred in it, but 
> it's 
> the best fit out of all of the pre-existing modules, and std.exception does 
> have 
> semi-related functions. And honestly, I _do_ think that the size of a module 
> matters. If it doesn't have enough functions in it, then it really shouldn't 
> be 
> its own module. The problem is when you have miscellaneous functions which 
> don't 
> quite fit any any module - which may be why assumeUnique and pointsTo ended 
> up in 
> std.exception.

For me it's first logical separation. This way I never end up with
functions in a module that do not belong there. But of course I may end
up with many modules. So I may end up with the same problem now with
modules. So I'm completely fine with hierarchies a la Java (maybe less
deep). I'll guess you're not.
I think of these modules as hierarchies as in a file system. Because
it's very for me to navigate in a file system.

No need to reply. I think you have good arguments that are valid. And in
the very end it often boils down to a matter of style. It's very
difficult to argue about style.

Jens


Re: std.unittests [updated] for review

2011-01-31 Thread Jens Mueller
Andrei Alexandrescu wrote:
> On 01/30/2011 06:13 AM, Jens Mueller wrote:
> >Masahiro Nakagawa wrote:
> >>
> >>I vote Andrei's suggestion, std.exception is better than new std.unittests.
> >>I think testing module should provide more features(e.g. Mock, Stub...).
> >>Your helpers help assert writing style but not help testing.
> >>In addition, std.exception already defined similar functions.
> >
> >I do not like putting it in std.exception. Maybe the name std.unittest
> >is also not good. I would propose std.assert if assert wasn't a keyword.
> >When I use std.exception I want to handle situations that are part of
> >the spec (i.e. exceptions) whereas Jonathan's module helps me writing
> >asserts (that's most of the time unittests).
> >Basically it helps me verifying behavior according to a spec. I want to
> >keep the dichotomy of errors and exceptions. Putting both things in one
> >module is rather strange to me. What are the arguments for putting it in
> >std.exception? I find the size a rather weak argument. I thought about
> >providing an assertDeath ones std.process is redone.
> >And even though enforce and assert are mirroring each other they are
> >used in different contexts. I would _not_ expect helpers for writing
> >assertions (Assert_Error_) in a module named std.exception.
> >
> >Jens
> 
> assertThrows and its converse are a good fit for std.exception. Then
> we're left with a couple of concepts that don't deserve their own
> module and are difficult to fit elsewhere. I reckon that in a
> perfect world there would be a better match, but I don't cringe at
> the thought of std.exception holding them.

I going to get used to it. I'll guess I just don't want to loose the
concept of errors vs. exceptions.

Jens


Would user polls be useful? (Was: Re: std.unittests [updated] for review)

2011-01-31 Thread Jens Mueller
spir wrote:
> On 01/30/2011 01:13 PM, Jens Mueller wrote:
> >I do not like putting it in std.exception. Maybe the name std.unittest
> >is also not good. I would propose std.assert if assert wasn't a keyword.
> >[...]
>  I would_not_  expect helpers for writing
> >assertions (Assert_Error_) in a module named std.exception.
> 
> Same for me. Find it strange. Would never search assertion helper
> funcs inside std.exception. Why not std.assertion? std.unittests
> would be fine if there were some more stuff in there, I mean not
> only assertions. Else, the obvious name imo is std.assertion.

Nice. I just wonder what others think.
I'd like to start a poll
http://doodle.com/vn2ceenuvfwtx38e
In general are those polls useful? I mean there where some
discussions in the last time where a poll may help. git vs. hg. 80 vs.
90 characters per line. If all arguments are on the table it can be
useful to have an opinion poll to finally settle the discussion.

It may even be that I'm totally wrong here. But I think the module
naming needs to be done very careful. It's what a D newcomer needs to
grasp as easy as possible. Am I too picky? Somehow I care (too?) much
about names.

Jens


Re: std.unittests [updated] for review

2011-01-31 Thread Jens Mueller
Jonathan M Davis wrote:
> In case you didn't know, I have a set of unit test helper functions which 
> have 
> been being reviewed for possible inclusion in phobos. Here's an update.
> 
> Most recent code: http://is.gd/F1OHat
> 
> Okay. I took the previous suggestions into consideration and adjusted the 
> code a 
> bit more. However, most of the changes are to the documentation (though there 
> are some changes to the code). Some of the code duplication was removed, and 
> the 
> way that some of the assertPred functions' errors are formatted has been 
> altered 
> so that values line up vertically, making them easier to compare. The big 
> change 
> is the docs though. There's now a fake version of assertPred at the top with 
> an 
> overall description for assertPred followed by the individual versions with 
> as 
> little documentation as seemed appropriate while still getting all of the 
> necessary information across. A couple of the functions still have 
> irritatingly 
> long example sections, but anything less wouldn't get the functionality 
> across.
> 
> In any case. Here's the updated code. Review away. Andrei set the vote 
> deadline 
> for February 7th, at which point, if it passes majority vote, then it will go 
> into Phobos. The number of functions is small enough now (thanks to having 
> consolidated most of them into the fantastically versatile assertPred) that 
> it 
> looks like it will likely go in std.exception if the vote passes rather than 
> becoming a new module. So, the std.unittests title has now become a bit of a 
> misnomer, but that's what I've been calling it, so it seemed appropriate to 
> continue to label it that way in the thread's title.

What do you think about renaming
collectExceptionMsg
to
collectThrowableMsg?
Since it handles both errors and exceptions.
One could make it handle only exceptions and then it would be a perfect
fit for std.exception. Does one need really need to collect error
messages? If so then collectException in std.exception should handle
errors as well and should be called collectThrowable.

Jens


Re: Would user polls be useful? (Was: Re: std.unittests [updated] for review)

2011-02-01 Thread Jens Mueller
Jonathan M Davis wrote:
> On Monday 31 January 2011 15:49:11 Jens Mueller wrote:
> > spir wrote:
> > > On 01/30/2011 01:13 PM, Jens Mueller wrote:
> > > >I do not like putting it in std.exception. Maybe the name std.unittest
> > > >is also not good. I would propose std.assert if assert wasn't a keyword.
> > > >[...]
> > > >
> > >  I would_not_  expect helpers for writing
> > >  
> > > >assertions (Assert_Error_) in a module named std.exception.
> > > 
> > > Same for me. Find it strange. Would never search assertion helper
> > > funcs inside std.exception. Why not std.assertion? std.unittests
> > > would be fine if there were some more stuff in there, I mean not
> > > only assertions. Else, the obvious name imo is std.assertion.
> > 
> > Nice. I just wonder what others think.
> > I'd like to start a poll
> > http://doodle.com/vn2ceenuvfwtx38e
> > In general are those polls useful? I mean there where some
> > discussions in the last time where a poll may help. git vs. hg. 80 vs.
> > 90 characters per line. If all arguments are on the table it can be
> > useful to have an opinion poll to finally settle the discussion.
> > 
> > It may even be that I'm totally wrong here. But I think the module
> > naming needs to be done very careful. It's what a D newcomer needs to
> > grasp as easy as possible. Am I too picky? Somehow I care (too?) much
> > about names.
> 
> I wouldn't actually be looking for "assertion helpers" anywhere. I might be 
> looking for unit test helper, but I wouldn't be thinking about assertions at 
> all, even if the unit test helpers threw AssertError like they do. But truth 
> be 
> told, I don't generally look for modules with a particular name unless I know 
> what I'm looking for. I look at the list of modules and see which names seem 
> like they'd have what I'd want. As such, std.unittests would make me think 
> that 
> the module held unit test stuff, whereas I really wouldn't know what to 
> expect in 
> std.assertion or std.exception at all - _especially_ std.assertion.

When I hear std.assertion and std.exception then I assume that these
modules contain stuff for working with assertions and exceptions
respectively. Just the fact that I want to throw an exception makes me
go to std.exception to check out what's in there.

> However, given the small number of unit test functions, it makes no sense for 
> them to be their own module. So, I really don't think that std.unittests 
> makes 
> sense at this point. std.exception may not be the best name, but given what's 
> currently in it, the unit testing functions fit in there reasonably well. So, 
> the 
> issue then is what to name std.exception if that name is not good enough. 
> std.assertion makes no sense - particularly with enforce in there - and 
> std.unittests doesn't work, because it's not just unit testing stuff in there.

I really dislike the size argument. Because as a programmer I do not
care how big a module is in the first place. First I care about how to
find it.
If I have found it I may say: "Oh that's a little module". But that
usually doesn't bother me much.
And putting something in a module where it does not belong is not an
option. I think we agree on that since you would like to have a better
name for std.exception.

Just checked:
std.bigint is quite small looking at it's documentation. std.complex as
well. std.demangle is very small. std.functional has seven functions.
std.getopt has one big function in it. std.uni is very small. There are
more I'll guess. It's not the size of a module that comes first when to
decide where to put something.

> So, unless you can come up with a better name for std.exception with the idea 
> that it's going to be holding my new functions along with what's already in 
> there, I don't think that discussing names is going to mean much. From a 
> contents standpoint, it does make sense that the stuff in std.exception and 
> my 
> stuff would be lumped together, and it does not make sense for my stuff to be 
> in 
> its own module at this point. There isn't enough of it, and since it fits 
> well in 
> std.exception, there's even less reason to create a new module for it. So, if 
> a 
> change is to be made, I think that it's going to have to be to the name of 
> std.exception, and I can't think of a better name nor have I see a better 
> name 
> suggested.

The poll is less about a good name. It should be more about where do you
expect things to be. And since I do not have a good name for a module
that c

Re: std.unittests [updated] for review

2011-02-01 Thread Jens Mueller
Michel Fortin wrote:
> On 2011-02-01 10:34:26 -0500, Andrei Alexandrescu
>  said:
> 
> >On 2/1/11 9:21 AM, Don wrote:
> >>Jonathan M Davis wrote:
> >>>Do you really find
> >>>
> >>>assertPred!"=="(min(5, 7), 5);
> >>>
> >>>to be all that harder to understand than
> >>>
> >>>assert(min(5, 7) == 5);
> >>
> >>I do. *Much* harder. Factor of two, at least.
> >>In absolute terms, not so much, because it was the original assert is
> >>very easy to understand. But the relative factor matters enormously.
> >>Much as comparing:
> >>a.add(b);
> >>a += b;
> >>
> >>And I think this is a very important issue.
> >>
> >> >I don't see how these functions could be anything but an improvement.
> >> > But even if they get into Phobos, you obviously don't have to use them.
> >>
> >>This is not true. Including them in Phobos gives a legitimacy to that
> >>style of programming. It's a role model.
> >>
> >>Including stuff like this could give D a reputation for lack of
> >>readability. My belief is that right now, the #1 risk for Phobos is that
> >>it becomes too clever and inaccessible.
> >>
> >>IMHO, something simple which has any appearance of being complicated,
> >>needs a VERY strong justification.
> >
> >Does this count as a vote against the submission?
> 
> To me this is a compelling argument against. That and the fact that
> it can't really mimic the true behaviour of assert in some
> situation. assertPred won't work correctly for 'in' contracts with
> inheritance, where the compiler generate the assertion code
> differently.
> 
> In my view, the correct way to improve assertion error messages is
> to improve how the compiler handle assertions (it should output
> messages like it does for static asserts).
> 
> assertPred might be fine as a stopgap solution, but personally I'd
> not make it part of the public API. We can't tell people to use
> assert() everywhere and then tell them they should use
> assertPred!op() if they want a useful error message except for 'in'
> contracts of virtual functions; that'd just be too confusing.

Actually we say use assertPred/etc. when writing unittests, don't we? To
me that is not complicated. There used to be a version(unittest). I
don't know for what reason it got removed. If it was still there an else
could help a bit. Like
version(unittest) {
}
else {
static assert(false, "assertPred/etc. are only available within 
unittests.");
}
Now every code compiled without -unittest and using assertPred/etc will
fail to compile. But of course with -unittest it still seems that it
will work in contracts. I mean at least we can make the problem explicit
in most cases. Not sure how likely it is that people will distribute
software that they only compiled with unittests.

Jens


Re: bug with std.range.zip? range with opEquals(const) const not allowed inside zip

2012-08-27 Thread Jens Mueller
Jonathan M Davis wrote:
> On Sunday, August 26, 2012 14:47:38 Jens Mueller wrote:
> > What is the ref situation?
> > I thought ref is used as an optimization that allows passing lvalues
> > more efficiently whereas without ref is needed for rvalues.
> 
> ref doesn't necessarily have anything to do with optimizations. It makes it 
> so 
> that any operations done on the function parameter inside the function are 
> also done on the variable passed in. The parameter is essentially an alias 
> for 
> the variable passed in.
> 
> You can choose to use ref in order to avoid a copy, but it's also arguably 
> bad 
> practice to have a function take an argument by ref if it's not actually 
> going 
> to mutate the original, since that's confusing.
> 
> _const_ ref is more for avoiding the copy, since it's like ref except that 
> you 
> can't actually mutate the variable. So, it makes sense to use const ref 
> specifically to avoid unnecessary copies.

This is what I meant.

> However, while in C++, you can pass rvalues to const&, in D, you can't. It 
> doesn't matter if the ref is const or not, it still requires an lvalue. This 
> solves certain issues caused by C++'s choice (issues primarily related to 
> function overloading IIRC), but it makes it rather difficult to declare a 
> single 
> function which takes either an lvalue or an rvalue but which tries to avoid 
> unnecessary copying.
> 
> D's auto ref essentially does it (rvalues are then always passed by rvalue 
> and 
> lvalues are always passed by lvalue), but it only works with templates, 
> because it has to create two versions of the function.
>
> So, what we'd _like_ to have is a solution where you can mark a parameter in 
> a 
> way similar to auto ref or C++s const& and have the function not care whether 
> it's passed an lvalue or rvalue and have it avoid copying as much as possible 
> and have it work with _all_ function types, not just templated ones, but we 
> haven't sorted out how to do that yet. _That's_ the ref situation that needs 
> to be solved.

Aha. I see.
Then we get down from four declarations to two by writing
bool opEquals(const auto ref S rhs) const {...}
and
bool opEquals(auto ref S rhs) {...}

And with inout probably even further:
bool opEquals(inout auto ref S rhs) inout {...}

Thanks for explaining.

Jens


Re: Building LDC from source

2012-09-06 Thread Jens Mueller
Andrei Alexandrescu wrote:
> On 9/6/12 9:22 AM, Jacob Carlborg wrote:
> >On 2012-09-06 02:30, jerro wrote:
> >>>reason to do with not finding druntime.
> >>
> >>You probably didn't do
> >>
> >>git submodule init; git submodule update
> >
> >Or in one command:
> >
> >$ git submodule update --init
> >
> >You can also add --recursive to be on the safe side.
> 
> BTW I've added pointers for the LDC instructions to the download
> page: http://dlang.org/download.html. Feedback welcome.

Better add links to
https://github.com/ldc-developers/ldc/wiki/Installation
for building on Linux and
https://github.com/ldc-developers/ldc/wiki/Building-and-hacking-LDC-on-Windows-using-MSVC
for building on Windows.

Jens


Re: Building LDC from source

2012-09-06 Thread Jens Mueller
Andrei Alexandrescu wrote:
> On 9/6/12 9:22 AM, Jacob Carlborg wrote:
> >On 2012-09-06 02:30, jerro wrote:
> >>>reason to do with not finding druntime.
> >>
> >>You probably didn't do
> >>
> >>git submodule init; git submodule update
> >
> >Or in one command:
> >
> >$ git submodule update --init
> >
> >You can also add --recursive to be on the safe side.
> 
> BTW I've added pointers for the LDC instructions to the download
> page: http://dlang.org/download.html. Feedback welcome.

I think you forgot to add the Gentoo logo to git.

Jens


Re: Building LDC from source

2012-09-06 Thread Jens Mueller
Andrei Alexandrescu wrote:
> On 9/6/12 11:57 AM, Jens Mueller wrote:
> >>BTW I've added pointers for the LDC instructions to the download
> >>page: http://dlang.org/download.html. Feedback welcome.
> >
> >I think you forgot to add the Gentoo logo to git.
> >
> >Jens
> 
> You're right, thanks! Done now.

Link for Windows should be
https://github.com/ldc-developers/ldc/wiki/Building-and-hacking-LDC-on-Windows-using-MSVC

Jens


Re: std.benchmark redux

2012-09-17 Thread Jens Mueller
Andrei Alexandrescu wrote:
> I recall we have nothing in the review queue for the time being, is
> that correct?
> 
> If that's the case, allow me to tender std.benchmark again for
> inclusion into Phobos. I reworked the benchmarking framework for
> backward compatibility, flexibility, and convenience.
> 
> Code: https://github.com/D-Programming-Language/phobos/pull/794
> 
> Dox: http://dlang.org/phobos-prerelease/std_benchmark.html
> 
> There are a few enhancement possibilities (such as tracking
> system/user time separately etc), but there is value in keeping
> things simple and convenient. Right now it really takes only one
> line of code and observing a simple naming convention to hook a
> module into the benchmarking framework.
> 
> Looking for a review manager!

I'd like to organize the review.
If that's fine with you I'll post the announcement in a separate thread.

Jens


Review of Andrei's std.benchmark

2012-09-17 Thread Jens Mueller
Hi,

it's my pleasure to announce the begin of the formal review of Andrei's
std.benchmark. The review will start today and end in two weeks, on 1st
of October. The review is followed by a week of voting which ends on 8th
of October.

Quoting Andrei from his request for formal review:
"I reworked the benchmarking framework for backward compatibility,
flexibility, and convenience.

There are a few enhancement possibilities (such as tracking
system/user time separately etc), but there is value in keeping things
simple and convenient. Right now it really takes only one line of code
and observing a simple naming convention to hook a module into the
benchmarking framework."

Code: https://github.com/D-Programming-Language/phobos/pull/794
Docs: http://dlang.org/phobos-prerelease/std_benchmark.html

If std.benchmark is accepted it will likely lead to a deprecation of
std.datetime's benchmark facilities.

The code is provided as a pull requested and being (as usual) integrated
by the auto tester for Mac OS X, FreeBSD, Linux and Windows (see
(http://d.puremagic.com/test-results/pull-history.ghtml?repoid=3&pullid=794).

In your comments you can/should address the
* design
* implementation
* documentation
* usefulness
of the library.

Provide information regarding the depth (ranging from very brief to
in-depth) of your review and conclude explicitly whether std.benchmark
should or shouldn't be included in Phobos.

Post all feedback to this thread. Constructive feedback is very much
appreciated.

To conclude in more Andrei like words: Happy destruction!

Jens


Re: Weird Link Error

2012-09-20 Thread Jens Mueller
Daniel wrote:
> I have searched everywhere and I can't find anything so I decided to
> come here. I have a simple Hello World program in the file Test.d,
> it compiles just fine but when I try this...

Can you attach the Test.d?
But it looks like you didn't define a main function.

> [daniel@arch D]$ dmd Test.o
> /usr/lib/libphobos2.a(dmain2_459_1a5.o): In function
> `_D2rt6dmain24mainUiPPaZi7runMainMFZv':
> (.text._D2rt6dmain24mainUiPPaZi7runMainMFZv+0x10): undefined
> reference to `_Dmain'
> /usr/lib/libphobos2.a(deh2_43b_525.o): In function
> `_D2rt4deh213__eh_finddataFPvZPS2rt4deh29FuncTable':
> (.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh29FuncTable+0x4):
> undefined reference to `_deh_beg'
> /usr/lib/libphobos2.a(deh2_43b_525.o): In function
> `_D2rt4deh213__eh_finddataFPvZPS2rt4deh29FuncTable':
> (.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh29FuncTable+0xc):
> undefined reference to `_deh_beg'
> /usr/lib/libphobos2.a(deh2_43b_525.o): In function
> `_D2rt4deh213__eh_finddataFPvZPS2rt4deh29FuncTable':
> (.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh29FuncTable+0x13):
> undefined reference to `_deh_end'
> /usr/lib/libphobos2.a(deh2_43b_525.o): In function
> `_D2rt4deh213__eh_finddataFPvZPS2rt4deh29FuncTable':
> (.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh29FuncTable+0x36):
> undefined reference to `_deh_end'
> /usr/lib/libphobos2.a(thread_18f_1b8.o): In function
> `_D4core6thread6Thread6__ctorMFZC4core6thread6Thread':
> (.text._D4core6thread6Thread6__ctorMFZC4core6thread6Thread+0x1d):
> undefined reference to `_tlsend'
> /usr/lib/libphobos2.a(thread_18f_1b8.o): In function
> `_D4core6thread6Thread6__ctorMFZC4core6thread6Thread':
> (.text._D4core6thread6Thread6__ctorMFZC4core6thread6Thread+0x24):
> undefined reference to `_tlsstart'
> /usr/lib/libphobos2.a(thread_19f_6e4.o): In function
> `thread_attachThis':
> (.text.thread_attachThis+0xb7): undefined reference to `_tlsstart'
> /usr/lib/libphobos2.a(thread_19f_6e4.o): In function
> `thread_attachThis':
> (.text.thread_attachThis+0xbc): undefined reference to `_tlsend'
> /usr/lib/libphobos2.a(thread_17d_1b8.o): In function
> `_D4core6thread6Thread6__ctorMFPFZvkZC4core6thread6Thread':
> (.text._D4core6thread6Thread6__ctorMFPFZvkZC4core6thread6Thread+0x1d):
> undefined reference to `_tlsend'
> /usr/lib/libphobos2.a(thread_17d_1b8.o): In function
> `_D4core6thread6Thread6__ctorMFPFZvkZC4core6thread6Thread':
> (.text._D4core6thread6Thread6__ctorMFPFZvkZC4core6thread6Thread+0x27):
> undefined reference to `_tlsstart'
> /usr/lib/libphobos2.a(thread_17e_1b8.o): In function
> `_D4core6thread6Thread6__ctorMFDFZvkZC4core6thread6Thread':
> (.text._D4core6thread6Thread6__ctorMFDFZvkZC4core6thread6Thread+0x1d):
> undefined reference to `_tlsend'
> /usr/lib/libphobos2.a(thread_17e_1b8.o): In function
> `_D4core6thread6Thread6__ctorMFDFZvkZC4core6thread6Thread':
> (.text._D4core6thread6Thread6__ctorMFDFZvkZC4core6thread6Thread+0x27):
> undefined reference to `_tlsstart'
> /usr/lib/libphobos2.a(thread_17a_713.o): In function
> `thread_entryPoint':
> (.text.thread_entryPoint+0x64): undefined reference to `_tlsend'
> /usr/lib/libphobos2.a(thread_17a_713.o): In function
> `thread_entryPoint':
> (.text.thread_entryPoint+0x6a): undefined reference to `_tlsstart'
> collect2: error: ld returned 1 exit status
> --- errorlevel 1
> 
> I would try to solve the problem myself, except that I have no clue
> wtf this means.

These are linker errors. Just read the first two line:

> /usr/lib/libphobos2.a(dmain2_459_1a5.o): In function
> `_D2rt6dmain24mainUiPPaZi7runMainMFZv':
> (.text._D2rt6dmain24mainUiPPaZi7runMainMFZv+0x10): undefined
> reference to `_Dmain'

The linker looks for a D main function since it is referenced in the
function with mangled name _D2rt6dmain24mainUiPPaZi7runMainMFZv. But
it cannot find it (i.e. the reference is undefined) you'll get this
error and subsequent errors.

Jens


Re: Extending unittests [proposal] [Proof Of Concept]

2012-09-20 Thread Jens Mueller
Johannes Pfau wrote:
> Current situation:
> The compiler combines all unittests of a module into one huge function.
> If a unittest in a module fails, the rest won't be executed. The
> runtime (which is responsible for calling that per module unittest
> method) must always run all unittests of a module.
> 
> Goal:
> The runtime / test runner can decide for every test if it wants to
> continue testing or abort. It should also be possible to run single
> tests and skip some tests. As a secondary goal the runtime should
> receive the filename and line number of the unittest declaration.
> 
> Proposal:
> Introduce a new 'MInewunitTest' ModuleInfo flag in object.d and in the
> compiler. If MInewunitTest is present, the moduleinfo does not contain
> a unittester function. Instead it contains an array (slice) of UnitTest
> structs. So the new module property looks like this:
> 
> @property UnitTest[] unitTest() nothrow pure;
> 
> 
> the UnitTest struct looks like this:
> 
> struct UnitTest
> {
>string name; //Not used yet
>string fileName;
>uint line;
>void function() testFunc;
> }
> 
> 
> The compiler generates a static array of all UnitTest objects for every
> module and sets the UnitTest[] slice in the moduleinfo to point to this
> static array. As the compiler already contains individual functions for
> every unittest, this isn't too difficult.
> 
> 
> Proof of Concept:
> I haven't done any dmd hacking before so this might be terrible code,
> but it is working as expected and can be used as a guide on how to
> implement this:
> https://github.com/jpf91/druntime/compare/newUnittest
> https://github.com/jpf91/dmd/compare/newUnittest
> 
> In this POC the MInewunitTest flag is not present yet, the new method
> is always used. Also the implementation in druntime is only minimally
> changed. The compiler changes allow an advanced testrunner to do a lot
> more:
> 
> * Be a GUI tool / use colored output / ...
> * Allow to run single, specific tests, skip tests, ...
> * Execute tests in a different process, communicate with IPC. This way
>   we can deal with segmentation faults in unit tests.

Very recently I have polished a tool I wrote called dtest.
http://jkm.github.com/dtest/dtest.html
And the single thing I want to support but failed to implement is
calling individual unittests. I looked into it. I thought I could find a
way to inspect the assembly with some C library. But I couldn't make it
work. Currently each module has a __modtest which calls the unittests.

I haven't looked into segmentation faults but I think you can handle
them already currently. You just need to provide your own segmentation
fault handler. I should add this to dtest. dtest also let's you continue
executing the tests if an assertion fails and it can turn failures into
break points. When you use GNU ld you can even continue and break on any
thrown Throwable.

In summary I think everything can be done already but not on an
individual unittest level. But I also think that this is important and
this restriction alone is enough to merge your pull request after a
review.
But the changes should be backward compatible. I think there is no need
to make the runtime more complex. Just let it execute the single
function __modtest as it was but add the array of unittests. I'd be
happy to extend dtest to use this array because I found no different
solution.

> Sample output:
> Testing generated/linux/debug/32/unittest/std/array
> std/array.d:86  SUCCESS
> std/array.d:145 SUCCESS
> std/array.d:183 SUCCESS
> std/array.d:200 SUCCESS
> std/array.d:231 SUCCESS
> std/array.d:252 SUCCESS
> std/array.d:317 SUCCESS

See
https://buildhive.cloudbees.com/job/jkm/job/dtest/16/console
for dtest's output.
$ ./dtest --output=xml
Testing 1 modules: ["dtest_unittest"]
== Run 1 of 1 ==
PASS dtest_unittest

All modules passed: ["dtest_unittest"]

This also generates a JUnit/GTest-compatible XML report.

Executing ./failing gives more interesting output:
$ ./failing --abort=asserts
Testing 3 modules: ["exception", "fail", "pass"]
== Run 1 of 1 ==
FAIL exception
object.Exception@tests/exception.d(3): first exception
object.Exception@tests/exception.d(4): second exception
FAIL fail
core.exception.AssertError@fail(5): unittest failure
PASS pass

Failed modules (2 of 3): ["exception", "fail"]

I also found some inconsistency in the output when asserts have no
message. It'll be nice if that could be fixed too.
http://d.puremagic.com/issues/show_bug.cgi?id=8652

> The perfect solution:
> Would allow user defined attributes on tests, so you could name them,
> assign categories, etc. But till we have those user defined attributes,
> this seems to be a good solution.

This is orthogonal to your proposal. You just want that every unittest
is exposed as a function. How to define attributes for functions is a
different story.

Jens


Re: Extending unittests [proposal] [Proof Of Concept]

2012-09-20 Thread Jens Mueller
Jonathan M Davis wrote:
> On Thursday, September 20, 2012 18:53:38 Johannes Pfau wrote:
> > Proposal:
> [snip]
> 
> In general, I'm all for instrumenting druntime such that unit testing tools 
> could run unit tests individually and present their output in a customized 
> manner, just so long as it doesn't really change how unit tests work now as 
> far as compiling with -unittest and running your program goes. The only 
> change 
> that might be desirable would be making it so that after a unittest block 
> fails, subsequent unittest blocks within its module are still run.
> 
> I _would_ point out that running any unittest blocks in a function without 
> running every other unittest block before them is error prone (running 
> further 
> unittet blocks after a failure is risky enough). Last time I used JUnit, even 
> though it claimed to run unitests individually and tell you the result, it 
> didn't really. It might have not run all of the unit tests after the one you 
> asked for, but it still ran all of the ones before it. Not doing so would be 
> p 
> problem in any situation where one unit test affects state that further unit 
> tests use (much as that's arguably bad practice).

You say that JUnit silently runs all unittests before the first
specified one, don't you? If that is done silently that's indeed
strange.
When to abort the execution of a unittest or all unittests of a module
is indeed a delicate question. But even though there is a strong default
to abort in case of any failure I see merit of allowing the user to
change this behavior on demand.

> Regardless, I confess that I don't care too much about the details of how 
> this 
> sort of thing is done so long as it doesn't really change how they work from 
> the standpoint of compiling with -unittest and running your executable. The 
> _one_ feature that I really wish we had was the ability to name unit tests, 
> since then you'd get a decent name in stack traces, but the fact that the 
> pull 
> request which makes it so that unittest block functions are named after their 
> line number has finally been merged in makes that less of an issue.

When has this been merged? It must have been after v2.060 was released.
Because I noticed some number at the end of the unittest function names.
But it was not the line number.

Jens


CTFE calling a template: Error: expression ... is not a valid template value argument

2012-09-20 Thread Jens Mueller
Hi,

I do not understand the following error message given the code:

string foo(string f)
{
if (f == "somestring")
{
return "got somestring";
}
return bar!(foo("somestring"));
}

template bar(string s)
{
enum bar = s;
}

I'll with dmd v2.060 get:
test.d(7):called from here: foo("somestring")
test.d(7):called from here: foo("somestring")
test.d(7):called from here: foo("somestring")
test.d(7): Error: expression foo("somestring") is not a valid template value 
argument
test.d(12):called from here: foo("somestring")
test.d(12):called from here: foo("somestring")
test.d(7): Error: template instance test.bar!(foo("somestring")) error 
instantiating

In line 7 I call the template bar. But I call with the string that is
returned by the CTFE of foo("somestring") which should return "got
somestring" but instead it seems that an expression is passed. How do I
force the evaluation foo("somestring")?
I haven't found a bug on this.

Jens


Re: Extending unittests [proposal] [Proof Of Concept]

2012-09-20 Thread Jens Mueller
Jonathan M Davis wrote:
> On Thursday, September 20, 2012 22:55:23 Jens Mueller wrote:
> > You say that JUnit silently runs all unittests before the first
> > specified one, don't you?
> 
> Yes. At least, that was its behavior the last time that I used it (which was 
> admittedly a few years ago).
> 
> > If that is done silently that's indeed strange.
> 
> It could have been a quirk of their implementation, but I expect that it's to 
> avoid issues where a unit test relies on previous unit tests in the same 
> file. 
> If your unit testing functions (or unittest blocks in the case of D) have 
> _any_ dependencies on external state, then skipping any of them affects the 
> ones that you don't skip, possibly changing the result of the unit test (be 
> it 
> to success or failure).
> 
> Running more unittest blocks after a failure is similarly flawed, but at 
> least 
> in that case, you know that had a failure earlier in the module, which should 
> then tell you that you may not be able to trust further tests (but if you 
> still run them, it's at least then potentially possible to fix further 
> failures 
> at the same time - particularly if your tests don't rely on external state). 
> So, while not necessarily a great idea, it's not as bad to run subsequent 
> unittest blocks after a failure (especially if programmers are doing what 
> they're supposed to and making their unit tests independent).
> 
> However, what's truly insane IMHO is continuing to run a unittest block after 
> it's already had a failure in it. Unless you have exceedingly simplistic unit 
> tests, the failures after the first one mean pretty much _nothing_ and simply 
> clutter the results.

I sometimes have unittests like

assert(testProperty1());
assert(testProperty2());
assert(testProperty3());

And in these cases it will be useful if I got all of the assertion
failures. But you are very right that you should use it with very much
care and knowing what you do. You may even get lost not seeing the
actual problem because of so many subsequent failures.

> > When has this been merged? It must have been after v2.060 was released.
> > Because I noticed some number at the end of the unittest function names.
> > But it was not the line number.
> 
> A couple of weeks ago IIRC. I'm pretty sure that it was after 2.060 was 
> released.

I just checked.
It was merged in on Wed Sep 5 19:46:50 2012 -0700 (commit d3669f79813)
and v2.060 was released 2nd of August.
Meaning I could try calling these functions myself now that I know their
names.

Jens


Re: CTFE calling a template: Error: expression ... is not a valid template value argument

2012-09-20 Thread Jens Mueller
Simen Kjaeraas wrote:
> On Thu, 20 Sep 2012 23:22:36 +0200, Jens Mueller
>  wrote:
> 
> >string foo(string f)
> >{
> >if (f == "somestring")
> >{
> >return "got somestring";
> >}
> >return bar!(foo("somestring"));
> >}
> >
> >template bar(string s)
> >{
> >enum bar = s;
> >}
> 
> >In line 7 I call the template bar. But I call with the string that is
> >returned by the CTFE of foo("somestring") which should return "got
> >somestring"
> 
> When's it gonna get around to doing that? In order to figure out the
> return value of foo("somestring"), it will have to figure out the
> return value of foo("somestring"), and to do that...

There is no endless recursion. Note that foo("somestring") returns "got
somestring".
Am I wrong?

Jens


Re: CTFE calling a template: Error: expression ... is not a valid template value argument

2012-09-20 Thread Jens Mueller
Jonathan M Davis wrote:
> On Thursday, September 20, 2012 23:22:36 Jens Mueller wrote:
> > Hi,
> > 
> > I do not understand the following error message given the code:
> > 
> > string foo(string f)
> > {
> > if (f == "somestring")
> > {
> > return "got somestring";
> > }
> > return bar!(foo("somestring"));
> > }
> > 
> > template bar(string s)
> > {
> > enum bar = s;
> > }
> > 
> > I'll with dmd v2.060 get:
> > test.d(7): called from here: foo("somestring")
> > test.d(7): called from here: foo("somestring")
> > test.d(7): called from here: foo("somestring")
> > test.d(7): Error: expression foo("somestring") is not a valid template value
> > argument test.d(12): called from here: foo("somestring")
> > test.d(12): called from here: foo("somestring")
> > test.d(7): Error: template instance test.bar!(foo("somestring")) error
> > instantiating
> > 
> > In line 7 I call the template bar. But I call with the string that is
> > returned by the CTFE of foo("somestring") which should return "got
> > somestring" but instead it seems that an expression is passed. How do I
> > force the evaluation foo("somestring")?
> > I haven't found a bug on this.
> 
> Template arguments must be known at compile time. And even if you use foo at 
> compile time, it has to be compiled before you use it, so you can't call it 
> inside itself and pass that as a template argument. foo must be fully 
> compiled 
> before it can be called, and as it stands, it can't be fully compiled until 
> it's called. So... Yeah. Not going to work.

I thought foo is interpreted at compile time.
There seems to be a subtle difference I'm not getting.
Because you can do the factorial using CTFE even though you have
recursion. I.e. there you have a call to the function itself. I.e. it
can be compiled because you just insert a call to the function. But for
a template you cannot issue something like call for instantiation.
Have to think more about it. But your answer helps a lot. Pushes me in
the right direction.

Jens


Re: CTFE calling a template: Error: expression ... is not a valid template value argument

2012-09-21 Thread Jens Mueller
Jonathan M Davis wrote:
> On Friday, September 21, 2012 00:11:51 Jens Mueller wrote:
> > I thought foo is interpreted at compile time.
> > There seems to be a subtle difference I'm not getting.
> > Because you can do the factorial using CTFE even though you have
> > recursion. I.e. there you have a call to the function itself. I.e. it
> > can be compiled because you just insert a call to the function. But for
> > a template you cannot issue something like call for instantiation.
> > Have to think more about it. But your answer helps a lot. Pushes me in
> > the right direction.
> 
> Okay. Straight up recursion works. So, with this code
> 
> int func(int value)
> {
>  if(value < 10)
>  return func(value + 1);
>  return value;
> }
> 
> enum var = func(5);
> 
> var would be 10. The problem is that you're trying to pass the result of a 
> recursive call as a template argument. As far as a function's behavior goes, 
> it's identical regardless of whether it's run at compile time or runtime 
> (save 
> that __ctfe is true at compile time but not runtime). To quote the docs:
> 
> --
> Any func­tions that ex­e­cute at com­pile time must also be ex­e­cutable at 
> run time. The com­pile time eval­u­a­tion of a func­tion does the 
> equiv­a­lent 
> of run­ning the func­tion at run time. This means that the se­man­tics of a 
> func­tion can­not de­pend on com­pile time val­ues of the func­tion. For ex­
> am­ple:
> 
> int foo(char[] s) {
>  return mixin(s);
> }
> 
> const int x = foo("1");
> 
> is il­le­gal, be­cause the run­time code for foo() can­not be gen­er­ated. A 
> func­tion tem­plate would be the ap­pro­pri­ate method to im­ple­ment this 
> sort of thing.
> --

Is it also illegal to do

int foo(char[] s) {
  if (__ctfe)
return mixin(s);
  else
return ""; // or assert(false)
}

?

Because this is executable at run time.

> You're doing something very similar to passing a function argument to a mixin 
> statement, but in this case, it's passing the result of calling a function 
> which doesn't exist yet (since it hasn't been fully compiled) to a template.
> 
> In order for your foo function to be called, it must be fully compiled first 
> (including its entire body, since CTFE needs the full definition of the 
> function, not just its signature). The body cannot be fully compiled until 
> the 
> template that it's using is instantiated. But that template can't be compiled 
> until foo has been compiled, because you're passing a call to foo to it as a 
> template argument. So, you have a circular dependency.

I see. That's is clear to me now. Thanks.

> Normal recursion avoids this, because it only depends on the function's 
> signature, but what you're doing requires that the function be _run_ as part 
> of the process of defining it. That's an unbreakable circular dependency and 
> will never work. You need to redesign your code so that you don't require a 
> function to call itself while it's being defined. Being called at compile 
> time 
> is fine, but being called while it's being compiled is not.

But if the function wasn't compiled but interpreted at compile time it
would be possible, wouldn't it?

Jens


Re: GDC Explorer - an online disassembler for D

2012-09-21 Thread Jens Mueller
Andrei Alexandrescu wrote:
> I've met Matt Goldbolt, the author of the GCC Explorer at
> http://gcc.godbolt.org - a very handy online disassembler for GCC.

This is not a disassembler. It just stops compilation before the
assembler (gcc -S). A dissembler would create the assembler code given
only the machine code.
But it's nice to have source code and assembly side by side.

Jens


Re: CTFE calling a template: Error: expression ... is not a valid template value argument

2012-09-21 Thread Jens Mueller
Jens Mueller wrote:
> Jonathan M Davis wrote:
> > On Friday, September 21, 2012 00:11:51 Jens Mueller wrote:
> > > I thought foo is interpreted at compile time.
> > > There seems to be a subtle difference I'm not getting.
> > > Because you can do the factorial using CTFE even though you have
> > > recursion. I.e. there you have a call to the function itself. I.e. it
> > > can be compiled because you just insert a call to the function. But for
> > > a template you cannot issue something like call for instantiation.
> > > Have to think more about it. But your answer helps a lot. Pushes me in
> > > the right direction.
> > 
> > Okay. Straight up recursion works. So, with this code
> > 
> > int func(int value)
> > {
> >  if(value < 10)
> >  return func(value + 1);
> >  return value;
> > }
> > 
> > enum var = func(5);
> > 
> > var would be 10. The problem is that you're trying to pass the result of a 
> > recursive call as a template argument. As far as a function's behavior 
> > goes, 
> > it's identical regardless of whether it's run at compile time or runtime 
> > (save 
> > that __ctfe is true at compile time but not runtime). To quote the docs:
> > 
> > --
> > Any func­tions that ex­e­cute at com­pile time must also be ex­e­cutable at 
> > run time. The com­pile time eval­u­a­tion of a func­tion does the 
> > equiv­a­lent 
> > of run­ning the func­tion at run time. This means that the se­man­tics of a 
> > func­tion can­not de­pend on com­pile time val­ues of the func­tion. For ex­
> > am­ple:
> > 
> > int foo(char[] s) {
> >  return mixin(s);
> > }
> > 
> > const int x = foo("1");
> > 
> > is il­le­gal, be­cause the run­time code for foo() can­not be gen­er­ated. 
> > A 
> > func­tion tem­plate would be the ap­pro­pri­ate method to im­ple­ment this 
> > sort of thing.
> > --
> 
> Is it also illegal to do
> 
> int foo(char[] s) {
>   if (__ctfe)
> return mixin(s);
>   else
> return ""; // or assert(false)
> }
> 
> ?
> 
> Because this is executable at run time.

Just read the docs again. And __ctfe is used to exclude running code at
runtime. It seems it really is a variable that is false at runtime. I
thought it more a value known at compile time. But then you would write
static if anyway.

Somehow I find these restrictions unnecessary. I believe they can be
solved. Then you could combine CTFE with all other compile-time
mechanisms. But this needs more time to think about. Currently I will
try to work around this. Let's see ...

Jens


Re: CTFE calling a template: Error: expression ... is not a valid template value argument

2012-09-21 Thread Jens Mueller
Timon Gehr wrote:
> On 09/20/2012 11:22 PM, Jens Mueller wrote:
> >Hi,
> >
> >I do not understand the following error message given the code:
> >
> >string foo(string f)
> >{
> > if (f == "somestring")
> > {
> > return "got somestring";
> > }
> > return bar!(foo("somestring"));
> >}
> >
> >template bar(string s)
> >{
> > enum bar = s;
> >}
> >
> >I'll with dmd v2.060 get:
> >test.d(7):called from here: foo("somestring")
> >test.d(7):called from here: foo("somestring")
> >test.d(7):called from here: foo("somestring")
> >test.d(7): Error: expression foo("somestring") is not a valid template value 
> >argument
> >test.d(12):called from here: foo("somestring")
> >test.d(12):called from here: foo("somestring")
> >test.d(7): Error: template instance test.bar!(foo("somestring")) error 
> >instantiating
> >
> >In line 7 I call the template bar. But I call with the string that is
> >returned by the CTFE of foo("somestring") which should return "got
> >somestring" but instead it seems that an expression is passed. How do I
> >force the evaluation foo("somestring")?
> >I haven't found a bug on this.
> >
> >Jens
> >
> 
> You can file a diagnostics-bug.
> 
> The issue is that CTFE can only interpret functions that are fully
> analyzed and therefore the analysis of foo depends circularly on
> itself. The compiler should spit out an error that indicates the
> issue.

That is true. I will file such a diagnostics bug with low priority.

> You could post an enhancement request to allow interpretation of
> incompletely-analyzed functions, if you think it is of any use.

I think it is.
What do you think?

Jens


Re: GDC Explorer - an online disassembler for D

2012-09-21 Thread Jens Mueller
Iain Buclaw wrote:
> On 21 September 2012 11:29, Iain Buclaw  wrote:
> > On 21 September 2012 11:17, Bernard Helyer  wrote:
> >> On Friday, 21 September 2012 at 10:04:00 UTC, Jens Mueller wrote:
> >>>
> >>> Andrei Alexandrescu wrote:
> >>>>
> >>>> I've met Matt Goldbolt, the author of the GCC Explorer at
> >>>> http://gcc.godbolt.org - a very handy online disassembler for GCC.
> >>>
> >>>
> >>> This is not a disassembler. It just stops compilation before the
> >>> assembler (gcc -S). A dissembler would create the assembler code given
> >>> only the machine code.
> >>
> >>
> >> You are both correct and incredibly pedantic. :P
> >
> > Half correct and incredibly pedantic. :-)
> >
> > There's two modes.  One is assembler output, the other is objdump
> > output (which is a disassembler).
> >
> 
> And if it doesn't then I must be incredibly confused at this hour in
> the morning (yawns).

How do I use the objdump mode in the web interface?

Jens


Re: Extending unittests [proposal] [Proof Of Concept]

2012-09-21 Thread Jens Mueller
Johannes Pfau wrote:
> Am Fri, 21 Sep 2012 11:11:49 +0200
> schrieb Jacob Carlborg :
> 
> > On 2012-09-20 21:11, Johannes Pfau wrote:
> > 
> > > Oh right, I thought that interface was more restrictive. So the only
> > > changes necessary in druntime are to adapt to the new compiler
> > > interface.
> > >
> > > The new dmd code is still necessary, as it allows to access
> > > all unittests of a module individually. The current code only
> > > provides one function for all unittests in a module.
> > 
> > Yes, exactly. There where some additional data, like file and module 
> > name as well in your compiler changes?
> > 
> 
> The modulename can already be obtained from the moduleinfo. My proposal
> adds fileName and line information for every unittest. It's also
> prepared for unittest names: The name information is passed to the
> runtime, but currently it's always an empty string.

Why do you need filename and line information of a unittest. If a
unittest fails you'll get the relevant information. Why do you want the
information when a unittest succeeded? I only care about failed
unittests. A count of the number of executed unittests and total number
is enough, I think.

Jens


Re: Extending unittests [proposal] [Proof Of Concept]

2012-09-21 Thread Jens Mueller
Jacob Carlborg wrote:
> On 2012-09-21 14:19, Jens Mueller wrote:
> 
> >Why do you need filename and line information of a unittest. If a
> >unittest fails you'll get the relevant information. Why do you want the
> >information when a unittest succeeded? I only care about failed
> >unittests. A count of the number of executed unittests and total number
> >is enough, I think.
> 
> But others might care about other things. I doesn't hurt if the
> information is available. There might be use cases when one would
> want to display all tests regardless of if they failed or not.

If there are use cases I agree. I do not know one.
The question whether there are *tools* that report in case of success is
easier to verify. Do you know any tool that does reporting in case
success? I think gtest does not do it. I'm not sure about JUnit.
But of course if a unittest has additional information and that is
already implemented or easy to implement fine with me. My point is more
that for the common cases you do not need this. Maybe in most. Maybe in
all.

Jens


Re: Extending unittests [proposal] [Proof Of Concept]

2012-09-21 Thread Jens Mueller
Johannes Pfau wrote:
> Am Fri, 21 Sep 2012 16:37:37 +0200
> schrieb Jens Mueller :
> 
> > Jacob Carlborg wrote:
> > > On 2012-09-21 14:19, Jens Mueller wrote:
> > > 
> > > >Why do you need filename and line information of a unittest. If a
> > > >unittest fails you'll get the relevant information. Why do you
> 
> With the recent name mangling change it's possible to get the unittest
> line if a test fails, but only if you have working backtraces. That
> might not be true for other compilers / non x86 architectures.
> 
> To get the filename you have to demangle the unittest function name
> (IIRC core.demangle can't even demangle that name right now) and this
> only gives you the module name (which you could also get using
> moduleinfo though)

I'm saying I do not care which unittest succeeded. All I need that all
unittest I ran where successfully executed.

> It's also useful for disabled tests, so you can actually look them up.

That may be useful. So you say these tests where disabled instead of
just 2 tests where disabled.

> > > >want the information when a unittest succeeded? I only care about
> > > >failed unittests. A count of the number of executed unittests and
> > > >total number is enough, I think.
> 
> The posted example shows everything that can be done, even if it might
> not make sense. However printing successful tests also has a use case:
> 
> 1: It shows the progress of unit testing. (Not so important)
> 2: If code crashes and doesn't produce a backtrace, you still now which
> test crashed as the file name and line number are printed before
> running the test. (might sound unprobable. But try porting gdc to a new
> architecture. I don't want to waste time anymore commenting out
> unit tests to find the failing one in a file with dozens of tests and
> an ARM machine that takes ages to run the tests)

Why don't you get report when the program crashes?

> Another use case is printing all unittests in a library. Or a gui app
> displaying all unittests, allowing to only run single unittests, etc.

Listing on a unittest level and selecting may be useful.

> > > But others might care about other things. I doesn't hurt if the
> > > information is available. There might be use cases when one would
> > > want to display all tests regardless of if they failed or not.
> > 
> > If there are use cases I agree. I do not know one.
> > The question whether there are *tools* that report in case of success
> > is easier to verify. Do you know any tool that does reporting in case
> > success? I think gtest does not do it. I'm not sure about JUnit.
> 
> I don't know those tools, but I guess they have some sort of progress
> indicator?

They have them at test case level. I'm not sure whether there is a
strict relation between unittest and test case for D. The module level
may be enough.

> But I remember some .NET unit test GUIs that showed a green button for
> successful tests. But it's been years since I've done anything in .NET.
> 
> > But of course if a unittest has additional information and that is
> > already implemented or easy to implement fine with me. My point is
> > more that for the common cases you do not need this. Maybe in most.
> > Maybe in all.
> 
> You usually don't have to print sucessful tests (although sometimes I
> wasn't sure if tests actually run), but as you can't know at compile
> time which tests fail you either have this information for all tests or
> for none.

But you could just count the number and report it. If it says
"testing std.algorithm with 134 of 134 unittest"
you know all have been executed. What is true it won't tell you which
unittests were disabled. But that is easy to find out.

> The main reason _I_ want this is for gdc: We currently don't run the
> unit tests on gdc at all. I know they won't pass on ARM. But the unit
> tests error out on the first failing test. Often that error is a
> difficult to fix backend bug, and lots of simpler library bugs are
> hidden because the other tests aren't executed.

But this is a different problem. You want to keep executing on failure.
You don't need a unittest name for this. Maybe you say skipping a
failing unittest is better and disabling them in the source using
@disable is tedious.

> I'm actually kinda surprised the feedback on this is rather negative. I
> thought running unit tests individually and printing line/file/name was
> requested quite often?

Running unittests individually is very useful. But I'm not so sure about
the latter. I think driving the execution of how to execute the
unittests is important. Not so much reporting listing single unittests.
But I won't object when you add this feature if you believe it will be
used. Just saying I have less use for it. And if the change is simple
it should be unlikely to introduce any bugs.

Jens


Re: Extending unittests [proposal] [Proof Of Concept]

2012-09-21 Thread Jens Mueller
Jacob Carlborg wrote:
> On 2012-09-21 16:37, Jens Mueller wrote:
> 
> >If there are use cases I agree. I do not know one.
> >The question whether there are *tools* that report in case of success is
> >easier to verify. Do you know any tool that does reporting in case
> >success? I think gtest does not do it. I'm not sure about JUnit.
> >But of course if a unittest has additional information and that is
> >already implemented or easy to implement fine with me. My point is more
> >that for the common cases you do not need this. Maybe in most. Maybe in
> >all.
> 
> Test::Unit, the default testing framework for Ruby on Rails prints a
> dot for each successful test.

That is fine. But you don't need the name of the unittest then.

Jens


Re: Extending unittests [proposal] [Proof Of Concept]

2012-09-21 Thread Jens Mueller
Tobias Pankrath wrote:
> 
> >I'm actually kinda surprised the feedback on this is rather
> >negative. I
> >thought running unit tests individually and printing
> >line/file/name was
> >requested quite often?
> 
> I want to have this. My workflow is: Run all tests0(run all). If
> some fail, see if there might be a common reason (so don't stop).
> Than run the unit tests that will most likely tell you what's wrong
> in a debugger (run one test individually).

Though dtest is in an early state, you can
do:
$ ./dtest --abort=no

runs all unittests and report each failure, i.e. it continues in case of
a failure instead of aborting.

Then run:
$ ./dtest --abort=no --break=both
to turn all failures into breakpoints.
What is true that you cannot pick here an individual unittest. But you
can continue in the debugger though this may have its problems. But
running them individually may have problems too if the unittests are
not written to be executed independently.

Jens


Re: Extending unittests [proposal] [Proof Of Concept]

2012-09-21 Thread Jens Mueller
Jacob Carlborg wrote:
> On 2012-09-21 20:01, Johannes Pfau wrote:
> 
> >I didn't think of setAssertHandler. My changes are perfectly compatible
> >with it.
> >IIRC setAssertHandler has the small downside that it's used for all
> >asserts, not only those used in unit tests? I'm not sure if that's a
> >drawback or actually useful.
> 
> That's no problem, there's a predefined version, "unittest", when
> you pass the -unittest flag to the compiler:
> 
> version (unittest)
> setAssertHandler(myUnitTestSpecificAssertHandler);

But if you have an assert in some algorithm to ensure some invariant or
in a contract it will be handled by myUnitTestSpecificAssertHandler.
But I think that is not a drawback. Don't you want to no whenever an
assert is violated?

Jens


Re: Extending unittests [proposal] [Proof Of Concept]

2012-09-21 Thread Jens Mueller
David Piepgrass wrote:
> >However, what's truly insane IMHO is continuing to run a unittest
> >block after
> >it's already had a failure in it. Unless you have exceedingly
> >simplistic unit
> >tests, the failures after the first one mean pretty much _nothing_
> >and simply
> >clutter the results.
> 
> I disagree. Not only are my unit tests independent (so of course the
> test runner should keep running tests after one fails) but often I
> do want to keep running after a failure.
> 
> I like the BOOST unit test library's approach, which has two types
> of "assert": BOOST_CHECK and BOOST_REQUIRE. After a BOOST_CHECK
> fails, the test keeps running, but BOOST_REQUIRE throws an exception
> to stop the test. When testing a series of inputs in a loop, it is
> useful (for debugging) to see the complete set of which ones succeed
> and which ones fail. For this feature (continuation) to be really
> useful though, it needs to be able to output context information on
> failure (e.g. "during iteration 13 of input group B").

This leads us to the distinction of exceptions and errors. It is safe to
catch exceptions but less so for errors. At least it is far more
dangerous and less advised to continue execution but should not be
prohibited I think.

Jens


Re: GDC Explorer - an online disassembler for D

2012-09-21 Thread Jens Mueller
Ellery Newcomer wrote:
> On 09/21/2012 03:04 AM, Jens Mueller wrote:
> >But it's nice to have source code and assembly side by side.
> >
> >Jens
> >
> 
> And very nice to have demangled names in assembly.

You can pipe your assembly code to ddemangle if there is some other tool
that missing demangling. I did this for example when I looked at output
from a statistical profiler.

Jens


Re: Review of Andrei's std.benchmark

2012-09-21 Thread Jens Mueller
Andrei Alexandrescu wrote:
> On 9/21/12 5:39 AM, Jacob Carlborg wrote:
> >On 2012-09-21 06:23, Andrei Alexandrescu wrote:
> >
> >>For a very simple reason: unless the algorithm under benchmark is very
> >>long-running, max is completely useless, and it ruins average as well.
> >
> >I may have completely misunderstood this but aren't we talking about
> >what do include in the output of the benchmark? In that case, if you
> >don't like max and average just don't look at it.
> 
> I disagree. I won't include something in my design just so people
> don't look at it most of the time. Min and average are most of the
> time an awful thing to include, and will throw off people with
> bizarre results.
> 
> If it's there, it's worth looking at. Note how all columns are
> directly comparable (I might add, unlike other approaches to
> benchmarking).
> 
> >>For virtually all benchmarks I've run, the distribution of timings is a
> >>half-Gaussian very concentrated around the minimum. Say you have a
> >>minimum of e.g. 73 us. Then there would be a lot of results close to
> >>that; the mode of the distribution would be very close, e.g. 75 us, and
> >>the more measurements you take, the closer the mode is to the minimum.
> >>Then you have a few timings up to e.g. 90 us. And finally you will
> >>inevitably have a few outliers at some milliseconds. Those are orders of
> >>magnitude larger than anything of interest and are caused by system
> >>interrupts that happened to fall in the middle of the measurement.
> >>
> >>Taking those into consideration and computing the average with those
> >>outliers simply brings useless noise into the measurement process.
> >
> >After your replay to one of Manu's post, I think I misunderstood the
> >std.benchmark module. I was thinking more of profiling. But are these
> >quite similar tasks, couldn't std.benchmark work for both?
> 
> This is an interesting idea. It would delay release quite a bit
> because I'd need to design and implement things like performance
> counters and such.

You mean like extending StopWatch and allowing the user to provide the
measuring code, i.e. counting the number of instructions. This would be
very useful. Is it possible to make sure that these changes can be
introduced later without breaking the API?

Jens


Re: Extending unittests [proposal] [Proof Of Concept]

2012-09-22 Thread Jens Mueller
Jacob Carlborg wrote:
> On 2012-09-21 23:11, Jens Mueller wrote:
> 
> >But if you have an assert in some algorithm to ensure some invariant or
> >in a contract it will be handled by myUnitTestSpecificAssertHandler.
> >But I think that is not a drawback. Don't you want to no whenever an
> >assert is violated?
> 
> Oh, you mean like that. Sure, but that will only show up as a failed
> test. For example, in the Ruby world there are two different testing
> frameworks: Rspec and test-unit. Rspec makes not difference between
> a thrown exception or a failed test (assert). Test-unit on the other
> hand do make a difference of these scenarios. I'm leaning more
> towards the Rspec way of handling this.

What does it mean to make no distinction in RSpec?
Both should be reported. In D you just see either an AssertError or
SomeException.

Jens


Re: Extending unittests [proposal] [Proof Of Concept]

2012-09-22 Thread Jens Mueller
Johannes Pfau wrote:
> Am Fri, 21 Sep 2012 23:15:33 +0200
> schrieb Jens Mueller :
> 
> > > I like the BOOST unit test library's approach, which has two types
> > > of "assert": BOOST_CHECK and BOOST_REQUIRE. After a BOOST_CHECK
> > > fails, the test keeps running, but BOOST_REQUIRE throws an exception
> > > to stop the test. When testing a series of inputs in a loop, it is
> > > useful (for debugging) to see the complete set of which ones succeed
> > > and which ones fail. For this feature (continuation) to be really
> > > useful though, it needs to be able to output context information on
> > > failure (e.g. "during iteration 13 of input group B").
> > 
> > This leads us to the distinction of exceptions and errors. It is safe
> > to catch exceptions but less so for errors. At least it is far more
> > dangerous and less advised to continue execution but should not be
> > prohibited I think.
> > 
> > Jens
> 
> I don't know, I'd expect Exceptions, Errors and assert to always exit
> the current scope, so I'd expect this to always work:
> 
> unittest
> {
> throw new Exception();
> assert(1 == 2);
> auto a = *cast(int*)null; //should never be executed
> }

That should definitely be the default.
I think dmd also warns about such code.

> I think a proper unit test framework should supply an additional check
> method:
> unittest
> {
> check(a == 1); //always continue execution
> check(b == 2); //always continue execution
> check(c == 3); //always continue execution
> }
> 
> This can be implemented in library code: Have a module level array of
> failed checks, then let check append to that array. Analyze the result
> after every unit test run and empty the array. Then call the next test
> and so on.

gtest also has ASSERT_* and EXPECT_*. I used EXPECT_* rarely.
I think it complicates matters for little reason. Because in D you then
have assert, enforce, and check. I would prefer if assert and enforce
are the only ones. Though semantics for enforce and check are a little
different. An exception is like a check. It may fail and can be handled.

Jens


Re: Extending unittests [proposal] [Proof Of Concept]

2012-09-23 Thread Jens Mueller
Jacob Carlborg wrote:
> On 2012-09-22 19:43, Jens Mueller wrote:
> 
> >What does it mean to make no distinction in RSpec?
> >Both should be reported. In D you just see either an AssertError or
> >SomeException.
> 
> Test-unit would report something like this:
> 
> 5 tests, 2 failures, 1 error
> 
> Failures would be asserts that triggered, errors would be thrown exceptions.
> 
> Rspec on the other hand would report:
> 
> 5 examples, 3 failures
> 
> It doesn't care if a failure is due to a thrown exception or a
> failed assert.

I see. Thanks for giving this example.

> Both of these also show a form of stack trace if an exception has
> been thrown.

How is the stack trace provided? Do you get a stack trace for each
failure/error? Because that may clutter up the output. Maybe they stop
at a predefined stack trace length.

Jens


Re: dynamic library building and loading

2012-09-26 Thread Jens Mueller
Maxim Fomin wrote:
> You can build shared libraries on linux by manually compiling object
> files and linking them. On windows last time I tries it was not
> possible.

Can you give detailed steps for doing this on Linux? Because nobody as
far as I know has made this work yet?

Jens


Re: dynamic library building and loading

2012-09-27 Thread Jens Mueller
Jacob Carlborg wrote:
> On 2012-09-27 10:04, Maxim Fomin wrote:
> >On Thursday, 27 September 2012 at 05:52:44 UTC, Jens Mueller
> >wrote:
> >>Maxim Fomin wrote:
> >>>You can build shared libraries on linux by manually compiling object
> >>>files and linking them. On windows last time I tries it was not
> >>>possible.
> >>
> >>Can you give detailed steps for doing this on Linux? Because nobody as
> >>far as I know has made this work yet?
> >>
> >>Jens
> >
> >Dpaste seems not working, so, sorry for code
> >
> >lib.d---
> >import std.stdio;
> >
> >static this()
> >{
> > writeln("module ctor");
> >}
> >
> >static ~this()
> >{
> > writeln("module dtor");
> >}
> >
> >class A
> >{
> > private string text;;
> > this(string text)
> > {
> > writeln("class ctor");
> > this.text = text;
> > }
> > void tell()
> > {
> > writeln(this.text);
> > }
> > ~this()
> > {
> > writeln(this.text);
> > writeln("dtor");
> > }
> > static this()
> > {
> > writeln("static ctor");
> > }
> > static ~this()
> > {
> > writeln("static dtor");
> > }
> >}
> >---
> >-main.d
> >import lib;
> >
> >void main()
> >{
> > auto a = new A("some text");
> > a.tell();
> >}
> >---
> >
> >dmd -c -fPIC lib.d
> >gcc -shared lib.o -o liblib.so
> >dmd -c main.d
> >gcc main.o -llib -lphobos2 -lrt -lpthread -L. -Wl,-rpath=.
> >./a.out
> >ldd a.out
> > linux-vdso.so.1 (0x7fff703ff000)
> > liblib.so => ./liblib.so (0x7f48158f1000)
> > librt.so.1 => /lib64/librt.so.1 (0x7f48156cd000)
> > libpthread.so.0 => /lib64/libpthread.so.0 (0x7f48154b1000)
> > libc.so.6 => /lib64/libc.so.6 (0x7f481510c000)
> > /lib64/ld-linux-x86-64.so.2 (0x7f4815af4000)
> 
> 1. Does this actually run?

I just tried.
$ ./a.out
module ctor
static ctor
class ctor
some text
static dtor
module dtor
some text
dtor

> 2. This is statically linked with druntime and Phobos. What happens
> when you create an executable that links with the D dynamic library?

a.out is linked dynamically against liblib.so.

> Last time I tried this (on Mac OS X) I got several symbols missing.
> This was all symbols that are usually pointing to the executable,
> inserted by the compiler. One of them would be "main" and symbols
> like these:
> 
> https://github.com/D-Programming-Language/druntime/blob/master/src/rt/deh2.d#L27

I'm running Linux. You can test on Mac OS X.
I'm also astonished that this works. This is great.

Jens


Re: Review of Andrei's std.benchmark

2012-10-01 Thread Jens Mueller
Jens Mueller wrote:
> Hi,
> 
> it's my pleasure to announce the begin of the formal review of Andrei's
> std.benchmark. The review will start today and end in two weeks, on 1st
> of October. The review is followed by a week of voting which ends on 8th
> of October.
> 
> Quoting Andrei from his request for formal review:
> "I reworked the benchmarking framework for backward compatibility,
> flexibility, and convenience.
> 
> There are a few enhancement possibilities (such as tracking
> system/user time separately etc), but there is value in keeping things
> simple and convenient. Right now it really takes only one line of code
> and observing a simple naming convention to hook a module into the
> benchmarking framework."
> 
> Code: https://github.com/D-Programming-Language/phobos/pull/794
> Docs: http://dlang.org/phobos-prerelease/std_benchmark.html
> 
> If std.benchmark is accepted it will likely lead to a deprecation of
> std.datetime's benchmark facilities.
> 
> The code is provided as a pull requested and being (as usual) integrated
> by the auto tester for Mac OS X, FreeBSD, Linux and Windows (see
> (http://d.puremagic.com/test-results/pull-history.ghtml?repoid=3&pullid=794).
> 
> In your comments you can/should address the
> * design
> * implementation
> * documentation
> * usefulness
> of the library.
> 
> Provide information regarding the depth (ranging from very brief to
> in-depth) of your review and conclude explicitly whether std.benchmark
> should or shouldn't be included in Phobos.
> 
> Post all feedback to this thread. Constructive feedback is very much
> appreciated.
> 
> To conclude in more Andrei like words: Happy destruction!
> 
> Jens

The review of std.benchmark is over.
I'd like to give some conclusions regarding the review of the proposed
benchmarking module hoping to reach some consensus on how to proceed.

First of all I'd like to thank all the reviewers for taking part in this
review.

Let me first summarize the main point that was intensely discussed
in the review.

* benchmarking vs. profiling
  std.benchmark, as the review clarified, is primarily intended for
  micro benchmarking.
  The review questioned this arguably limited scope. In particular, it
  asked for different reductions (max, avg (with std deviation)).
  This whole initial confusion should be addressed by improving the
  documentation and making sure a broader set of use cases can be
  supported without breaking code.

  It is not entirely settled whether this broader scope of usage will be
  addressed by Andrei's proposal. Maybe the community can address this
  issue by providing additional functionality at a later point in time.
  But it needs to made sure that those changes won't break code written
  against the first version of std.benchmark.

  The issues related to this are
  -non-deterministic/randomized functions (currently not supported)
  -benchmarking real time software
  -benchmarking with warm vs. cold caches
  -measuring by using hardware counters

  These seem to be of particular interest to D community.

During the review other issues were identified which the author will
look into.
* make number of function runs configurable
* individual registration of benchmark functions in addition to naming 
convention
* auto detect when min is stable with some degree of statistical certainty
* specify a problem size
* make scheduleForBenchmarking a template mixin
* benchmark should return the BenchmarkResult array

A major issue is that std.benchmark won't work if two cyclically
dependent modules are benchmarked because it uses module/static
constructors. Currently there is no idea on how to solve this issue.

I hope this summary captures the most important issues that where
brought up. How to proceed seems difficult at this point. I believe the
issue with cyclic dependent modules has to be solved and we should reach
consensus regarding the intended use cases that should be addressed by
std.benchmark even in the long run.
For the time being I suppose there is no use in proceeding with voting.
Any comments?

Jens


Re: Review of Andrei's std.benchmark

2012-10-03 Thread Jens Mueller
Andrei Alexandrescu wrote:
> On 10/1/12 9:09 PM, Jens Mueller wrote:
> >The review of std.benchmark is over.
> >I'd like to give some conclusions regarding the review of the proposed
> >benchmarking module hoping to reach some consensus on how to proceed.
> [snip]
> 
> Thanks Jens for shepherding the review and to all for the comments.

Thanks for your reply.
I'm looking forward to your changes.

Jens


Re: Gathering info for D/Embedded presentation

2012-10-12 Thread Jens Mueller
mist wrote:
> After some gentle preachings I have been asked in my company to
> prepare presentation regarding D usage in scope of embedded,
> kernel-level development and mobile devices. I am quite starving to
> find good project examples for D2 though ( most stuff I am aware of
> is D1 ) and do not have enough time to write some from scratch. Any
> suggestions here?
> 
> Regarding mobile development - I remember a thread some time ago
> regarding Android + D2 that I can't find anymore. What is current
> state of affairs?

You can have a look at this guide:
http://gdcproject.org/wiki/GDCOnAndroid

Jens


Re: Tricky semantics of ranges & potentially numerous Phobos bugs

2012-10-16 Thread Jens Mueller
Jonathan M Davis wrote:
> On Tuesday, October 16, 2012 10:58:23 David Gileadi wrote:
> > On 10/16/12 10:28 AM, Jonathan M Davis wrote:
> > > Any range is free to violate this, but because range-based functions are
> > > free to rely on it, such ranges risk not working correctly with many
> > > range-based functions and must be used with caution.
> > 
> > As a D dabbler, it seems wrong to me that a built-in range like byLine,
> > which is often used in example code, should have weird side effects with
> > the built-in methods in std.algorithm. IMO this needs to be fixed one
> > way or another, and a mere documentation change is likely not enough for
> > casual D users.
> 
> ByLine needs to do what it does for performance reasons, so its 
> implementation 
> makes a lot of sense, and it really wouldn't make sense for it to do what 
> would be necessary to make it work as a normal range (since that would mean 
> allocating a new buffer for every line), so if the fact that it's likely to 
> be 
> used and then misused by newbies is a big problem, then that's a strong 
> argument for making it just use opApply rather than being a proper range. I 
> certainly don't think that it makes sense to change how ranges work in 
> general 
> just to better support ByLine's weirdness. it would be far too restrictive to 
> do so.

I've not really looked at byLine. Why do you have to do an allocation
for each line?
byChunk seems to not suffer from this problem (see
http://d.puremagic.com/issues/show_bug.cgi?id=8085). Does this mean
byChunk is less efficient?

I want to add that if byLine only implements opApply, then there should
be some adapter that turns anything which has an opApply into a range.
Then you have to do: byLine().adapter().joiner().

And I also think that the documentation needs to clarify whether
popFront may invalidate t, if t was obtained before via auto t =
r.front.

Jens


  1   2   3   4   5   >