Re: How to implement a copy

2010-03-20 Thread Ali Çehreli

� wrote:


this(this) is the copy constructor, I think.


this(this) is not the copy constructor. It is post-blit, which is useful 
for when corrections need to be done after the automatic blitting:


  http://digitalmars.com/d/2.0/struct.html#StructPostblit

Ali


is pointer

2010-03-20 Thread bearophile
(I am looking for rough corners in D, or in my knowledge of D.)

In this page:
http://www.digitalmars.com/d/2.0/templates-revisited.html

In the section Template Parameters there is written:

P:P*, // P must be a pointer type

-

So I have written this D2 program:


template IsPointer1(T) {
enum bool IsPointer1 = is(T : T*);
}
void main() {
int* ptr;
static assert(IsPointer1!(typeof(ptr))); // Err
}


But it asserts, do you know why?

-

Then I have written a different program:


template IsPointer2(T) {
enum bool IsPointer2 = is(typeof(*T)) || is(T == void*);
}
void main() {
int* ptr;
static assert(IsPointer2!(typeof(ptr))); // OK
int[] arr;
static assert(!IsPointer2!(typeof(arr))); // Err
}


Do you know why IsPointer2 is true for the dynamic array type too?

(I know in std.traits of Phobos 2 there is an isPointer).

Thank you,
bye,
bearophile


Re: system mkdir

2010-03-20 Thread Spacen Jasset

noboy wrote:

There was a soft link /bin/sh - dash
I have change this to bash, and now all went fine.

Thank you

Steven Schveighoffer Wrote:


On Thu, 18 Mar 2010 09:28:06 -0400, noboy nob...@nowhere.com wrote:


