Re: How should I sort a doubly linked list the D way?

2019-08-13 Thread Mike Parker via Digitalmars-d-learn
On Tuesday, 13 August 2019 at 22:12:23 UTC, Mirjam Akkersdijk 
wrote:



Though, it left me with some semi-offtopic questions unanswered:

(1) Ali, do you mean that from an optimization viewpoint, it's 
better to keep appending like `nodes ~= ...` instead of setting 
the length first? I would like to have some more background on 
that claim.


He's not saying it will be better, but that the cost will be 
negligible. On every append, the GC allocates new memory only if 
the current capacity == 0. When it does allocate, it allocates 
more space than it actually needs based on the current length of 
the array, so you don't actually have an allocation on every 
append. Also, when the adjacent memory block is free and can hold 
the additional elements, the allocation consists of extending the 
array's memory block and no copying is performed, making the cost 
of the allocation even cheaper than it could be.


Anyway, you can use `reserve` when appending rather than setting 
the length. This will allocate enough memory without 
default-initializing anything and you don't have to worry about 
bounds checking.


int[] ints;
ints.reserve(100);
foreach(i; 0..100) {
ints ~= i;
}


See Steve Schveighoffer's array article for details:

https://dlang.org/articles/d-array-article.html


Re: How should I sort a doubly linked list the D way?

2019-08-13 Thread Mirjam Akkersdijk via Digitalmars-d-learn

On Tuesday, 13 August 2019 at 21:11:41 UTC, H. S. Teoh wrote:
A contiguous allocator doesn't help after the list has 
undergone a large number of insertions/deletions, because of 
fragmentation.
Fragmentation should not be an issue, I insist on keep using a 
DLL for the base structure in my application and create an array 
just for sorting operations. No new nodes are added and no nodes 
are permanently removed.


You can still get a cache-efficient linked list by chunking. 
[...]
I very much appreciate this thought, as I was thinking of adding 
such kind of cache to my implementation. It's still in the early 
stages and I have yet to see when this would make a considerable 
impact. I will remember this.


Re: How should I sort a doubly linked list the D way?

2019-08-13 Thread Mirjam Akkersdijk via Digitalmars-d-learn

On Tuesday, 13 August 2019 at 18:28:35 UTC, Ali Çehreli wrote:

> can't I define an array of fixed size, which is dependent on
the input
> of the function?

arr.length = number_of_elements;

All elements will be initialized to the element's default 
value, which happens to be null for pointers. (If we are back 
to linked list Node pointers.)


However, I wouldn't bother with setting length either as the 
cost of automatic array resizing is amortized, meaning that it 
won't hurt the O(1) algorithmic complexity in the general case. 
In the GC case that D uses, it will be even better: because if 
the GC knowns that the neighboring memory block is free, it 
will just add that to the dynamic array's capacity without 
moving elements to the new location.


For the application I am writing, it makes very much sense to use 
a DLL. The approach I am using right now is to: (as stated in the 
first post)


void bsort(DLL* list) {
  Node*[] nodes;

  foreach (i; 0 .. list.size)
nodes ~= get_node(list, i);

  nodes.sort!("a.x < b.x");
  // (unrelated data structure cleaning up goes here)
}

My concern was that using a dynamic array, continuously appending 
to it despite known size, would greatly impact overall 
performance. My goal is to make this operation as fast as 
possible, the D way.


I tried setting the length first and iterating through it with 
`nodes[i] = ...` and the implementation did not run noticeably 
faster (10 trials), per Teoh's advice to test out the difference.
For now, I consider this a success and would like to thank 
everyone in the thread for assistance and valuable insights.


Though, it left me with some semi-offtopic questions unanswered:

(1) Ali, do you mean that from an optimization viewpoint, it's 
better to keep appending like `nodes ~= ...` instead of setting 
the length first? I would like to have some more background on 
that claim.


(2) I watched the talk and read the paper [1] to be sure. Many 
contributors to this thread claim (C++) vectors are nearly always 
the preferred choice compared to DLLs, but how come they are much 
faster compared to DLLs, given they have nearly the same 
functionality?


(3) And I sense this is very closely related to what Ali is on?

[1] http://www.stroustrup.com/Software-for-infrastructure.pdf


Re: How should I sort a doubly linked list the D way?

2019-08-13 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Aug 13, 2019 at 08:42:37PM +, Max Haughton via Digitalmars-d-learn 
wrote:
> On Tuesday, 13 August 2019 at 18:54:58 UTC, H. S. Teoh wrote:
[...]
> > These days, with CPU multi-level caches and memory access
> > predictors, in-place arrays are often the best option for
> > performance, up to a certain size.  In general, avoid indirection
> > where possible, in order to avoid defeating the memory access
> > predictor and reduce the number of cache misses.
[...]
> I saw a Bjarne Stroustrup talk where he benchmarked that the for n >
> 1, std::vector was a lot faster than a linked list for all supported
> operations. I don't know how clever the caching strategies are on a
> modern processor (Pointer chasing), but to my knowledge the only way
> of getting a cache efficient linked list would be to effectively have
> a very contiguous allocator (Which obviously defeats the purpose of
> using a list in the first place)
> 
> Found it: https://www.youtube.com/watch?v=YQs6IC-vgmo

A contiguous allocator doesn't help after the list has undergone a large
number of insertions/deletions, because of fragmentation.

You can still get a cache-efficient linked list by chunking. I.e.,
instead of a linked-list of individual elements, group the elements into
blocks (arrays) that are then linked into a linked list.  Then you can
still insert/delete elements with sub-O(1) complexity by updating only
the affected block, and only occasionally you need to delete a block or
allocate a new block.

