Re: opCmp with structs

2015-11-10 Thread anonymous via Digitalmars-d-learn

On 07.11.2015 16:59, anonymous wrote:

Wat. It even compiles with @safe. That's not good.


Filed an issue:
https://issues.dlang.org/show_bug.cgi?id=15315


Re: opCmp with structs

2015-11-07 Thread Alex via Digitalmars-d-learn

Ok... found the solution. The technical at least.

import std.algorithm;
import std.range;
void main(){
ku[] tt = [ku(2), ku(1)];
//writeln(tt);
auto index3 = new size_t[tt.length];
makeIndex!("a.id < b.id")(tt, index3);
auto ind = indexed(tt, index3);
//writeln(ind);
}

This yield in 'ind' the array of 'tt', ordered in the expected 
way.

So, the remaining open questions are just ideologic now...

Thanks for helping and commenting!


Re: opCmp with structs

2015-11-07 Thread Alex via Digitalmars-d-learn

Found something useful, here:
http://dlang.org/phobos/std_algorithm_sorting.html#makeIndex

with that I can achieve the following
void main(){
ku[] tt = [ku(2), ku(1)];
//writeln(tt);
auto index3 = new size_t[tt.length];
makeIndex!("a.id < b.id")(tt, index3);
//writeln(index3);
}

so my index3 contains the right permutation of the tt array.
What I still need is the possibility to take the values of the tt 
array in the order of the generated index. Can somebody give a 
hint how to achieve this?


Re: opCmp with structs

2015-11-07 Thread anonymous via Digitalmars-d-learn

On 07.11.2015 15:36, Mike Parker wrote:

It's actually possible to use move one instance
into another, though:

void main() {
 import std.algorithm : move;
 ku k1 = ku(1);
 ku k2 = ku(2);
 k2.move(k1);
 assert(k1.id == 2);
}


Wat. It even compiles with @safe. That's not good.


Re: opCmp with structs

2015-11-07 Thread Alex via Digitalmars-d-learn

On Saturday, 7 November 2015 at 14:36:25 UTC, Mike Parker wrote:



So my general question is: why immutable variables shouldn't 
be able to be moved (inside an array)?


To be pedantic, sort isn't actually moving anything. It's 
reassigning elements, i.e. a[1] = a[2]. The immutable member 
makes it illegal to assign one instance of ku to another:
But sort doesn't work that way. You'll need to take a different 
approach to sort an array of ku.


Yeah... and I'm in the acceptance phase now ;) Do you have a 
hint, how this approach could be like?


Re: opCmp with structs

2015-11-07 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 7 November 2015 at 11:48:56 UTC, Alex wrote:



So my general question is: why immutable variables shouldn't be 
able to be moved (inside an array)?


To be pedantic, sort isn't actually moving anything. It's 
reassigning elements, i.e. a[1] = a[2]. The immutable member 
makes it illegal to assign one instance of ku to another:


void main() {
ku k = ku(1);
k = ku(2);
}

That's why it's failing. It's actually possible to use move one 
instance into another, though:


void main() {
import std.algorithm : move;
ku k1 = ku(1);
ku k2 = ku(2);
k2.move(k1);
assert(k1.id == 2);
}

But sort doesn't work that way. You'll need to take a different 
approach to sort an array of ku.





Re: opCmp with structs

2015-11-07 Thread Alex via Digitalmars-d-learn

On Saturday, 7 November 2015 at 00:19:56 UTC, Ali Çehreli wrote:

Continuing from your hint: So, opCmp works but it is sort() 
that cannot move objects of ku around because of that immutable 
variable.


So my general question is: why immutable variables shouldn't be 
able to be moved (inside an array)?


There may be references to ku objects or its id members and 
those references may be depending on the immutability of that 
member. const and immutable members effectively make objects 
unassignable. (const part is the same in C++.)


And this is also something unexpected: yes, there may be such 
references and they should stay valid of course. But why 
shouldn't be a concrete collection of such references be 
sortable? Why this should affect other references to the 
individual 'ku' objects?


Re: opCmp with structs

2015-11-07 Thread Alex via Digitalmars-d-learn

On Saturday, 7 November 2015 at 10:24:03 UTC, BBaz wrote:


void main()
{
ku*[] tt = [new ku(2),new  ku(1)];
sort(tt);
}


Don't really like this ;) not because
writeln(tt);
doesn't work any more, but because I have to think about where to 
use pointers and where not...





Re: opCmp with structs

2015-11-07 Thread BBaz via Digitalmars-d-learn

On Saturday, 7 November 2015 at 10:15:25 UTC, Alex wrote:
So the question remains, how to sort? Do you think removing the 
immutable property from an id is the semantically right way? Or 
do you have a hint, maybe something like, a dup copy with 
removing immutability and returning a new, sorted copy? If you 
think the latter is the way to choose, how is the syntax there? 
;)