I was little bit surprise because
mkdir -p dmd-2/usr/{bin,lib,src/phobos2,share/man
do the right thing.
When you do that, you are using your shell.  The shell actually does the  
argument expansion, not mkdir.  So the question to answer is, does system  
use the shell or just call mkdir directly.  According to my man page,  
using system(cmd) is equivalent to doing /bin/sh -c cmd.  On my system  
doing this:


/bin/sh -c 'mkdir -p /testdir/{a,b,c}'

results in the desired behavior.  The single quotes force the shell I'm  
currently running *not* to expand the arguments, but pass them directly to  
/bin/sh as one string.  I would expect that system would execute the same  
command.


I would guess on my system that your code would work properly, but I'm not  
sure.  What you need to find out is what /bin/sh actually is on your  
system.  Maybe it is a shell that does not understand how to expand the  
{a,b,c} term.  IIRC, /bin/sh usually is a link to bash, but I think on  
some systems, bash behaves differently if it's called via /bin/sh.



But if i make
mkdir -p dmd-2/usr/{bin,lib,src/phobos2,share/man
it's wrong.

So i have think the system command wrap quotes about the command.

I don't think this is what's happening.

-Steve


then presumably the syntax you are using is a bashism?. You could also 
say something like:



system(bash mkdir -p  ~ path);


Messing with your sh symlink may have some undesired consequences.


Re: is pointer

2010-03-20 Thread Moritz Warning
On Fri, 19 Mar 2010 19:29:24 -0400, bearophile wrote:

 (I am looking for rough corners in D, or in my knowledge of D.)
[..]
 
 template IsPointer1(T) {
 enum bool IsPointer1 = is(T : T*);
 }
 void main() {
 int* ptr;
 static assert(IsPointer1!(typeof(ptr))); // Err
 }
 
 
 But it asserts, do you know why?

I think the problem is that is(T : T*) becomes is(int* : int**)
and that's false.



 Then I have written a different program:
[..]
 enum bool IsPointer2 = is(typeof(*T)) || is(T == void*);
[..]
 
 
 Do you know why IsPointer2 is true for the dynamic array type too?
.. no idea.


Confused about const

2010-03-20 Thread Paul D. Anderson
I created a struct, call it S, and some functions that operate on S. But I'm 
confused about when const is useful.

Being an old Java programmer, I use 'const' the same as I used 'final' in Java. 
So most of my functions look like this:

S for(const S a, const S b) {
S x = a;
S y = b;
// do some stuff
return a;
}

I declare the parameters const and then copy them to work on them.

I get error messages about not implicitly casting const S to S. So I can make 
an explicit cast:

S x = cast(S) a;
S y = cast(S) b;

and the error messages go away.

But I think I must have gone off the rails somewhere -- all I want is for the 
caller to be sure the function doesn't alter a and b. But I end up with lots of 
casts to/from const. What am I missing??

Paul


Re: Confused about const

2010-03-20 Thread bearophile
Paul D. Anderson:

 I created a struct, call it S, and some functions that operate on S. But 
 I'm confused about when const is useful.
 
 Being an old Java programmer, I use 'const' the same as I used 'final' in 
 Java. So most of my functions look like this:
 
 S for(const S a, const S b) {
 S x = a;
 S y = b;
 // do some stuff
 return a;
 }
 
 I declare the parameters const and then copy them to work on them.
 
 I get error messages about not implicitly casting const S to S.

This program compiles:

struct S { int x; }
S foo(const S a) {
S other = a;
return other;
}
void main() {}


So, what's that you actually write? When possible show programs that run! It's 
one of the things I have learnt from the Python groups.

Bye,
bearophile


Re: Confused about const

2010-03-20 Thread bearophile
Paul D. Anderson:
 S x = cast(S) a;
 S y = cast(S) b;

In Java (especially old Java) casts may be common, but in D they are something 
that has to be used with care, don't cast away things carelessly :-)

Bye,
bearophile


Re: Confused about const

2010-03-20 Thread Paul D. Anderson
bearophile Wrote:

 Paul D. Anderson:
 
  I created a struct, call it S, and some functions that operate on S. But 
  I'm confused about when const is useful.
  
  Being an old Java programmer, I use 'const' the same as I used 'final' in 
  Java. So most of my functions look like this:
  
  S for(const S a, const S b) {
  S x = a;
  S y = b;
  // do some stuff
  return a;
  }
  
  I declare the parameters const and then copy them to work on them.
  
  I get error messages about not implicitly casting const S to S.
 
 This program compiles:
 
 struct S { int x; }
 S foo(const S a) {
 S other = a;
 return other;
 }
 void main() {}
 
 
 So, what's that you actually write? When possible show programs that run! 
 It's one of the things I have learnt from the Python groups.
 
 Bye,
 bearophile

My struct has a dynamic array as a member -- that seems to be the problem. This 
code doesn't compile:

struct S {
 int x;
 int[] a;
}

S foo(const S b) {
S other = b;
return other;
}
void main() {}

FYI, I'm using DMD version 2.30.


Re: Confused about const

2010-03-20 Thread Paul D. Anderson
bearophile Wrote:

 Paul D. Anderson:
  S x = cast(S) a;
  S y = cast(S) b;
 
 In Java (especially old Java) casts may be common, but in D they are 
 something that has to be used with care, don't cast away things carelessly :-)
 
 Bye,
 bearophile

I realize that casting is a last resort -- but it seemed to be the only thing 
that worked. That's what made me think I'm making some sort of fundamental 
mistake.

Paul


Re: is pointer

2010-03-20 Thread Ellery Newcomer

On 03/19/2010 07:53 PM, Moritz Warning wrote:

On Fri, 19 Mar 2010 19:29:24 -0400, bearophile wrote:


(I am looking for rough corners in D, or in my knowledge of D.)

[..]


template IsPointer1(T) {
 enum bool IsPointer1 = is(T : T*);
}
void main() {
 int* ptr;
 static assert(IsPointer1!(typeof(ptr))); // Err
}


But it asserts, do you know why?


I think the problem is that is(T : T*) becomes is(int* : int**)
and that's false.




Then I have written a different program:

[..]

 enum bool IsPointer2 = is(typeof(*T)) || is(T == void*);

[..]



Do you know why IsPointer2 is true for the dynamic array type too?

.. no idea.


Curious behavior DArrays exhibit:

void main(){
  int[] i = [5,4,3,2,1];
  writeln(*i); // prints 5
}

Ick.


Re: is pointer

2010-03-20 Thread bearophile
Moritz Warning:
I think the problem is that is(T : T*) becomes is(int* : int**) and that's 
false.

Thank you, you can be right.
So D docs are wrong, or that syntax has a semantic bug, or I have not 
understood the situation yet.
If someone else has ideas I'm all ears.

-

Ellery Newcomer:
 Curious behavior DArrays exhibit:

Thankfully this doesn't compile:

import std.stdio: writeln;
import std.c.stdlib: calloc;

struct Array {
int* ptr;
size_t length;
}

void main() {
enum size_t N = 5;
int* p = cast(int*)calloc(N, int.sizeof);
Array a = Array(p, N);
writeln(*a);
}

This solves the second question, I'll file it as a bug or specs bug. Thank you.

Bye,
bearophile


Re: Confused about const

2010-03-20 Thread biozic

My guess is that:


struct S {
  int x;
  int[] a;
}

S foo(const S b) {


foo makes the promise that b's members won't change: so 'b.x' is 
implicitely const(int) and 'b.a' is implicitely const(int[]).



 S other = b;


Here you assign 'b.x', which is const(int), to 'other.x', which is int. 
You can assign an const(int) to an int: after the value is copied, 
changing 'other.x' won't change 'b.x'.
But then you assign 'b.a', which is const(int[]), to 'other.a' which is 
int[]. This is forbidden: this would copy the reference to the array 
from 'b' to 'other', and after the copy, you would be able to change the 
content of 'b.a' by changing the content of 'other.a', thus going 
against const.


I'm not sure if this is completely right nor if I'm completely clear, 
though... :)


Nicolas


Re: Confused about const

2010-03-20 Thread bearophile
biozic:
 I'm not sure if this is completely right nor if I'm completely clear, 
 though... :)

I think you are right.
In practice to copy something const to something that's not const you need a 
deep copy function, because inside the array there can be other arrays that are 
const, etc. Transitive const requires transitive copy, it's easy :-)

Bye,
bearophile


Re: Confused about const

2010-03-20 Thread bearophile
 Transitive const requires transitive copy, it's easy :-)

Or when possible, you don't copy it, just return it.

Bye,
bearophile


Re: Confused about const

2010-03-20 Thread bearophile
So the question here is: do you know if there are important use cases for a 
shallow_const attribute?

Bye,
bearophile


Re: is pointer

2010-03-20 Thread Daniel Keep

bearophile wrote:
 (I am looking for rough corners in D, or in my knowledge of D.)
 
 In this page:
 http://www.digitalmars.com/d/2.0/templates-revisited.html
 
 In the section Template Parameters there is written:
 
 P:P*, // P must be a pointer type
 
 -
 
 So I have written this D2 program:
 
 
 template IsPointer1(T) {
 enum bool IsPointer1 = is(T : T*);
 }
 void main() {
 int* ptr;
 static assert(IsPointer1!(typeof(ptr))); // Err
 }
 
 
 But it asserts, do you know why?

You do realise that Template Parameters are a completely different
thing to is expressions, right?


Re: Confused about const

2010-03-20 Thread bearophile
Paul D. Anderson:
 My struct has a dynamic array as a member -- that seems to be the problem. 
 This code doesn't compile:
 
 struct S {
  int x;
  int[] a;
 }
 
 S foo(const S b) {
 S other = b;
 return other;
 }
 void main() {}

This compiles, oh joy:

struct S {
int x;
int[] a;
}
S foo(const S b) {
S other;
other.x = b.x;
other.a = b.a.dup; // the dup is necessary here
return other;
}
void main() {}


The idea now is to find a way to encapsulate that manual copying  dupping into 
some overloaded operator of S. But I have failed so far. Operator overloading 
in D2 is not an easy thing, it needs training. (That's why I have recently 
asked for the compiler to be strict to avoid wrong usages of the operator 
overloading.)

Bye,
bearophile


Re: Confused about const

2010-03-20 Thread Steven Schveighoffer
On Fri, 19 Mar 2010 20:58:21 -0400, Paul D. Anderson  
paul.d.removet...@comcast.andthis.net wrote:


I created a struct, call it S, and some functions that operate on S.  
But I'm confused about when const is useful.


Being an old Java programmer, I use 'const' the same as I used 'final'  
in Java. So most of my functions look like this:


S for(const S a, const S b) {
S x = a;
S y = b;
// do some stuff
return a;
}

I declare the parameters const and then copy them to work on them.

I get error messages about not implicitly casting const S to S. So I can  
make an explicit cast:


S x = cast(S) a;
S y = cast(S) b;

and the error messages go away.

But I think I must have gone off the rails somewhere -- all I want is  
for the caller to be sure the function doesn't alter a and b. But I end  
up with lots of casts to/from const. What am I missing??



I'll try to help, const is a very complex thing to understand.  However,  
what it provides is so valuable for interface design that it is worth  
learning.


One thing to remember that const is transitive.  This means that if S  
contains a pointer to something, you have to treat that pointer as if it  
were const too.  This is a difference from Java's final.


If S has a pointer or reference, then a const S cannot be copied to a  
mutable S because you can then change the data through the mutable  
reference without any casts.  I'll give you an example:


struct S
{
  int *a;
}

void foo(const(S) s)
{
   S s2 = s; // this fails to compile because of the possibility for the  
next line.
   *s2.a = 5; // I now just changed the value pointed to by s, which is  
const data!

}

However, if S does not have a pointer or reference, then you can copy a  
const S to a mutable one because then changing the mutable S does not  
affect the const data in the original S.


example:

struct S
{
   int a;
}

void foo(const(S) s)
{
   S s2 = s; // this compiles
   s2.a = 5; // does not change s at all.
}

In answer to your question, what you are missing is what const is for.   
When declaring a function takes a const item, you are declaring that that  
function will not change the argument *or* anything it references.  The  
compiler is trying to enforce that.  Casting away const breaks the  
compiler guarantees, so you should not do that unless you know what you  
are doing.  So what I think is if you want to change the elements of S, or  
return an S parameter that is not const, then you shouldn't declare them  
as const parameters.


One final thing -- there is a brand new feature for D2 that allows you to  
forward the const attributes of parameters to return values.  This is  
under the heading inout functions of the documentation.  This feature is  
not implemented properly, even in the latest compiler.  However, once it  
does work, you can use it to declare your function like this:


inout(S) foo(inout(S) a, inout(S) b)
{
   return a;
}

What this means is, during the foo function, it will not modify a or b,  
but once it returns, the return value has the same constancy as the  
parameters.  It basically means the const you put in is the const you get  
out.


-Steve


Re: Confused about const

2010-03-20 Thread Paul D. Anderson
After further review, I now realize that the right way (for me) to do this is 
to add a .dup property. So instead of 

S foo(const S s) {
S other;
other = s;
}

or

S foo(const S s) {
S other = S(s);
return other;
}

which didn't look right to me, I can write

S foo(const S s) {
S other = s.dup;
return other;
}

which is ultimately an equivalent operation.

Thanks again, everyone for taking the time to explain what was going on.

Paul

It just looks better to me.





Paul D. Anderson Wrote:

 bearophile Wrote:
 
  The idea now is to find a way to encapsulate that manual copying  dupping 
  into some overloaded operator of S. But I have failed so far. Operator 
  overloading in D2 is not an easy thing, it needs training. (That's why I 
  have recently asked for the compiler to be strict to avoid wrong usages of 
  the operator overloading.)
  
  Bye,
  bearophile
 
 
 So I understand better now, thanks, what is wrong. I'm a little disappointed 
 that there is apparently no way to implement case 4 for any struct with a 
 reference.
 
 Paul



Re: system mkdir

2010-03-20 Thread Jesse Phillips
Spacen Jasset wrote:

 then presumably the syntax you are using is a bashism?. You could also 
 say something like:


 system(bash mkdir -p  ~ path);


 Messing with your sh symlink may have some undesired consequences.

Actually, not messing with it will have undesired consequences. Lots of
scripts assume sh points to bash. Though he should still change his code
so he isn't one of those doing the assuming.

I think someone wanted to restore that scripts be sh complient when they
claim to use it, so dash became the default.


Re: Confused about const

2010-03-20 Thread Don

bearophile wrote:

Operator overloading in D2 is not an easy thing, it needs training. 
(That's why I have recently asked for the compiler to be strict to 
avoid wrong usages of the operator overloading.)


I think the problem is really that it's still very buggy. In particular,
opAssign seems pretty defective. More importantly, struct constructors, 
post blit, and  struct destructors are still quite badly broken.


Re: Confused about const

2010-03-20 Thread bearophile
Paul D. Anderson:

 After further review, I now realize that the right way (for me) to do this is 
 to add a .dup property.

Steven Schveighoffer has given you quite good answers.
A dup is generally not enough, because what you dup can have other immutable 
references nested inside. Dup is not a deep copy.
The summary of this topic is (until inout works) that if you can return a const 
value, then don't copy things. This is the preferred option, because one of the 
main purposes of const data is to not have to copy them.
If you can't return a const, then don't mark the input values as const. The 
safety given by the not deep const of Java is only partial safety.

Bye,
bearophile


Re: is pointer

2010-03-20 Thread bearophile
Daniel Keep:
 You do realise that Template Parameters are a completely different
 thing to is expressions, right?

Nope. And from the other answers by Moritz and Ellery it seems I am not alone 
:-)
You are right, this works:


template IsPointer1(T:T*) {
enum bool IsPointer1 = true;
}
template IsPointer1(T) {
enum bool IsPointer1 = false;
}
void main() {
static assert(IsPointer1!(int*));
static assert(!IsPointer1!(int));
static assert(!IsPointer1!(int[]));
}


This syntax looks too much similar to the syntax with is():
template IsPointer1(T:T*) {
It's a syntax collision. You realize that I will not be the only one to fall in 
this little trap.

Bye and thank you,
bearophile


Re: Confused about const

2010-03-20 Thread bearophile
Don:
 I think the problem is really that it's still very buggy. In particular,
 opAssign seems pretty defective. More importantly, struct constructors, 
 post blit, and  struct destructors are still quite badly broken.

You are right, but in my opinion it's not just a matter of bugs. To solve real 
world problems (like bugs in code) you usually have to attack the problems from 
many sides at the same time. So once:

- the op overloading design is not too much bug-prone;
- such parts of D are debugged;
- the compiler performs several sanity tests on the operators defined by the 
programmer (even if this means disallowing few legit corner cases)

Then D2 op overloading can be safe enough to use :-)

Bye,
bearophile


Re: system mkdir

2010-03-20 Thread noboy noboy
Jesse Phillips Wrote:

 Spacen Jasset wrote:
 
  then presumably the syntax you are using is a bashism?. You could also 
  say something like:
 
 
  system(bash mkdir -p  ~ path);
 
 
  Messing with your sh symlink may have some undesired consequences.
 
 Actually, not messing with it will have undesired consequences. Lots of
 scripts assume sh points to bash. Though he should still change his code
 so he isn't one of those doing the assuming.
 
 I think someone wanted to restore that scripts be sh complient when they
 claim to use it, so dash became the default.