As long as the block size is suitably-sized, it will be cache-coherent
most of the time and enjoy the associated performance boosts from the
cache hierarchy.  For small lists, it will be equivalent to using a
single array. For very large lists, you'll also reap the cheap
insert/delete flexibility of a linked list.

To minimize space wastage from unused slots in the blocks, you could
have a list rebalancing based on some desired utilization factor (e.g.,
if <50% of a block is used, redistribute elements among adjacent
blocks). Redistribution should be pretty cache-coherent (except perhaps
for some corner cases), because it mostly involves linear copying of
elements from one block to another.


T

-- 
I am not young enough to know everything. -- Oscar Wilde


Re: How should I sort a doubly linked list the D way?

2019-08-13 Thread Max Haughton via Digitalmars-d-learn

On Tuesday, 13 August 2019 at 18:54:58 UTC, H. S. Teoh wrote:
On Tue, Aug 13, 2019 at 11:28:35AM -0700, Ali Çehreli via 
Digitalmars-d-learn wrote: [...]
Summary: Ditch the linked list and put the elements into an 
array. :)

[...]

+1.  The linked list may have been faster 20 years ago, before 
the advent of modern CPUs with caching hierarchies and memory 
access predictors.


These days, with CPU multi-level caches and memory access 
predictors, in-place arrays are often the best option for 
performance, up to a certain size.  In general, avoid 
indirection where possible, in order to avoid defeating the 
memory access predictor and reduce the number of cache misses.



T


I saw a Bjarne Stroustrup talk where he benchmarked that the for 
n > 1, std::vector was a lot faster than a linked list for all 
supported operations. I don't know how clever the caching 
strategies are on a modern processor (Pointer chasing), but to my 
knowledge the only way of getting a cache efficient linked list 
would be to effectively have a very contiguous allocator (Which 
obviously defeats the purpose of using a list in the first place)


Found it: https://www.youtube.com/watch?v=YQs6IC-vgmo


Re: How should I sort a doubly linked list the D way?

2019-08-13 Thread Sebastiaan Koppe via Digitalmars-d-learn

On Tuesday, 13 August 2019 at 18:28:35 UTC, Ali Çehreli wrote:

On Tuesday, 13 August 2019 at 14:04:45 UTC, Sebastiaan Koppe
> wrote:
> Convert the nodes into an D array, sort the array with 
> nodes.sort!"a.x < b.x" and then iterate the array and repair 
> the next/prev pointers.


If possible, I would go further and ditch the linked list 
altogether: Just append the nodes to an array and then sort the 
array. It has been shown in research, conference presentations, 
and in personal code to be the fasted option is most (or all) 
cases.




Yeah, very likely. Although in this case there already is an 
array; it's going to be close :)


Re: How should I sort a doubly linked list the D way?

2019-08-13 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Aug 13, 2019 at 11:28:35AM -0700, Ali Çehreli via Digitalmars-d-learn 
wrote:
[...]
> Summary: Ditch the linked list and put the elements into an array. :)
[...]

+1.  The linked list may have been faster 20 years ago, before the
advent of modern CPUs with caching hierarchies and memory access
predictors.

These days, with CPU multi-level caches and memory access predictors,
in-place arrays are often the best option for performance, up to a
certain size.  In general, avoid indirection where possible, in order to
avoid defeating the memory access predictor and reduce the number of
cache misses.


T

-- 
"If you're arguing, you're losing." -- Mike Thomas


Re: How should I sort a doubly linked list the D way?

2019-08-13 Thread Ali Çehreli via Digitalmars-d-learn

On 08/13/2019 10:33 AM, Mirjam Akkersdijk wrote:
> On Tuesday, 13 August 2019 at 14:04:45 UTC, Sebastiaan Koppe wrote:

>> Convert the nodes into an D array, sort the array with nodes.sort!"a.x
>> < b.x" and then iterate the array and repair the next/prev pointers.

If possible, I would go further and ditch the linked list altogether: 
Just append the nodes to an array and then sort the array. It has been 
shown in research, conference presentations, and in personal code to be 
the fasted option is most (or all) cases.


> doesn't the nature of the dynamic array slow it down a bit?

Default bounds checking is going to cost a tiny bit, which you can turn 
off after development with a compiler flag. (I still wouldn't.)


The only other option that would be faster is an array that's sitting on 
the stack, created with alloca. But it's only for cases where the thread 
will not run out of stack space and the result of the array is not going 
to be used.


> can't I define an array of fixed size, which is dependent on the input
> of the function?

arr.length = number_of_elements;

All elements will be initialized to the element's default value, which 
happens to be null for pointers. (If we are back to linked list Node 
pointers.)


However, I wouldn't bother with setting length either as the cost of 
automatic array resizing is amortized, meaning that it won't hurt the 
O(1) algorithmic complexity in the general case. In the GC case that D 
uses, it will be even better: because if the GC knowns that the 
neighboring memory block is free, it will just add that to the dynamic 
array's capacity without moving elements to the new location.


Summary: Ditch the linked list and put the elements into an array. :)

Ali



Re: How should I sort a doubly linked list the D way?

2019-08-13 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Aug 13, 2019 at 12:12:28PM -0600, Jonathan M Davis via 
Digitalmars-d-learn wrote:
> On Tuesday, August 13, 2019 11:33:10 AM MDT Mirjam Akkersdijk via 
> Digitalmars-d-learn wrote:
[...]
> > Thank you, this is what I eventually chose to do. It's also fairly
> > fast, though doesn't the nature of the dynamic array slow it down a
> > bit? Since I already know the size of the array (but just not at
> > compile time), can't I define an array of fixed size, which is
> > dependent on the input of the function?
> 
> In D, static arrays must know their length at compile time. Dynamic
> arrays can have their length determined at runtime. I don't know why a
> dynamic array would slow anything down here though - especially if you
> just allocate it with the correct length.
[...]