This fails because in sort() a struct is considered as a value, 
so the instance are not moved, it looks like this() is called 
using the instance of another slot.


So to get rid of that use some pointer to struct, here when 
sort() will have to move it'll move the reference:


---
import std.stdio;
import std.algorithm;

struct ku
{
immutable int id;
alias id this;

this(int i)
{
id = i;
}

int opCmp(ref const ku rhs) const {return id - rhs.id; }
}

void main()
{
ku*[] tt = [new ku(2),new  ku(1)];
sort(tt);
}
---



Re: opCmp with structs

2015-11-07 Thread Alex via Digitalmars-d-learn

Ok, ok... I see the direction, but I still miss something:
From the point of view of "Programming in D", chapter 33.3, 
"Immutability of the slice vs the elements":


I don't want to have an immutable slice but immutable elements. 
And your answers imply that sorting not only modify the slice 
itself but also mutate the elements. This is a little bit 
strange, in my opinion, as sorting modifies only relationships 
between the sorted elements not the elements itself. At least in 
my head, at least for the moment :)


A test says the same thing:

void main()
{
immutable int[] immSlice = [2, 1];
sort(immSlice);
}

and

void main()
{
immutable(int)[] immSlice = [2, 1];
sort(immSlice);
}

both give errors:
Error: template std.algorithm.sorting.sort cannot deduce function 
from argument types !()(immutable(int[]))

and
Error: template std.algorithm.sorting.sort cannot deduce function 
from argument types !()(immutable(int)[])

respectively.

So the question remains, how to sort? Do you think removing the 
immutable property from an id is the semantically right way? Or 
do you have a hint, maybe something like, a dup copy with 
removing immutability and returning a new, sorted copy? If you 
think the latter is the way to choose, how is the syntax there? ;)


Re: opCmp with structs

2015-11-06 Thread BBaz via Digitalmars-d-learn

On Friday, 6 November 2015 at 22:55:15 UTC, Alex wrote:

Ok... the question is not silly any more...
without 'immutable' it works. So, what am I missing?


sorry, again a forum bug that stripped my answer:

sort() fails because in the template constraint 
`hasAssignableElements` fails.
hasAssignableElements fails because of this you cannot assign 
another value to a ku because the immutable member is already 
defined.

---
template hasAssignableElements(R)
{
enum bool hasAssignableElements = isInputRange!R && is(typeof(
(inout int = 0)
{
R r = R.init;
r.front = r.front;
static if (isBidirectionalRange!R) r.back = r.front;
static if (isRandomAccessRange!R) r[0] = r.front;
}));
}
---

more especially this is 'r.front = r.front;' that doesn't pass:

---
import std.range;

struct ku
{
immutable int id;
}

void main()
{
ku[] tt;
tt.front = tt.front;
}
---

so yeah, it cant work if id is immutable.


Re: opCmp with structs

2015-11-06 Thread BBaz via Digitalmars-d-learn

On Friday, 6 November 2015 at 22:55:15 UTC, Alex wrote:

Ok... the question is not silly any more...
without 'immutable' it works. So, what am I missing?


sort() fails because in the template constraint 
`hasAssignableElements


Re: opCmp with structs

2015-11-06 Thread Ali Çehreli via Digitalmars-d-learn

On 11/06/2015 02:54 PM, Alex wrote:
> I'm sure I'm doing a silly mistake somewhere, but why this doesn't work?
> import std.stdio;
> import std.algorithm;
>
> struct ku
> {
>  immutable int id;
>  alias id this;
>
>  this(int i)
>  {
>  id = i;
>  }
>
>  int opCmp(ref const ku rhs) const {return id - rhs.id; }
> }
>
> void main()
> {
>  ku[] tt = [ku(2), ku(1)];
>  sort(tt);
> }

Continuing from your hint: So, opCmp works but it is sort() that cannot 
move objects of ku around because of that immutable variable.


There may be references to ku objects or its id members and those 
references may be depending on the immutability of that member. const 
and immutable members effectively make objects unassignable. (const part 
is the same in C++.)


Ali



Re: opCmp with structs

2015-11-06 Thread Alex via Digitalmars-d-learn

Ok... the question is not silly any more...
without 'immutable' it works. So, what am I missing?


opCmp with structs

2015-11-06 Thread Alex via Digitalmars-d-learn
I'm sure I'm doing a silly mistake somewhere, but why this 
doesn't work?

import std.stdio;
import std.algorithm;

struct ku
{
immutable int id;
alias id this;

this(int i)
{
id = i;
}

int opCmp(ref const ku rhs) const {return id - rhs.id; }
}

void main()
{
ku[] tt = [ku(2), ku(1)];
sort(tt);
}