Re: linked list

2010-09-27 Thread Joel Christensen

Thanks for the long winded reply Jonathan.

I don't know how to avoid using my own linked list, I have next/prev in 
each class (Ball, Lazer and Mine ) in the list.


Thanks bearophile, I had a bit of a look at that site.

My game is simple so just maybe the easiest way is the way to go, though 
if I use the most tightest way and so my game would be an prototype for 
bigger games to reference.


Re: linked list

2010-09-27 Thread Denis Koroskin
On Mon, 27 Sep 2010 10:27:36 +0400, Joel Christensen joel...@gmail.com  
wrote:



Thanks for the long winded reply Jonathan.

I don't know how to avoid using my own linked list, I have next/prev in  
each class (Ball, Lazer and Mine ) in the list.




That's called intrusive linked list, and I find using it quite viable:
zero-allocation O(1) add/removal is a very strong characteristics.

They are very useful especially for lock-free algorithms.


Re: Segmentation fault on closing file in destructor

2010-09-27 Thread Lars T. Kyllingstad
On Sun, 26 Sep 2010 20:55:33 +0200, Tom Kazimiers wrote:
 If I would use std.stdio.File, what would be different?

Well, for one thing you won't have to write your code all over again when 
std.stream is deprecated, which will happen soon.  std.stdio.File is 
really what you should use for file I/O in new code.

That said, there's a chance it does exactly what you want.  You don't 
have to open a file on construction, there's an open() function which 
opens a file and assigns it to the File handle.  Nor do you have to worry 
about closing the file in the destructor, as it is automatically closed 
the moment the last reference to it goes out of scope.

Here are a few examples of how to use it:

  File file;// File's a struct, so no need to use 'new'

  // Read a text file line by line
  file.open(foo.txt);
  foreach (line; file.byLine())  writeln(line);

  // Read a binary file in 4MB chunks
  file.open(foo.dat);
  foreach (ubyte[] chunk; file.byChunk(4*1024))
  doStuffWith(chunk);

  // Read up to 100 ints from a file
  file.open(myInts);
  auto buffer = new int[100];
  auto data = file.rawRead(buffer);
  
-Lars


Re: linked list, ranges

2010-09-27 Thread Steven Schveighoffer
On Sun, 26 Sep 2010 04:38:36 -0400, Joel Christensen joel...@gmail.com  
wrote:


Thanks again for the reply Jonathan. I'm using doublely linked list I  
made for a game where ships and there lazer bolts are in the same list.  
Without linked list I couldn't do things like create a lazer bolt or  
remove one while trans-versing the linked list. I had to use my own  
linked list, having a next and prev node in each object that goes in the  
list.


Not sure if dcollections could be of use:

http://www.dsource.org/projects/dcollections

And the linked list class:

http://www.dsource.org/projects/dcollections/browser/branches/d2/dcollections/LinkList.d

One thing my lib supports is removal while traversing via foreach.  See  
the purge function.


Sorry about lack of online docs, I need to figure out how to automatically  
generate them (the D1 docs are auto-generated, but I haven't put in any  
time to figure out how to generate the D2 version).


-Steve


Re: Segmentation fault on closing file in destructor

2010-09-27 Thread Steven Schveighoffer
On Sun, 26 Sep 2010 20:20:18 -0400, Michel Fortin  
michel.for...@michelf.com wrote:


On 2010-09-26 10:06:33 -0400, Simen kjaeraas simen.kja...@gmail.com  
said:



Tom Kazimiers 2voo...@gmx.de wrote:


Hi,
 a file reading class of mine can be constructed with a filename as