When it comes down to fine points concerning performance like here, my
default response is: are you sure this is an *actual* performance hit?
Did you run a profiler to measure the actual runtimes?

Static arrays have the advantage that the size is known at compile-time,
so the compiler can generate better code (by hard-coding the length,
optimizing the memory layout, etc.).  But when you pass static arrays
around, you have to either slice them, in which case they become
identical to dynamic arrays anyway, or pass them on the stack, which in
some cases can actually slow things down (you have to copy a potentially
large amount of data to/from the stack when passing arguments to a
function). Passing a dynamic array (or a slice of a static array) is
very fast: it's just a pointer + size pair.

Dynamic arrays could potentially incur performance hits if you're
appending to them (may need a GC allocation).  Static arrays don't have
this problem -- but then you can't append to a static array at all. :-P

Anyway, splitting hairs over whether to use static arrays or dynamic
arrays sounds like premature optimization to me.  Before worrying about
potential performance problems with using dynamic arrays, always use a
profiler to see if the bottleneck is actually in that part of the code.
Otherwise it's just a waste of time and energy to "optimize" the code
when it isn't even anywhere near the real bottleneck(s) in the program.

Profile, profile, profile. Until then, don't sweat it over optimization.


T

-- 
Mediocrity has been pushed to extremes.


Re: How should I sort a doubly linked list the D way?

2019-08-13 Thread Johannes Loher via Digitalmars-d-learn
Am 13.08.19 um 11:48 schrieb Mirjam Akkersdijk:
> Hello there,
> If I had a DLL, how would I sort it judging by the node contents, the D
> way?
> 
> In C if I were to sort a piece of malloc'd memory pointing to node
> pointers, I would write my compare function and let qsort sort it out.
> In D, I tried to use std.algorithm's sort functionality to no avail,
> because my guess would be it only operates on arrays. This opens up
> another can of worms as I am not fond of VLAs and D desperately wants to
> know what the size is at compile time.
> 
> Let's say we this trivial implementation:
> 
> Node* get_node(DLL* list, uint index);
> 
> struct Node {
>   int x;
>   Node* prev, next;
> };
> 
> struct DLL {
>   Node* head;
>   uint size;
> };
> 
> Node** nodes = cast(Node**) malloc(DLL.size * (Node*).sizeof);
> 
> and I would like to sort based on Node.t, how should I tackle it,
> preferably without resorting to C libraries?

I'd do something along the lines of this:

```
import std;

struct Node(T)
{
private:
typeof(this)* prev, next;
public:
T data;
}

struct DoublyLinkedList(T)
{
private:
Node!T* head = null;
Node!T* tail = null;

public:
void pushFront(T t)
{
auto n = new Node!T;
if (head != null)
{
head.prev = n;
}
else
{
tail = n;
}
n.data = t;
n.next = head;
head = n;
}

T front() const @property
{
return head.data;
}

void popFront()
{
head = head.next;
if (head != null)
{
head.prev = null;
}
else
{
tail = null;
}
}

void pushBack(T t)
{
auto n = new Node!T;
if (tail != null)
{
tail.next = n;
}
else
{
head = n;
}
n.data = t;
n.prev = tail;
tail = n;
}

T back() const @property
{
return tail.data;
}

void popBack()
{
tail = tail.prev;
if (tail != null)
{
tail.next = null;
}
else
{
head = null;
}
}

size_t empty() const @property
{
return head == null;
}

auto nodes() @property
{
static struct NodePointerRange
{
private:
Node!T* head;

public:
Node!T* front() @property
{
return head;
}

void popFront()
{
head = head.next;
}

bool empty() const @property
{
return head == null;
}
}

return NodePointerRange(head);
}
}

auto doublyLinkedList(R)(R r) if (isInputRange!R)
{
DoublyLinkedList!(ElementType!R) list;

foreach (e; r)
{
list.pushBack(e);
}
return list;
}

auto doublyLinkedListFromNodePointerRange(R)(R r)
if (isInputRange!R && isPointer!(ElementType!R)
&& isInstanceOf!(Node, PointerTarget!(ElementType!R)))
{
DoublyLinkedList!(TemplateArgsOf!(PointerTarget!(ElementType!R))) list;
foreach (n; r)
{
n.prev = list.tail;
if (list.tail != null)
{
list.tail.next = n;
}
else
{
list.head = n;
}
list.tail = n;
}
list.tail.next = null;
return list;
}

void main()
{
auto list = doublyLinkedList([5, 3, 7, 24, 1]);
// looks natural but allocates new nodes
auto sortedList = list.array.sort.doublyLinkedList;
sortedList.each!writeln;

writeln;

auto anotherList = doublyLinkedList([54, 23, 8]);
// looks a bit uglier but reuses the already allocated nodes
auto anotherSortedList = anotherList.nodes
.array
.sort!((n1, n2) => n1.data < n2.data)
.doublyLinkedListFromNodePointerRange;
anotherSortedList.each!writeln;
}
```

Modulo bugs of course ;)

This uses the GC. If you want to avoid it in favor of malloc (or
std.experimental.allocator), you need to add `free`s (and possibly
referece counting) accordingly.




Re: How should I sort a doubly linked list the D way?

2019-08-13 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, August 13, 2019 11:33:10 AM MDT Mirjam Akkersdijk via 
Digitalmars-d-learn wrote:
> On Tuesday, 13 August 2019 at 14:04:45 UTC, Sebastiaan Koppe
>
> wrote:
> > On Tuesday, 13 August 2019 at 09:48:52 UTC, Mirjam Akkersdijk
> >
> > wrote:
> >> and I would like to sort based on Node.t, how should I tackle
> >> it, preferably without resorting to C libraries?
> >
> > Convert the nodes into an D array, sort the array with
> > nodes.sort!"a.x < b.x" and then iterate the array and repair
> > the next/prev pointers.
>
> Thank you, this is what I eventually chose to do. It's also
> fairly fast, though doesn't the nature of the dynamic array slow
> it down a bit? Since I already know the size of the array (but
> just not at compile time), can't I define an array of fixed size,
> which is dependent on the input of the function?