Yes this can be true. In April i start an update from Kubuntu 8.04  LTS to
Kubuntu 10.04 LTS.

By the way, the  line system(mkdir -p  ~ path); comes from project
DDebber.

It's a cool project, and i have make succesfully deb files for dmd 2.041.



Re: is pointer

2010-03-20 Thread Jacob Carlborg

On 2010-03-20 00.29, bearophile wrote:

(I am looking for rough corners in D, or in my knowledge of D.)

In this page:
http://www.digitalmars.com/d/2.0/templates-revisited.html

In the section Template Parameters there is written:

P:P*, // P must be a pointer type

-

So I have written this D2 program:


template IsPointer1(T) {
 enum bool IsPointer1 = is(T : T*);
}
void main() {
 int* ptr;
 static assert(IsPointer1!(typeof(ptr))); // Err
}


But it asserts, do you know why?


You can do like this:

template IsPointer (T)
{
enum IsPointer = false;
}

template IsPointer (T : T*)
{
enum IsPointer = true;
}


-

Then I have written a different program:


template IsPointer2(T) {
 enum bool IsPointer2 = is(typeof(*T)) || is(T == void*);
}
void main() {
 int* ptr;
 static assert(IsPointer2!(typeof(ptr))); // OK
 int[] arr;
 static assert(!IsPointer2!(typeof(arr))); // Err
}


