Re: What is put() useful for with regards to dynamic arrays?

2011-05-02 Thread Lars T. Kyllingstad
On Sat, 30 Apr 2011 00:09:09 -0400, Andrej Mitrovic wrote:

> import std.range;
> 
> void main()
> {
> int[] a = [1, 2, 3];
> 
> a.put(6);
> assert(a == [2, 3]);
> 
> a.put([1, 2]);
> assert(a.length == 0);
> }
> 
> Seems kind of odd.. put is implemented as an append method for some
> custom types, e.g. std.array.appender. But for arrays put just removes
> Item or RangeLength number of elements from the array. What's the use
> case for this?

This should probably be in a FAQ somewhere. :)

http://www.digitalmars.com/d/archives/digitalmars/D/
std.array.put_doesn_t_put_106871.html

-Lars


Re: Matrix creation quiz

2011-05-02 Thread bearophile
I was away.

Don:

> That would not fix this problem. You're doing arithmetic on unsigned 
> values, where overflow doesn't happen.

My enhancement request about integral overflows asks for two compiler switches: 
one that turns signed integral overflows (at compile time or run time) into 
errors, and one switch that turns both signed and unsigned overflows into 
errors. If you use the second switch you have overflows on unsigned values too.


> -- which compiles happily on 32 bits, but won't compile on a 64 bit 
> system. I think it should be rejected on all systems.

I agree. I think code that doesn't work on 64 bit systems has to not work on 32 
bit ones too.

Bye,
bearophile


Re: "not an lvalue"

2011-05-02 Thread Steven Schveighoffer
On Sun, 01 May 2011 09:30:34 -0400, CrypticMetaphor  
 wrote:


Hi, I've been away from D for a while, but now I'm back and I'm stuck  
with an compile time error.


I've got a Matrix33 class and a Vector3 class, but something is wrong  
with the way I return my Vector3 in my matrix class:


If I do this I get an error:

Matrix33 mtest = new Matrix33();
mtest.SetIdentity();
Vector3 test1 = new Vector3(0, 0, 0);
Vector3 test2 = test + mtest.GetColumn(2);

I get the error "Error: mtest.GetColumn(x) is not an lvalue"

But the following works:

Matrix33 mtest = new Matrix33();
mtest.SetIdentity();
Vector3 test1 = new Vector3(0, 0, 0);
Vector3 temp = mtest.GetColumn(2);
Vector3 test2 = test + temp;

// GetColumn method
Matrix33
{
// ...

   /// Get a matrix column, horizontal line
   Vector3 GetColumn(uint index)
   {
 assert(!(index > 2), "index is too high");
 return new Vector3(cell[index * 3], cell[index * 3 + 1], cell[index  
* 3 + 2]);

   }
// ...
}

My questions:
What changes do I have to make to make the first example compile?


I think others have said you need to not use ref.

The solution (which is not yet properly implemented) is to use auto ref.   
The way it is supposed to work is like this:


void foo(T t); // t is passed by value (copied).  t can be an lvalue or an  
rvalue

void foo(ref T t); // t is passed by reference.  t can only be an lvalue
void foo(auto ref T t); // t is passed by reference.  t can be an lvalue  
or an rvalue.


Essentially, with auto-ref you are saying, I know there are dangers in  
passing rvalues here, but I still want to accept an rvalue by reference.


There was confusion on Walter's part as to how this was supposed to work,  
so auto ref currently doesn't act this way.


There are two workarounds I know of:

1. as you have done, convert the rvalue to an lvalue by assigning to a  
temporary
2. call the method on the rvalue.  For some reason (probably to make  
people not go insane) you are allowed to pass an rvalue by ref if you are  
calling a method on it.


i.e. this should work (don't remember vectors much, but I believe addition  
is commutative?):


Vector3 test2 = mtest.GetColumn(2) + test;

If you can't do the second method, I think method 1 is your only option.

-Steve


Re: What is put() useful for with regards to dynamic arrays?