In D, static arrays must know their length at compile time. Dynamic arrays
can have their length determined at runtime. I don't know why a dynamic
array would slow anything down here though - especially if you just allocate
it with the correct length. Appending each element individually instead of
allocating the full dynamic array and then setting each element would
certainly be slower, but once the dynamic array is fully allocated, as far
as accessing elements go, accessing a dynamic array and static array should
be basically the same. The only real difference is that one would have its
elements on the stack, whereas the other would have them on the heap. Even
if you used a static array, you'd have to slice it to pass to sort, which
would mean that you'd be passing it a dynamic array. A dynamic array is
basically just a struct with a pointer and a length. e.g.

struct DynamicArray(T)
{
size_t length;
T* ptr;
}

and accessing its elements is the same as you'd get with a pointer in C
except for the fact that in @safe code, the bounds are checked when indexing
elements. The only thing about dynamic arrays that can get slow is if you're
doing a lot of appending to them, because then it has to keep checking to
see whether it can expand in place or has to allocate a new block of memory
and copy the elements. In that respect, it's similar to C++'s std::vector.

- Jonathan M Davis





Re: How should I sort a doubly linked list the D way?

2019-08-13 Thread Mirjam Akkersdijk via Digitalmars-d-learn
On Tuesday, 13 August 2019 at 14:04:45 UTC, Sebastiaan Koppe 
wrote:
On Tuesday, 13 August 2019 at 09:48:52 UTC, Mirjam Akkersdijk 
wrote:
and I would like to sort based on Node.t, how should I tackle 
it, preferably without resorting to C libraries?


Convert the nodes into an D array, sort the array with 
nodes.sort!"a.x < b.x" and then iterate the array and repair 
the next/prev pointers.


Thank you, this is what I eventually chose to do. It's also 
fairly fast, though doesn't the nature of the dynamic array slow 
it down a bit? Since I already know the size of the array (but 
just not at compile time), can't I define an array of fixed size, 
which is dependent on the input of the function?


Re: How should I sort a doubly linked list the D way?

2019-08-13 Thread Mirjam Akkersdijk via Digitalmars-d-learn

On Tuesday, 13 August 2019 at 12:34:46 UTC, bachmeier wrote:
I'm confused by this statement. Are you referring to the qsort 
in C's stdlib? I had never heard of using that to sort a linked 
list, so I searched, and it is not possible.


Ah yes, maybe I should have elaborated. In C, you can just create 
an array


(1) struct Node* nodes[buf_size];

and then loop over it, filling it with

(2) nodes[i] = (DLLbuf + i * sizeof(struct Node));

subsequently calling our dear friend from stdlib

(3) qsort(nodes, buf_size, sizeof(struct Node*), 
buf_compare_function);


You can then rechain all nodes together but that's a bit out of 
scope for this thread unless you do really want me to work it out 
:)


But I was looking for a more D-specific approach to solve this, 
as it feels archaic to do it the C way. If there is anyone with a 
better one please let me know.


Re: How should I sort a doubly linked list the D way?

2019-08-13 Thread Sebastiaan Koppe via Digitalmars-d-learn
On Tuesday, 13 August 2019 at 09:48:52 UTC, Mirjam Akkersdijk 
wrote:
and I would like to sort based on Node.t, how should I tackle 
it, preferably without resorting to C libraries?


Convert the nodes into an D array, sort the array with 
nodes.sort!"a.x < b.x" and then iterate the array and repair the 
next/prev pointers.


Re: How should I sort a doubly linked list the D way?

2019-08-13 Thread bachmeier via Digitalmars-d-learn
On Tuesday, 13 August 2019 at 09:48:52 UTC, Mirjam Akkersdijk 
wrote:



I would write my compare function and let qsort sort it out.


I'm confused by this statement. Are you referring to the qsort in 
C's stdlib? I had never heard of using that to sort a linked 
list, so I searched, and it is not possible.


https://cboard.cprogramming.com/c-programming/64520-sorting-linked-list-qsort.html
https://stackoverflow.com/questions/7091685/doesnt-qsort-c-library-function-work-on-linked-lists:
 "qsort works on plain arrays of equally sized data, not linked lists"




Re: Local static class fields

2019-08-13 Thread Simen Kjærås via Digitalmars-d-learn

On Tuesday, 13 August 2019 at 08:41:02 UTC, Bert wrote:

On Tuesday, 13 August 2019 at 04:43:29 UTC, Paul Backus wrote:
It seems to me like the obvious solution is to use two 
different classes, one to store the global state, and one to 
store the individual objects in your structure. For example:


class Tree {
State state;
Node root;
}

class Node {
Node[] children;
}


Yes, I forgot to mention this as a solution.