parameter. It instantiates a new std.stream.File (without the passed
file name and closes it when opened within the destructor. The last  
part

is where things are getting unclear for me. On the file.isOpen() call
in the destructor a segmentation fault occurs. What is the problem with
that?

 Likely, it is this[1]:
 [T]he order in which the garbage collector calls destructors for
unreference objects is not specified. This means that when the garbage
collector calls a destructor for an object of a class that has members
that are references to garbage collected objects, those references may
no longer be valid. This means that destructors cannot reference sub
objects.
 [1]: http://digitalmars.com/d/2.0/class.html#destructors


That's it indeed, but I'll add that it's the File struct that is at  
fault. See this bug:

http://d.puremagic.com/issues/show_bug.cgi?id=4624


He's using std.stream.File, not std.stdio.File.

In fact, it's generally a good idea to not wait for the GC to collect  
your objects before closing files, because waiting for the GC could take  
an indeterminate amount of time and leave files open for a long time  
(the GC only runs when needed).


Yes, this is true no matter what File construct you use.

-Steve


Re: Segmentation fault on closing file in destructor

2010-09-27 Thread Steven Schveighoffer

On Sun, 26 Sep 2010 11:17:07 -0400, Tom Kazimiers 2voo...@gmx.de wrote:


Hi Simen,

On 09/26/2010 04:06 PM, Simen kjaeraas wrote:

Likely, it is this[1]:

[T]he order in which the garbage collector calls destructors for
unreference objects is not specified. This means that when the garbage
collector calls a destructor for an object of a class that has members
that are references to garbage collected objects, those references may
no longer be valid. This means that destructors cannot reference sub
objects.

[1]: http://digitalmars.com/d/2.0/class.html#destructors


thanks for your reply. I did not know that the garbage collector works
that way. Is the reason for that flexibility for the GC? What if I want
to handle some destruction parts to sub-objects or if I want conditions
while destruction, based on sub-objects?


Then do not use a destructor.  There is no way currently for the  
destructor to know whether it's being called from the GC or not, so it is  
only safe to destroy resources *not* allocated by the GC.  In fact, the  
only reason destructors are supported in classes is to destroy non-GC  
resources.



Or maybe I should generally
avoid situations like that. Do you have any suggestion how I should make
sure that the file gets closed on destruction?


You don't have to worry about it -- let the GC do its job.  If you think  
about it, your class instance may have the only reference to the File  
object.  Since your class is being destroyed by the GC, it makes sense  
that the File object has no references to it, so it too is being destroyed  
by the GC.  If you want sooner destruction, you should manually close it  
earlier via another function call (like close() or detach()).


However, I will mention something that others missed, unlike in C++, the  
default protection in a class is public, so your public: attribute doesn't  
do much, and your file member is publicly accessible.


-Steve


dcollection docs

2010-09-27 Thread Johannes Pfau
On 27.09.2010 14:01, Steven Schveighoffer wrote:
 
 
 Sorry about lack of online docs, I need to figure out how to
 automatically generate them (the D1 docs are auto-generated, but I
 haven't put in any time to figure out how to generate the D2 version).
 
 -Steve

Yao has a nice ddoc template for D2. See for example
http://d.yao.com.mx/datetime/core.html
The ddoc file is available here:
https://bitbucket.org/gomez/yao-library/src/da11956a6a6e/docs/ but I
don't know about the license for that file, you might have to ask him
about that. This doesn't generate an index though, if you meant that.

-- 
Johannes Pfau


Re: dcollection docs

2010-09-27 Thread Steven Schveighoffer

On Mon, 27 Sep 2010 08:34:57 -0400, Johannes Pfau s...@example.com wrote:


On 27.09.2010 14:01, Steven Schveighoffer wrote:



Sorry about lack of online docs, I need to figure out how to
automatically generate them (the D1 docs are auto-generated, but I
haven't put in any time to figure out how to generate the D2 version).

-Steve


Yao has a nice ddoc template for D2. See for example
http://d.yao.com.mx/datetime/core.html
The ddoc file is available here:
https://bitbucket.org/gomez/yao-library/src/da11956a6a6e/docs/ but I
don't know about the license for that file, you might have to ask him
about that. This doesn't generate an index though, if you meant that.


Thanks,

Yao's seems similar to Phobos, which I'm not a big fan of.  Particularly  
the munged-together list of constructs/functions at the top.


I used Tango's (old) doc generation templates to generate the D1 docs, and  
Brad of dsource set up my project to rebuild the D1 docs on every  
checkin.  However, I don't think he's set up a D2 compiler, and even if he  
did, it's changing so frequently that he'd have to update it too often.


I dumped the Tango doc templates for the D2 version, and I want to rewrite  
them, but I just haven't had the time.  In particular, I want a  
categorical index at the top or on the side (i.e. functions, members,  
etc.)  Having everything munged together is super-confusing.


I really like the dil-generated docs that Tango uses, but I'm pretty sure  
dil isn't D2...


-Steve


Dispatching from receive to a function

2010-09-27 Thread Bob Cowdery
 I've been looking for a way to hook up messages to a thread with a
handler function. As far as I can tell receive pattern matching only
allows the pattern to be distinguished by the parameter signature which
does not help when all the handlers only have a few different signatures.

I like the pattern matching concept as I have worked with Erlang which
will pattern match to a term (basically an arbitrary structure). Erlang
defines an Atom type which is really a global constant that can be used
as a message type in the match. Does anyone know of a way to simulate this?

Failing that I think a dispatcher structure using an associative array
would be my next choice. However I'm getting stuck on how to define and
use an array which maps a string key to a delegate. Can someone help me
out there please. I will then effectively have my 'Atom' as a string in
the message and dispatch on that.

I don't want to hard code in a switch statement.

Any other suggestions are very welcome.

Thanks
Bob


Re: Dispatching from receive to a function

2010-09-27 Thread Johannes Pfau
On 27.09.2010 15:07, Bob Cowdery wrote:
 
 Failing that I think a dispatcher structure using an associative array
 would be my next choice. However I'm getting stuck on how to define and
 use an array which maps a string key to a delegate. Can someone help me
 out there please. I will then effectively have my 'Atom' as a string in
 the message and dispatch on that.
 

Not sure about the other questions, but here's an example for a
string/delegate associative array:
---
import std.stdio;

alias bool delegate(int, char) TestDelegate;

TestDelegate[string] dict;

class C
{
bool test(int i, char c) {return true;}
}

void main()
{
C c = new C();
dict[test] = c.test;
writeln(dict[test](0, 'c'));
}
---

-- 
Johannes Pfau


Re: Dispatching from receive to a function

2010-09-27 Thread Bob Cowdery
 Thanks. Do you know if the signature is a mandatory part. If I left the
signature out would it then only work with a delegate with no
parameters? If so I think I'm in the same state as my delegates will not
all have the same signature.

Bob

On 27/09/2010 14:21, Johannes Pfau wrote:
 On 27.09.2010 15:07, Bob Cowdery wrote:
 Failing that I think a dispatcher structure using an associative array
 would be my next choice. However I'm getting stuck on how to define and
 use an array which maps a string key to a delegate. Can someone help me
 out there please. I will then effectively have my 'Atom' as a string in
 the message and dispatch on that.

 Not sure about the other questions, but here's an example for a
 string/delegate associative array:
 ---
 import std.stdio;

 alias bool delegate(int, char) TestDelegate;

 TestDelegate[string] dict;

 class C
 {
 bool test(int i, char c) {return true;}
 }

 void main()
 {
 C c = new C();
 dict[test] = c.test;
 writeln(dict[test](0, 'c'));
 }
 ---




Re: Dispatching from receive to a function

2010-09-27 Thread Johannes Pfau
On 27.09.2010 15:36, Bob Cowdery wrote:
  Thanks. Do you know if the signature is a mandatory part. If I left the
 signature out would it then only work with a delegate with no
 parameters? If so I think I'm in the same state as my delegates will not
 all have the same signature.
 

Yep, the signature is mandatory. There is another, ugly, unsafe (it's
safe, but you really have to be careful and write correct code) way:

Basically you cast away the delegates type information. You then store
the delegate in an array. Later, you have to cast the delegate back to
it's original type. The problem here is, that D doesn't provide enough
runtime type information to know which type the delegate originally had,
so _we_ have to store some type info _manually_. This can for example be
done by storing both the delegate and our type info in a struct.

Here's an example how to do exactly that.

!!!Note: It's very important to always cast the delegate back to the
_correct_ type before calling it, everything else leads to undefined
behavior!!! So just setting CDelegate.Type to a wrong type can cause a
disaster!

(Sorry about the bad variable names in the example. For better
encapsulation most of the casts could be moved into the CDelegate struct
by adding functions and constructors)
---
import std.stdio;

enum DelegateType
{
A,
B,
C,
D
}

struct CDelegate
{
void delegate() del; //Exact type doesn't matter, all delegates have
the same size
DelegateType Type;
}

CDelegate[string] dict;

class C
{
bool test(int i, char c) {return true;}
}

class D
{
int test(string s) {return 99;}
}

void main()
{
C c = new C();
D d = new D();
CDelegate custom;

custom.del = cast(void delegate())c.test;
custom.Type = DelegateType.C;
dict[c] = custom;

custom.del = cast(void delegate())d.test;
custom.Type = DelegateType.D;
dict[d] = custom;

foreach(cdeleg; dict)
{
switch(cdeleg.Type)
{
case DelegateType.C:
bool delegate(int i, char c) realdel = cast (bool
delegate(int i, char c)) cdeleg.del;
writeln(realdel(0, 'c'));
break;

case DelegateType.D:
int delegate(string) realdel = cast (int
delegate(string)) cdeleg.del;
writeln(realdel(test));
break;
}
}
}
---

-- 
Johannes Pfau


Re: Dispatching from receive to a function

2010-09-27 Thread Juanjo Alvarez
I'm new to the language so I don't know if this is horribly wrong on some 
levels, but it works:

-

import std.variant;
import std.stdio;

class C
{
bool test(int i, char c) { writeln(Hello from test1); return true; }
void test2(string v) { writeln(Hello from test2, , v); }
}


void main()
{
auto c = new C;
Variant[string] holder = [test: Variant(c.test), test2: Variant
(c.test2)];
receiver(holder);
}

void receiver(Variant[string] message) 
{
// If you get the Variant template instantiation delegate 
// signature wrong, it will
// be detected at compile time!
auto t = message[test].get!(bool delegate(int, char));
auto t2 = message[test2].get!(void delegate(string));
t(1, 'c');
t2(foo);
}
--

Curiously if you create holder like this, it will give an arrayoutofbound 
error at runtime, I don't know if that is a bug:

void main()
{
   auto c = new C;
   Variant[string] holder;
   holder[test] = Variant(c.test);
   holder[test2] = Variant(c.test2);
}

On Mon, 27 Sep 2010 18:03:32 +0200, Johannes Pfau wrote:

 On 27.09.2010 15:36, Bob Cowdery wrote:
  Thanks. Do you know if the signature is a mandatory part. If I left
  the
 signature out would it then only work with a delegate with no
 parameters? If so I think I'm in the same state as my delegates will
 not all have the same signature.
 
 
 Yep, the signature is mandatory. There is another, ugly, unsafe (it's
 safe, but you really have to be careful and write correct code) way:
 
 Basically you cast away the delegates type information. You then store
 the delegate in an array. Later, you have to cast the delegate back to
 it's original type. The problem here is, that D doesn't provide enough
 runtime type information to know which type the delegate originally had,
 so _we_ have to store some type info _manually_. This can for example be
 done by storing both the delegate and our type info in a struct.
 
 Here's an example how to do exactly that.
 
 !!!Note: It's very important to always cast the delegate back to the
 _correct_ type before calling it, everything else leads to undefined
 behavior!!! So just setting CDelegate.Type to a wrong type can cause a
 disaster!
 
 (Sorry about the bad variable names in the example. For better
 encapsulation most of the casts could be moved into the CDelegate struct
 by adding functions and constructors)
 
---
 import std.stdio;
 
 enum DelegateType
 {
 A,
 B,
 C,
 D
 }
 
 struct CDelegate
 {
 void delegate() del; //Exact type doesn't matter, all delegates have
 the same size
 DelegateType Type;
 }
 
 CDelegate[string] dict;
 
 class C
 {
 bool test(int i, char c) {return true;}
 }
 
 class D
 {
 int test(string s) {return 99;}
 }
 
 void main()
 {
 C c = new C();
 D d = new D();
 CDelegate custom;
 
 custom.del = cast(void delegate())c.test; custom.Type =
 DelegateType.C;
 dict[c] = custom;
 
 custom.del = cast(void delegate())d.test; custom.Type =
 DelegateType.D;
 dict[d] = custom;
 
 foreach(cdeleg; dict)
 {
 switch(cdeleg.Type)
 {
 case DelegateType.C:
 bool delegate(int i, char c) realdel = cast (bool
 delegate(int i, char c)) cdeleg.del;
 writeln(realdel(0, 'c'));
 break;
 
 case DelegateType.D:
 int delegate(string) realdel = cast (int
 delegate(string)) cdeleg.del;
 writeln(realdel(test));
 break;
 }
 }
 }
 
---



Re: Dispatching from receive to a function

2010-09-27 Thread Johannes Pfau
On 27.09.2010 20:46, Juanjo Alvarez wrote:
 I'm new to the language so I don't know if this is horribly wrong on some 
 levels, but it works:
 
 -
 
 import std.variant;
 import std.stdio;
 
 class C
 {
 bool test(int i, char c) { writeln(Hello from test1); return true; }
 void test2(string v) { writeln(Hello from test2, , v); }
 }
 
 
 void main()
 {
 auto c = new C;
 Variant[string] holder = [test: Variant(c.test), test2: Variant
 (c.test2)];
 receiver(holder);
 }
 
 void receiver(Variant[string] message) 
 {
 // If you get the Variant template instantiation delegate 
 // signature wrong, it will
 // be detected at compile time!
 auto t = message[test].get!(bool delegate(int, char));
 auto t2 = message[test2].get!(void delegate(string));
 t(1, 'c');
 t2(foo);
 }
 --
 
 Curiously if you create holder like this, it will give an arrayoutofbound 
 error at runtime, I don't know if that is a bug:
 
 void main()
 {
auto c = new C;
Variant[string] holder;
holder[test] = Variant(c.test);
holder[test2] = Variant(c.test2);
 }
 

I totally forgot about Variant!
As far as I know that's exactly what variant is for and it's way better
than my proposed hack. The example you posted is perfectly fine as well.
I'm not sure what causes the arrayoutofbound error, the second example
is correct as well.

-- 
Johannes Pfau


Re: Dispatching from receive to a function

2010-09-27 Thread Juanjo Alvarez
On Mon, 27 Sep 2010 21:00:48 +0200, Johannes Pfau wrote:

 On 27.09.2010 20:46, Juanjo Alvarez wrote:
 I'm new to the language so I don't know if this is horribly wrong on
 some levels, but it works:
 
 -
 
 import std.variant;
 import std.stdio;
 
 class C
 {
 bool test(int i, char c) { writeln(Hello from test1); return
 true; } void test2(string v) { writeln(Hello from test2, , v); }
 }
 
 
 void main()
 {
 auto c = new C;
 Variant[string] holder = [test: Variant(c.test), test2:
 Variant
 (c.test2)];
 receiver(holder);
 }
 
 void receiver(Variant[string] message) {
 // If you get the Variant template instantiation delegate //
 signature wrong, it will
 // be detected at compile time!
 auto t = message[test].get!(bool delegate(int, char)); auto t2 =
 message[test2].get!(void delegate(string)); t(1, 'c');
 t2(foo);
 }
 --
 
 Curiously if you create holder like this, it will give an
 arrayoutofbound error at runtime, I don't know if that is a bug:
 
 void main()
 {
auto c = new C;
Variant[string] holder;
holder[test] = Variant(c.test);
holder[test2] = Variant(c.test2);
 }
 
 
 I totally forgot about Variant!
 As far as I know that's exactly what variant is for and it's way better
 than my proposed hack. The example you posted is perfectly fine as well.
 I'm not sure what causes the arrayoutofbound error, the second example
 is correct as well.

Yep, variants are cool. You could even use an struct as value type of the 
associative array and store the variant in one member and the signature 
of the delegate, as string, in another member. The you could use a mixin 
in the receiver to extract the delegate without knowing the original 
signature.

All this is  wonderfully disturbing to me :)


Re: dcollection docs

2010-09-27 Thread Yao G.

On Mon, 27 Sep 2010 07:34:57 -0500, Johannes Pfau s...@example.com wrote:


Yao has a nice ddoc template for D2. See for example
http://d.yao.com.mx/datetime/core.html
The ddoc file is available here:
https://bitbucket.org/gomez/yao-library/src/da11956a6a6e/docs/ but I
don't know about the license for that file, you might have to ask him
about that. This doesn't generate an index though, if you meant that.


That ddoc file is in, let's say, experimental stage, and I had to make  
some hacks to make the generated docs pass the HTML4 validator (see for  
example the UL or the D_CODE macros).


They don't have licence because I didn't find an equivalent to the Boost  
Licence but for documentation, but they can be used freely for whatever  
need you have.


I still have to make some improvements, for example create a tree of  
symbols, like the one in Kandil or CandyDoc.


--
Yao G.


Re: dcollection docs

2010-09-27 Thread Yao G.
On Mon, 27 Sep 2010 07:46:49 -0500, Steven Schveighoffer  
schvei...@yahoo.com wrote:



Thanks,

Yao's seems similar to Phobos, which I'm not a big fan of.  Particularly  
the munged-together list of constructs/functions at the top.


To be honest, I don't like it either  :) I plan to improve it, and by  
improve it I mean to remove that cloud-like unordered list of symbols, and  
use a tree or something similar. CandyDoc sometimes hangs Opera, so I  
wanted to make a quick replacement, that also worked well without  
JavaScript. Maybe I'll switch to Kandil or just use the doc generator of  
Dil.


--
Yao G.


Re: Dispatching from receive to a function

2010-09-27 Thread Bob Cowdery
 Thanks for the suggestions. I'm still hankering after an elegant
solution to the receive rather than try to patch it up after the event.
The best I can come up with is pretty ugly (odd) at the front but looks
better at the back-end. Maybe someone can refine it a bit.


struct RATE{};
struct SRC_1{};
struct SRC_2{};

class OutputFrame{
void set_rate(RATE desc, int speed) {..}
void set_clock_src1(SRC_1 desc, string lo_ref){...}
void set_clock_src2(SRC_2 desc, string hi_ref) {...}
}

output_buffer = new OutputFrame();
while (true) {
receive(
(immutable (float) [] smpls) {
add_to_buffer(smpls);
output_data();
},
output_buffer.set_rate,
output_buffer.set_clock_src1,
output_buffer.set_clock_src2,
);
 }


On 27/09/2010 20:49, Juanjo Alvarez wrote:
 On Mon, 27 Sep 2010 21:00:48 +0200, Johannes Pfau wrote:

 On 27.09.2010 20:46, Juanjo Alvarez wrote:
 I'm new to the language so I don't know if this is horribly wrong on
 some levels, but it works:

 -

 import std.variant;
 import std.stdio;

 class C
 {
 bool test(int i, char c) { writeln(Hello from test1); return
 true; } void test2(string v) { writeln(Hello from test2, , v); }
 }


 void main()
 {
 auto c = new C;
 Variant[string] holder = [test: Variant(c.test), test2:
 Variant
 (c.test2)];
 receiver(holder);
 }

 void receiver(Variant[string] message) {
 // If you get the Variant template instantiation delegate //
 signature wrong, it will
 // be detected at compile time!
 auto t = message[test].get!(bool delegate(int, char)); auto t2 =
 message[test2].get!(void delegate(string)); t(1, 'c');
 t2(foo);
 }
 --

 Curiously if you create holder like this, it will give an
 arrayoutofbound error at runtime, I don't know if that is a bug:

 void main()
 {
auto c = new C;
Variant[string] holder;
holder[test] = Variant(c.test);
holder[test2] = Variant(c.test2);
 }


 I totally forgot about Variant!
 As far as I know that's exactly what variant is for and it's way better
 than my proposed hack. The example you posted is perfectly fine as well.
 I'm not sure what causes the arrayoutofbound error, the second example
 is correct as well.
 Yep, variants are cool. You could even use an struct as value type of the 
 associative array and store the variant in one member and the signature 
 of the delegate, as string, in another member. The you could use a mixin 
 in the receiver to extract the delegate without knowing the original 
 signature.

 All this is  wonderfully disturbing to me :)



Re: Dispatching from receive to a function

2010-09-27 Thread Philippe Sigaud
On Mon, Sep 27, 2010 at 21:49, Juanjo Alvarez 
juan...@thatwebmailofgoogleproperty.com wrote:

  Curiously if you create holder like this, it will give an
  arrayoutofbound error at runtime, I don't know if that is a bug:


I think I got this one too. IIRC, it's a bug in the holder[test] part than
the Variant(c.test) part.


 Yep, variants are cool. You could even use an struct as value type of the
 associative array and store the variant in one member and the signature
 of the delegate, as string, in another member. The you could use a mixin
 in the receiver to extract the delegate without knowing the original
 signature.

 All this is  wonderfully disturbing to me :)


I'm not sure you can. You can only mixin strings known at compile-time. Your
string member will only have a value at runtime.
Except if the struct is an enum, maybe.


Philippe


Re: intrusive linked list

2010-09-27 Thread Joel Christensen

That's called intrusive linked list, and I find using it quite viable:
zero-allocation O(1) add/removal is a very strong characteristics.

They are very useful especially for lock-free algorithms.


That's for the info Denis. I got the idea from a friend who is 
interested in how to make games.