2011-05-02 Thread Andrej Mitrovic
Thanks, that post explained it. Obviously I wasn't the first and
likely won't be the last person to run into this. Maybe put's
documentation could make a note of this.


Re: opDollar()

2011-05-02 Thread Don

Dmitry Olshansky wrote:

On 26.03.2011 11:03, Caligo wrote:

"In the expression a[, ...,], if $ occurs in, it is rewritten as a.opDollar!(i)()."  -- TDPL, pg 380

Is that correct? if so, could some one give an example code?  I don't
understand the need for the parameter.

Also, what is the signature for opDollar() in a struct.  I'm getting
errors trying to implement this.
That parameter means number of dimension. When implementing some kind of 
multidimensional array (e.g. an 2D raster Image) you'd have:
img[$-1, $-1] = lastValue; // the first dollar should resolve to 
"width", the second to "height"


Now speaking of it's implementation - it's quite broken.


It's not broken -- it's not implemented at all!

The relevant bug report is 
http://d.puremagic.com/issues/show_bug.cgi?id=3474 (vote up!)
Still it's not considered to be a critical one, since you can workaround 
it by:

img[img.width-1,img.height-1] = lastValue;



Re: expression templates

2011-05-02 Thread Don

Mr enuhtac wrote:

Hello everyone,

I'm new to D and this list (although I've had a look onto D a few years ago). I 
hope you guys can help me with my questions.

At the moment I'm trying to implement some expression template stuff. My first 
goal is to encode an expression into a type representing that expression 
without any additional functionality (like the possibility to evaluate that 
expression). Actually this is very simple and short in D. This is my approach:

struct OpBinary( string Op, R1, R2 )
{
alias typeof( mixin( "R1.EvalT.init" ~ Op ~ "R2.EvalT.init" ) ) EvalT;

enum string Operator = Op;
};

struct Constant( T, T v )
{
alias T EvalT;

enum T value = v;
};

struct Expr( R )
{
auto opBinary( string Op, R2 )( Expr!R2 )
{
return Expr!( OpBinary!( Op, R, R2 ) )();
}

auto opBinary( string Op, T )( T v ) if( isNumeric!T )
{
return Expr!( OpBinary!( Op, R, Constant!( T, v ) ) )();
}

auto opBinaryRight( string Op, T )( T v ) if( isNumeric!T )
{
return Expr!( OpBinary!( Op, Constant!( T, v ), R ) )();
}
};

But I cannot figure out how to implement expression templates for comparison 
operators, which is crucial for my purpose. The opCmp function is great for 
implementing comparison functionality, but when building an expression template 
tree the information on the actual comparison operator is needed. opCmp just 
knows that a comparison is going on, the actual type of comparison is unknown.
What I would like to have is something like this:

auto opCmp( string Op, R2 )( Expr!R2 )
{
return Expr!( OpBinary!( Op, R, R2 ) )();
}

So opCmp knows about the actual operator and would just use my OpBinary struct 
to encode it. But this is not possible.

The only workaround for I this problem I can imagine is using my own comparison 
functions instead of the comparison operators:
op!"<"( a, b ) instead of a < b.
Another possibility would be to call opBinary explicitly:
a.opCmp!"<"( b )
In this case I would not even have to write additional code.

But these workarounds are ugly, if would greatly prefer the normal comparison 
operators.
Does anyone has an idea how to use them?

Regards,
enuhtac


In the present language I don't think it's possible to do expression 
templates involving opCmp or opEquals, since you have no control over 
the return type.


One other solution I did: I had some code where the result of the 
expression template was used in a mixin, so I moved the mixin outside 
the expression. Then I changed all the >, <, == into something else 
before converting it into an expression template.

But this is ugly as well.


Difference between stack-allocated class and struct

2011-05-02 Thread Mariusz Gliwiński
What are the differences between class instantiated by scope and struct 
itself?

Two, that comes to my mind are:
- vtable existance (yep, struct with inheritation - that's what i like)
- lol, i just forgot while writing this e-mail

:)

Sincerely,
Mariusz Gliwiński