I was going to go in to more detail. This is not a great 
solution because it requires a base class simply to hold the 
"global" state and it requires nodes to have an accessor(they 
won't know which tree they come from).


What you're essentially looking at here is my solution 4):

class Node {
Node parent;
Node[] children;
@property State state() {
return parent.state;
}
}

class Root : Node {
State treeState;
override @property State state() {
return treeState;
}
}

class State {}



What I was thinking though, with D's capabilities, if a 
constructor could somehow return a "Voldemort" type that makes 
it all work out.


e.g.,

class Tree {
State state;
Node root;
alias root this;
}

then the constructor just returns tree which acts as an node.

It doesn't have to be a voldemort but it at least hides some of 
the details...


Ultimately it is not too different from using a dictionary 
though, effectively does the same thing.


Something like this may be possible, but it will still need to 
keep around a pointer to the context (likely the root), costing 
you the exact same as having a pointer to either the root or the 
state in each node:


class Root {
State state;
this() { state = new State(); }
auto newNode() {
class Node {
State getState() { return state; }
}
return new Node();
}
}

class State { }

unittest {
auto root1 = new Root();
auto node = root1.newNode();

assert(node.getState() == root1.state);
// Note that Node keeps track of its context, thus taking up 
more space:
assert(__traits(classInstanceSize, typeof(node)) > 
__traits(classInstanceSize, State));

}


There may be no way around such a problem in that these might 
be "optimal". Your's, which added parent in node, might be 
better since a dictionary doesn't have to be directly 
maintained.


Also, if space is a concern, the dictionary is actually worse 
than adding a pointer to the state in each node, as the internal 
book-keeping of the dictionary is more than one pointer's worth 
per entry (at the very least it needs to keep both the hash of 
the Node and the pointer to the state).



I'd like to get away from actually having a different "root" 
type though. Mainly because it reduces uniformity and 
complicates the design I already have. If I could hide all 
these things and it is not too complicated then it would work 
better for me.


The solution of having a Root class that derives from Node causes 
complications in three situations: When you create a new tree, 
when you move a subtree to become a new tree, and when you move a 
tree to become a subtree. The last two may or may not actually 
occur in your code, but without knowing more, I have no idea if 
that's the case. I'm fairly certain you will at some point be 
creating new trees, though. If the creation of new trees is 
confined to one or two functions while the creation of new nodes 
is widespread, this special-casing of roots should be easily 
manageable.


However, since you specifically mention in this post that Paul 
'added parent in node', you should definitely go with a pointer 
to the state in the Node, as per my earlier post. It's faster, 
you pay the memory cost anyway, and it's easy for maintainers 
(that's you in 6 months cursing your young-and-careless self) to 
understand what's going on.


Actually, there's one complication with having a pointer to the 
state in each node that we haven't mentioned: is the state often 
replaced wholesale? That is, not just its contents changed, but 
can the state of a tree suddenly point to a wholly different 
instance of the same class? If each node holds a pointer to it, 
then this operation is costly. However, this is generally easy to 
fix/avoid by a) favor mutation over reassignment, or b) another 
layer of indirection.


--
  Simen


Re: How should I sort a doubly linked list the D way?

2019-08-13 Thread ikod via Digitalmars-d-learn
On Tuesday, 13 August 2019 at 09:48:52 UTC, Mirjam Akkersdijk 
wrote:

Hello there,
If I had a DLL, how would I sort it judging by the node 
contents, the D way?


In C if I were to sort a piece of malloc'd memory pointing to 
node pointers, I would write my compare function and let qsort 
sort it out. In D, I tried to use std.algorithm's sort 
functionality to no avail, because my guess would be it only 
operates on arrays. This opens up another can of worms as I am 
not fond of VLAs and D desperately wants to know what the size 
is at compile time.


You can check std.container.rbtree which will build sorted "list" 
for you on every Node insert. Again, not sure how this can be 
done at compile time.


Re: How should I sort a doubly linked list the D way?

2019-08-13 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, August 13, 2019 3:48:52 AM MDT Mirjam Akkersdijk via 
Digitalmars-d-learn wrote:
> Hello there,
> If I had a DLL, how would I sort it judging by the node contents,
> the D way?
>
> In C if I were to sort a piece of malloc'd memory pointing to
> node pointers, I would write my compare function and let qsort
> sort it out. In D, I tried to use std.algorithm's sort
> functionality to no avail, because my guess would be it only
> operates on arrays. This opens up another can of worms as I am
> not fond of VLAs and D desperately wants to know what the size is
> at compile time.
>
> Let's say we this trivial implementation:
>
> Node* get_node(DLL* list, uint index);
>
> struct Node {
>int x;
>Node* prev, next;
> };
>
> struct DLL {
>Node* head;
>uint size;
> };
>
> Node** nodes = cast(Node**) malloc(DLL.size * (Node*).sizeof);
>
> and I would like to sort based on Node.t, how should I tackle it,
> preferably without resorting to C libraries?

std.algorithm.sort operates on random-access ranges, not just dynamic
arrays, and there's no need to know the size at compile time. I don't know
why you would think that arrays would need to know their size at compile
time unless you've only been using static arrays. However, a doubly-linked
list definitely isn't random access, so it wouldn't work with
std.algorithm.sort, and I don't think that Phobos has anything which would
be able to sort it. There might be a solution somewhere on code.dlang.org,
but I don't know of any that I could point you to. Either way, if there's a
solution floating around that you can use to sort a doubly-linked list in
place, it's not an official one.

- Jonathan M Davis





Re: How should I sort a doubly linked list the D way?

2019-08-13 Thread Daniel Kozak via Digitalmars-d-learn
You can make an array from it

On Tue, Aug 13, 2019 at 12:05 PM Mirjam Akkersdijk via
Digitalmars-d-learn  wrote:
>
> On Tuesday, 13 August 2019 at 09:48:52 UTC, Mirjam Akkersdijk
> wrote:
> > Hello there,
> > If I had a DLL, how would I sort it judging by the node
> > contents, the D way?
> >
> > [...]
>
> >Node.t
>
> Node.x, my bad


Re: Desktop app with vibe.d

2019-08-13 Thread GreatSam4sure via Digitalmars-d-learn

On Tuesday, 13 August 2019 at 09:44:59 UTC, Russel Winder wrote:
On Mon, 2019-08-12 at 20:01 +, DanielG via 
Digitalmars-d-learn wrote:

[...]


GtkD allows for "reactive" UI. 
https://www.reactivemanifesto.org/


There is also Qt, I haven't tried any of the D bindings to Qt, 
but given Qt is event loop based I am sure it allows for 
"reactive" UI as well – it definitely does using Python/PySIDE2.


GTK+ doesn't have the equivalent of the stage/engine of QML. 
QML is Qt's
version of JavaFX, so you do not need a browser to get a 
dynamic reactive UI.



I want my back end to be in D. I want to write the app in D. I am 
comfortable with JavaFX, adobe flex and Kotlin, c# to some extent




Re: How should I sort a doubly linked list the D way?

2019-08-13 Thread Mirjam Akkersdijk via Digitalmars-d-learn
On Tuesday, 13 August 2019 at 09:48:52 UTC, Mirjam Akkersdijk 
wrote:

Hello there,
If I had a DLL, how would I sort it judging by the node 
contents, the D way?


[...]



Node.t


Node.x, my bad


How should I sort a doubly linked list the D way?

2019-08-13 Thread Mirjam Akkersdijk via Digitalmars-d-learn

Hello there,
If I had a DLL, how would I sort it judging by the node contents, 
the D way?


In C if I were to sort a piece of malloc'd memory pointing to 
node pointers, I would write my compare function and let qsort 
sort it out. In D, I tried to use std.algorithm's sort 
functionality to no avail, because my guess would be it only 
operates on arrays. This opens up another can of worms as I am 
not fond of VLAs and D desperately wants to know what the size is 
at compile time.


Let's say we this trivial implementation:

Node* get_node(DLL* list, uint index);

struct Node {
  int x;
  Node* prev, next;
};

struct DLL {
  Node* head;
  uint size;
};

Node** nodes = cast(Node**) malloc(DLL.size * (Node*).sizeof);

and I would like to sort based on Node.t, how should I tackle it, 
preferably without resorting to C libraries?


Re: Is it possible to target all platforms that Qt Quick can target?

2019-08-13 Thread Russel Winder via Digitalmars-d-learn
On Mon, 2019-08-12 at 17:45 +, Enjoys Math via Digitalmars-d-learn wrote:
> Hi,
> 
> I'm writing my GUI in C++ & Qt Quick.  I know that I could 
> connect to D from the GUI code using a DLL, but can something 
> similar be done on the other PC OS's and the mobile OS's?
> 
> Thanks.
> 

Looking at https://wiki.dlang.org/GUI_Libraries there are some wrappers to Qt
for D, including dqml. I think some may not be as maintained as it would be
nice to have. Actually it would be nice if there was one standard D wrapper
for Qt and QML as there is GtkD the one true D wrapper to GTK+.

-- 
Russel.
===
Dr Russel Winder  t: +44 20 7585 2200
41 Buckmaster Roadm: +44 7770 465 077
London SW11 1EN, UK   w: www.russel.org.uk



signature.asc
Description: This is a digitally signed message part


Re: Desktop app with vibe.d

2019-08-13 Thread Russel Winder via Digitalmars-d-learn
On Mon, 2019-08-12 at 20:01 +, DanielG via Digitalmars-d-learn wrote:
> On Monday, 12 August 2019 at 10:41:57 UTC, GreatSam4sure wrote:
> > I will be happy if I can build an app in D with fanciful ui. I 
> > will also be happy if you know any other way to build a 
> > fanciful ui in D like adobe flex, javafx, etc.
> 
> I haven't seen anybody doing it yet, but in theory you could 
> launch a browser / Electron instance / etc, and have it connect 
> via gRPC to code written in D.
> 
> Then you could have a fancy React UI and use D to do the heavy 
> lifting.

GtkD allows for "reactive" UI. https://www.reactivemanifesto.org/

There is also Qt, I haven't tried any of the D bindings to Qt, but given Qt is
event loop based I am sure it allows for "reactive" UI as well – it definitely
does using Python/PySIDE2.

GTK+ doesn't have the equivalent of the stage/engine of QML. QML is Qt's
version of JavaFX, so you do not need a browser to get a dynamic reactive UI.
 
-- 
Russel.
===
Dr Russel Winder  t: +44 20 7585 2200
41 Buckmaster Roadm: +44 7770 465 077
London SW11 1EN, UK   w: www.russel.org.uk



signature.asc
Description: This is a digitally signed message part


Re: What the abstrac final class mean?

2019-08-13 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, August 13, 2019 3:03:49 AM MDT Jacob Carlborg via Digitalmars-d-
learn wrote:
> On 2019-08-12 11:25, a11e99z wrote:
> > its weird that next compiles in some weird form
> >
> > import std;
> > static class A {
> >
> >  static a() { "a".writeln; } // forgot return type
> >
> > }
>
> Since you have specified an attribute on "a", the compiler can infer the
> return type. In this case it's inferred to "void" since there is no
> return statement.
>
> It's not really the attribute that makes it possible for the compiler to
> infer the return type, it probably can in most of the cases. It just
> needs to be an attribute to satisfy the parser.

Indeed. Basically, the compiler needs _something_ there which goes with a
function to make it happy. The same goes with variable declarations. Many
people mistakenly think that auto tells the compiler to infer the type when
in reality all it does is provide a placeholder to make the parser happy.
The type is _always_ inferred unless it's explicitly given, which is why
stuff such as enum, const, or ref can be used by themselves without
specifying the full type. However, because _something_ has to be there to
indicate that it's a declaration, auto is in the language so that the
programmer has a way to indicate that it's a variable or function
declaration. static by itself is plenty to indicate that a declaration is
being provided. auto or void could be used, but they're not necessary.

- Jonathan M Davis