Do you know why IsPointer2 is true for the dynamic array type too?

(I know in std.traits of Phobos 2 there is an isPointer).

Thank you,
bye,
bearophile




Returning this from a const member

2010-03-20 Thread Robert Clipsham

According to http://digitalmars.com/d/2.0/const3.html:

Const member functions are functions that are not allowed to change any 
part of the object through the member function's this reference.



With the following code:

class Foo
{
Foo myFoo() const
{
return this;
}
}

void main()
{
auto f = new Foo;
}

I get the error:

test.d(5): Error: cannot implicitly convert expression (this) of type 
const(Foo) to test.Foo



Why is this? myFoo() isn't changing any part of Foo, so it should be 
fine according to the spec... Or is const like immutable here where it 
causes the rest of the object to become const if one member function is? 
If it is then maybe the spec should be updated to clarify this?


Re: Returning this from a const member

2010-03-20 Thread Robert Clipsham

On 21/03/10 00:18, bearophile wrote:

Robert Clipsham:

Why is this?


It's not a hard question. This code compiles:

class Foo {
 const(Foo) myFoo() const {
 return this;
 }
}
void main() {
 auto f = new Foo;
}

It's just in a const function the this is const, so if you want to return it, then you 
have to use a const Foo type, because it's not a mutable Foo :-)

Bye,
bearophile


Now you say it, that does seem obvious, thank you :)