Re: Difference between stack-allocated class and struct

2011-05-02 Thread Jonathan M Davis
> What are the differences between class instantiated by scope and struct
> itself?
> Two, that comes to my mind are:
> - vtable existance (yep, struct with inheritation - that's what i like)
> - lol, i just forgot while writing this e-mail

First off, I would point out that scoped classes are going away (though 
std.typecons.scoped serves as a replacement).

Now, structs are value types and are meant to be on the stack. When you assign 
one to another, a copy is made. If the original is altered, it doesn't affect 
the copy, and if the original goes away, the copy is unaffected.

Classes are reference types and are meant to be on the heap. When you assign 
one to another, you're merely copying the reference. Both refer to the same 
object. No copy is made. So, when you alter one, you also alter the other. 
When one goes away, it doesn't affect the other, but if the underlying object 
went away, then they would both be screwed.

Normally, class objects don't go away until the garbage collector collects 
them, but if you use scope (or std.typecons.scoped), then the object is on the 
stack instead of the heap, and as soon as that scope goes away, so does the 
object, so if you have references to it elsewhere, they're invalid, but the 
program won't know that, and it'll try and use them anyway. It can lead to 
serious bugs. Scoped classes are inherently unsafe, which is why they're going 
away.

It's like when you return an address to a local variable:

int* foo()
{
int a = 7;

return &a;
}

The pointer will be invalid, and you're going to have bugs. Now, the 
compiler's going to catch such a simple case as this, but what if you did 
something like this?

int* foo()
{
int a = 7;

return bar(&a);
}

int* bar(int* b)
{
return b;
}

The compiler can't catch that. The same goes if you were to use a scoped class 
instead of an int. In general, scoped classes are a _bad_ idea and should not 
be used unless profiling has shown that they speed up critical code and you're 
_certain_ that you're using them in a manner which won't cause a reference to 
the class to escape the function and outlive the function call.

As for everything else structs are structs and classes are classes. All of the 
normal differences apply. That includes the fact that structs have no 
inheritance and no vtable while classes do have inheritance and do have a 
vtable. However, you pretty much lose polymorphism if you use a scoped class. 
You're guaranteeing that the class that you're using is _exactly_ that type 
and not a subclass of that type. This is because the object is put on the 
stack inside the function and the compiler must know its _exact_ size. It's 
exactly like what you get with classes on the stack in C++. Putting them on 
the stack loses any of the advantages of polymorhism and risks slicing ( 
http://en.wikipedia.org/wiki/Object_slicing ) when you assign a subclass 
object to a base class object.

So, if you're using a scoped class, you're _not_ getting the benefits of 
polymorphism. What you're doing is saying that you know that you have an 
object of a particular type - that _exact_ type - which you know is not going 
to need to exist once you exit that scope, and you want to increase the 
efficiency of that code, so you make it so that the object is created on the 
stack instead of the heap. And in so doing, you _must_ make sure that no 
reference to that object escapes - which often isn't easy if you have to pass 
that object to any other functions, and even if you verify that it's safe now, 
it might not be later.

Structs and classes are inherently different. Structs are value types and 
classes are reference types. All you're doing with a scoped class is forcing 
the object to be put on the stack instead of the heap, which doesn't really 
change anything for the class except for the fact that it must be of that 
_exact_ type (so no polymorphism), and you have to make sure that no 
references to it escape, or you could have serious bugs.

- Jonathan M Davis


Re: Difference between stack-allocated class and struct

2011-05-02 Thread Mariusz Gliwiński
Firstly, thanks for comprehensive answer and I'd like to excuse for my 
stupid mistakes, which are caused by learning a lot and not actually 
programming.


On date 2011-05-02 23:03, Jonathan M Davis wrote:

Classes are reference types and are meant to be on the heap.

Yeah, value vs reference semantics - that was the thing i forgot...

So, if you're using a scoped class, you're _not_ getting the benefits of
polymorphism.
I completely didn't think about, that stack size needs to be known 
already at time of compiling. You just probably saved me a lot of problems.



So, scoped classes can't be used for filling gap in struct inheritance.

I'll clarify myself:
All i would need is extending - without polymorphism.
Containment, can be solution for fields which doesn't annoys so much 
(although image in auto-generated documentation, just like it's with 
subclassing, would be nice).
Unfortunately, the worse case is about methods, which have to be 
manually forwarded to contained struct.


So, does someone sees any nice solution for method forwarding as 
described? Should i make use of some mixin's?


Thanks,
Mariusz Gliwiński


Re: Difference between stack-allocated class and struct

2011-05-02 Thread Jonathan M Davis
> Firstly, thanks for comprehensive answer and I'd like to excuse for my
> stupid mistakes, which are caused by learning a lot and not actually
> programming.
> 
> On date 2011-05-02 23:03, Jonathan M Davis wrote:
> > Classes are reference types and are meant to be on the heap.
> 
> Yeah, value vs reference semantics - that was the thing i forgot...
> 
> > So, if you're using a scoped class, you're _not_ getting the benefits of
> > polymorphism.
> 
> I completely didn't think about, that stack size needs to be known
> already at time of compiling. You just probably saved me a lot of problems.
> 
> 
> So, scoped classes can't be used for filling gap in struct inheritance.
> 
> I'll clarify myself:
> All i would need is extending - without polymorphism.
> Containment, can be solution for fields which doesn't annoys so much
> (although image in auto-generated documentation, just like it's with
> subclassing, would be nice).
> Unfortunately, the worse case is about methods, which have to be
> manually forwarded to contained struct.
> 
> So, does someone sees any nice solution for method forwarding as
> described? Should i make use of some mixin's?

alias this is supposed to be one of the better solutions for dealing with the 
sort of problem that you're looking at. Unfortunately, it's highly buggy at 
the moment, so it's questionable as to whether it would work. And even if it 
works, you can currently only have one alias this per type, so if you need 
more than that, you'd need another solution (eventually, alias this should 
work just fine, and you should be able to have multiple of them per type, but 
not yet).

At the moment, you pretty much need to do manual forwarding. Now, with the 
clever use of compile-time reflection via __traits and/or std.traits along 
with template mixins or string mixins, you should be able to get the compiler 
to generate all of the forwarded functions for you, but you'd still have to 
write the code for generating the mixins, which could be somewhat tricky. If 
you get it right though, then it would generate all of the appropriate 
functions regardless of whether any are added to or removed from the type that 
you're forwarding function calls to.

- Jonathan M Davis


Re: Difference between stack-allocated class and struct

2011-05-02 Thread Piotr Szturmaj

Mariusz Gliwiński wrote:

I'll clarify myself:
All i would need is extending - without polymorphism.
Containment, can be solution for fields which doesn't annoys so much
(although image in auto-generated documentation, just like it's with
subclassing, would be nice).
Unfortunately, the worse case is about methods, which have to be
manually forwarded to contained struct.

So, does someone sees any nice solution for method forwarding as
described? Should i make use of some mixin's?


You can use 'alias this':

http://www.digitalmars.com/d/2.0/class.html#AliasThis


Re: Difference between stack-allocated class and struct

2011-05-02 Thread Sean Cavanaugh
Here is my prototype COM compile-time reflection based wrapper mixin 
(which I have abandoned in favor of alias this since it covers 95% of my 
use cases even though it isn't perfectly safe).  I am new at D so you 
have been warned, though this part of the language seems pretty 
straightforward enough.  It is possible the track down the argument 
names but takes some rather intricate parsing to do correctly (and the 
example someone linked me in another thread of mine chocked on const 
types due to parsing bugs).



http://snipt.org/xsu


The wrapped interface also needs to be a mixin so it can be created in 
the correct module, with visibility to all the types passed to the 
interface's methods.



So something like the following is going to fail miserably unless ComPtr 
is also made into a mixin and instantiated in the correct module.



struct ComPtr(T)
{
public:
T m_Pointer;
mixin(WrapComInterface!(T)("m_Pointer")
};