Re: What the abstrac final class mean?

2019-08-13 Thread Jacob Carlborg via Digitalmars-d-learn

On 2019-08-12 11:25, a11e99z wrote:


its weird that next compiles in some weird form

import std;
static class A {
     static a() { "a".writeln; } // forgot return type
}


Since you have specified an attribute on "a", the compiler can infer the 
return type. In this case it's inferred to "void" since there is no 
return statement.


It's not really the attribute that makes it possible for the compiler to 
infer the return type, it probably can in most of the cases. It just 
needs to be an attribute to satisfy the parser.


--
/Jacob Carlborg


Blog Post #0061: Cairo Toy Text

2019-08-13 Thread Ron Tarrant via Digitalmars-d-learn
When all you want is quick-n-dirty text in a GTK DrawingArea and 
Pango seems like more than you wanna deal with, Cairo's Toy Text 
will do the job nicely. Here's how: 
https://gtkdcoding.com/2019/08/13/0061-cairo-v-toy-text-image-formats.html


How to use #pragma omp parallel for collapse(n) in dlang?

2019-08-13 Thread ijet via Digitalmars-d-learn

How to use #pragma omp parallel for collapse(n) in dlang?


Re: Local static class fields

2019-08-13 Thread Bert via Digitalmars-d-learn

On Tuesday, 13 August 2019 at 04:43:29 UTC, Paul Backus wrote:

On Monday, 12 August 2019 at 22:48:43 UTC, Bert wrote:
Making a field static is effectively a global variable to the 
class.


I have a recursive class structure(think of a graph or tree) 
and I need to keep a global state for it, but this state 
actually needs to be different for each tree object. The 
reason for this is that structurally it will not change per 
tree and if it it is not static then it wastes space 
unnecessarily.


[...]

Is there any way to do this more naturally in D?


It seems to me like the obvious solution is to use two 
different classes, one to store the global state, and one to 
store the individual objects in your structure. For example:


class Tree {
State state;
Node root;
}

class Node {
Node[] children;
}


Yes, I forgot to mention this as a solution.

I was going to go in to more detail. This is not a great solution 
because it requires a base class simply to hold the "global" 
state and it requires nodes to have an accessor(they won't know 
which tree they come from).


What I was thinking though, with D's capabilities, if a 
constructor could somehow return a "Voldemort" type that makes it 
all work out.


e.g.,

class Tree {
State state;
Node root;
alias root this;
}

then the constructor just returns tree which acts as an node.

It doesn't have to be a voldemort but it at least hides some of 
the details...


Ultimately it is not too different from using a dictionary 
though, effectively does the same thing.


The main issue with your solution is that Nodes themselves do not 
have access to the state directly and that is a similar issue 
with the dictionary. One has to traverse up to the root and then 
get the state, in your case, Tree would have to inherit from Node 
so it could be cast and be the root(else the Node would have to 
reference the tree).


There may be no way around such a problem in that these might be 
"optimal". Your's, which added parent in node, might be better 
since a dictionary doesn't have to be directly maintained.


I'd like to get away from actually having a different "root" type 
though. Mainly because it reduces uniformity and complicates the 
design I already have. If I could hide all these things and it is 
not too complicated then it would work better for me.






Re: Local static class fields

2019-08-13 Thread Simen Kjærås via Digitalmars-d-learn

On Monday, 12 August 2019 at 22:48:43 UTC, Bert wrote:
Making a field static is effectively a global variable to the 
class.


I have a recursive class structure(think of a graph or tree) 
and I need to keep a global state for it, but this state 
actually needs to be different for each tree object. The reason 
for this is that structurally it will not change per tree and 
if it it is not static then it wastes space unnecessarily.


class X
{
X[] x;
static State s;
}

making s non-static has the problem that every X will allocate 
storage for s wasting space since for any instance chain of X's 
they will all have the same s. Making it static though then 
makes it the same for all instance chain's of X, of which it 
should be local to each.


One way around this is to use an dictionary that associates 
each state to each instance chain.


That is there is a initial X that is the parent of the chain 
and we can then associate a state to it's address, any other 
chain will have a different initial X and so we can get a new 
state.


class X
{
X[] x;
static State[X] s;
}


This is not a huge difficulty to do but does require finding 
the initial X to use, which is not difficult but wastes cycles 
for large chains. There will, of course, be a constructor that 
constructs a chain and creates a new state for it and updates s.



Is there any way to do this more naturally in D?


First: Are you low on memory? Is traversing the tree actually 
slow? Since you don't know which of these issues to prioritize, 
in all likelihood the answer to both questions is no, and you 
should use the solution that's easier to read.


Of course, that's not the answer you want to hear. Let's consider 
the alternatives:


1) Embed it in each node. Costs 1 pointer's worth of memory per 
node. Very fast. Very easy to understand.


2) Use a dictionary with entries for each node. Costs more than 1 
pointer's worth of memory per node. Fast, but not quite as fast 
as 1). 1) is almost definitely a better option.


3) Use a dictionary with entries for each root node. Costs more 
than 1 pointer's worth of memory, but per tree instead of per 
node. Requires traversal of the tree to find the root, so slower 
than both 1) and 2), especially for deep hierarchies. Complicated 
code.


4) Use a derived class for the root node (class RootX : X { State 
s }). Still requires traversing the tree to find the root, likely 
via a virtual method. Also requires a bit more work setting up 
the tree. Might be faster than 3), definitely smallest memory 
footprint. Relatively easy to follow.


There may be other options, but from the above I'd go with either 
1) or 4).


Now, I've noticed that X doesn't have a pointer to its parent, so 
traversing the tree to find the root is currently impossible. If 
this is true, and you have no other use for traversing up the 
tree, then 1) is the way to go, as 2) is almost never a better 
option, and 3) and 4) requires adding a parent pointer so you'll 
pay the memory price anyway.


--
  Simen


Re: Local static class fields

2019-08-13 Thread Simen Kjærås via Digitalmars-d-learn

On Tuesday, 13 August 2019 at 04:43:29 UTC, Paul Backus wrote:

On Monday, 12 August 2019 at 22:48:43 UTC, Bert wrote:
Making a field static is effectively a global variable to the 
class.


I have a recursive class structure(think of a graph or tree) 
and I need to keep a global state for it, but this state 
actually needs to be different for each tree object. The 
reason for this is that structurally it will not change per 
tree and if it it is not static then it wastes space 
unnecessarily.


[...]

Is there any way to do this more naturally in D?


It seems to me like the obvious solution is to use two 
different classes, one to store the global state, and one to 
store the individual objects in your structure. For example:


class Tree {
State state;
Node root;
}

class Node {
Node[] children;
}


So I have a Node. How do I find the Tree it belongs to?

--
  Simen


Re: Why is this allowed? Inheritance variable shadowing

2019-08-13 Thread a11e99z via Digitalmars-d-learn

On Tuesday, 13 August 2019 at 06:39:24 UTC, a11e99z wrote:

On Tuesday, 13 August 2019 at 05:57:23 UTC, Mike Parker wrote:

On Tuesday, 13 August 2019 at 04:40:53 UTC, Chris Katko wrote:


OT:
and again how to easy to google info about error/warning just 
with one word "CS0108"


D can use attrs for such things.

OT:
1) need to add compiler attrs that speaks with compiler - they 
are change code generation, compiler passes or something. like 
pragmas do.
2) need to separate all attrs in a separate construction like C# 
do

[inline, nextOne, returns: someAttrToReturnValue]
int meth( [argAttrCanBeToo] int x ) { }

or

[hide]
public int x = 2;
cuz its visually separated and easy to skip it with eye when u 
reading/reviewing code.


it can be mess for now:

pure @trusted int meth( int x ) @nogc nothrow { return 5; }
NB all of this attrs is compiler attrs not user, they changes 
compilation.

- no possibility add attr to args or returns
- some attrs with "@" and some don't
- its hard to read when D adds 2-3 attrs more for next 5-10 years

my wishlist of new compilation attrs:
- [hiding] for subj
- [offset(N)] for explicit struct alignment without mess with 
unions/align(4) cuz sometimes I know exactly offset for field and 
I can point it with no side effects calcs adding pads, unions and 
etc
- [inline(bool)] instead of pragma( inline, true ) that looks 
like compiler attr but another way

- [deprecated(text)]
- [nodiscard] cannot discard return value
- etc


Re: Why is this allowed? Inheritance variable shadowing

2019-08-13 Thread a11e99z via Digitalmars-d-learn

On Tuesday, 13 August 2019 at 05:57:23 UTC, Mike Parker wrote:

On Tuesday, 13 August 2019 at 04:40:53 UTC, Chris Katko wrote:


I don't know if I'd call that shadowing. This is how it works 
in Java, too. There's no such thing as a vtable for member 
variables -- each class gets its own set and they don't 
conflict. The only time it could be really be called shadowing 
is when the base class member is protected, as then it's 
accessible in the subclass scope.


Also, it's not the same thing as overriding. Overriding means 
that when you call base.foo(), you get sub.foo()'s 
implementation. But when you access base.var, you get base.var 
and not sub.var.


I would find it extremely annoying if it worked the way you're 
expecting it to.


C# results:
main.cs(8,14): warning CS0108: `B.x' hides inherited member 
`A.x'. Use the new keyword if hiding was intended
main.cs(4,14): (Location of the symbol related to previous 
warning)

Compilation succeeded - 1 warning(s)
mono main.exe
1
2


with "new" keyword that is used to hide a method, property, 
indexer, or event of the base class into the derived class.

class B : A {
  public new int x = 2;
  // I tell "I want hiding. Ensure "x exists in parent"" 
explicitly

  // almost same meaning as "override"
}


OT:
and again how to easy to google info about error/warning just 
with one word "CS0108"


Re: Why is this allowed? Inheritance variable shadowing

2019-08-13 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 13 August 2019 at 04:40:53 UTC, Chris Katko wrote:

You can drop this straight into run.dlang.io:

import std.stdio;

class base{ float x=1;}
class child : base {float x=2;} //shadows base variable!

void main()
{

base []array;
child c = new child;
array ~= c;

writeln(c.x); //=2
writeln(array[0].x); //=1  //uses BASE's interface, yes,
//but why does the CHILD instance one exist at all?
}

It appears to be legal C++ as well but I can't imagine a 
situation where you'd want to allow the HUGE risk of 
shadowing/aliasing variables in an child class. Why is 
inheritance shadowing allowed? Especially when in D you have to 
explicitly "override" existing _methods_ but not 
fields/variables?


To quote a Stack Overflow comment on C++ having this "It's not 
a compile error, but it's certainly a design one." Is this 
allowed just because "C++ does it" or because it has some sort 
of real world use that justifies the risk?


Personally, I'd love a compile-time warning that I could turn 
on that flags this situation.


Thanks for your help,
--Chris


I don't know if I'd call that shadowing. This is how it works in 
Java, too. There's no such thing as a vtable for member variables 
-- each class gets its own set and they don't conflict. The only 
time it could be really be called shadowing is when the base 
class member is protected, as then it's accessible in the 
subclass scope.


Also, it's not the same thing as overriding. Overriding means 
that when you call base.foo(), you get sub.foo()'s 
implementation. But when you access base.var, you get base.var 
and not sub.var.


I would find it extremely annoying if it worked the way you're 
expecting it to.