comp.lang.ada
 help / color / mirror / Atom feed
* tagged type as generic parameter
@ 2008-01-03 15:20 Philippe Tarroux
  2008-01-03 15:51 ` Dmitry A. Kazakov
  0 siblings, 1 reply; 14+ messages in thread
From: Philippe Tarroux @ 2008-01-03 15:20 UTC (permalink / raw)


Hi everybody,

I wrote the following packages:


generic
   type Data is tagged private;  -- In order to be able to build lists 
of items of this type
package List is

   type List (<>) is private;

private
   type Item;
   type Item_Ptr is access Item;
   type Item is new Data with record      -- Line 22
      Next : Item_Ptr;
   end record;
  
   type List_Head is tagged record
      Head : Item_Ptr := null;
   end record;

   type List is access List_Head;
end List;

-----------------------------------
package data_handler is

   type Data is tagged private;
  
   function A_Data(V : Integer) return Data;
   procedure Print (D : Data);
  
private
  
   type Data is tagged record
      Value : Integer;
   end record;

end data_handler;

-------------------------------------------

with List;
with Data_Handler;
use Data_Handler;

package data_list is

   package My_List is new List (Data_Handler.Donn�es); 

end data_list;

When i try to instantiate the last package (data_list) i get the 
following error:

data_list.ads:7:04: instantiation error at list.ads:22
data_list.ads:7:04: type must be declared abstract or "a_data" overridden
data_list.ads:7:04: "a_data" has been inherited at list.ads:22, instance 
at line 7
data_list.ads:7:04: "a_data" has been inherited from subprogram at 
data_handler.ads:5

I suspect the problem is due to the derivation of Item from Data at line 
22 of list.ads during the instantiation of the generic but I don't 
really understand why and i don't understand why the problem arises with 
the function A_Data and not with the procedure Print.

OS : W2K
GCC version 4.1.3 20070403 for GNAT GPL 2007

Thank and best regards

Philippe Tarroux






^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: tagged type as generic parameter
  2008-01-03 15:20 tagged type as generic parameter Philippe Tarroux
@ 2008-01-03 15:51 ` Dmitry A. Kazakov
  2008-01-03 16:22   ` Adam Beneschan
  2008-01-04 13:08   ` Philippe Tarroux
  0 siblings, 2 replies; 14+ messages in thread
From: Dmitry A. Kazakov @ 2008-01-03 15:51 UTC (permalink / raw)


On Thu, 03 Jan 2008 16:20:48 +0100, Philippe Tarroux wrote:

> I wrote the following packages:
> 
> generic
>    type Data is tagged private;  -- In order to be able to build lists 
> of items of this type
> package List is
> 
>    type List (<>) is private;
> 
> private
>    type Item;
>    type Item_Ptr is access Item;
>    type Item is new Data with record      -- Line 22
>       Next : Item_Ptr;
>    end record;
>   
>    type List_Head is tagged record
>       Head : Item_Ptr := null;
>    end record;
> 
>    type List is access List_Head;
> end List;
> 
> -----------------------------------
> package data_handler is
> 
>    type Data is tagged private;
>   
>    function A_Data(V : Integer) return Data;
>    procedure Print (D : Data);
>   
> private
>   
>    type Data is tagged record
>       Value : Integer;
>    end record;
> 
> end data_handler;

[...] 
> I suspect the problem is due to the derivation of Item from Data at line 
> 22 of list.ads during the instantiation of the generic but I don't 
> really understand why and i don't understand why the problem arises with 
> the function A_Data and not with the procedure Print.

The function A_Data returns Data. It is a primitive operation of Data and
thus covariant in the result. So when you derive anything from Data, you
have to override it in order to provide a correct implementation that would
return the derived type rather than the base.

There are many ways to resolve the issue, the choice depends on other
factors:

1. Class-wide A_Data:

   function A_Data (V : Integer) return Data'Class;

This will be same (contravariant) for all descendants of A_Data and thus
need not to overridden.

2. Data-specific List package:

generic
   type Data is abstract new Data_Handler.Data with private;
package Data_List is
   ...
   type Item is new Data with record
      Next : Item_Ptr;
   end record;
   function A_Data (V : Integer) return Item;

We know here that Data is a descendant of Data_Handler.Data, so we can
provide an override for A_Data.

3. Aggregation instead of inheritance:

   type Item is record
      Next  : Item_Ptr;
      Value : Data;
   end record;

No inheritance, no problem.

4. Non-generic implementation of lists. You can define a list interface and
derive Data_Handler.Data from a list item. (In Ada 2005 it is easier to do
than it was in Ada 95) That would reverse the inheritance order and thus
solve the problem with A_Data.

5. Storage-pool based implementation of lists. You can design a storage
pool that would maintain lists of allocated there items. In this case,
unlikely to all other variants, the list item is not a fully separate type
but just a pool-specific access to Data type. Because there again is no
inheritance involved, the problem is solved.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: tagged type as generic parameter
  2008-01-03 15:51 ` Dmitry A. Kazakov
@ 2008-01-03 16:22   ` Adam Beneschan
  2008-01-03 16:58     ` Dmitry A. Kazakov
  2008-01-04 13:08   ` Philippe Tarroux
  1 sibling, 1 reply; 14+ messages in thread
From: Adam Beneschan @ 2008-01-03 16:22 UTC (permalink / raw)


On Jan 3, 7:51 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:

> 3. Aggregation instead of inheritance:
>
>    type Item is record
>       Next  : Item_Ptr;
>       Value : Data;
>    end record;
>
> No inheritance, no problem.

Actually, I think the OP really needs a darn good reason why he would
want Item to be inherited from his generic formal type, rather than
simply a record containing a value and a link as in your above
suggestion.  Conceptually, at least to me, a type extension is
supposed to define a type that is a "kind of" the parent type.  In
this case, Item, as the OP originally defined it, doesn't really fit
the concept.  It's not really a "kind of" Data with additional
properties.  I'm sorry that my "pedagogical" understanding of object-
oriented programming isn't solid enough that I understand what terms
to use, but hopefully I'm getting some sort of notion across.

Or, to put it another way, don't use type extensions just because
they're there.

To me, #3 stands out as the *correct* solution to the problem, in most
cases.  Plus, if you do that, Data no longer needs to be a tagged
formal type, so that you can use your generic on both tagged and
untagged types.

                           -- Adam







^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: tagged type as generic parameter
  2008-01-03 16:22   ` Adam Beneschan
@ 2008-01-03 16:58     ` Dmitry A. Kazakov
  2008-01-03 17:47       ` Jean-Pierre Rosen
  0 siblings, 1 reply; 14+ messages in thread
From: Dmitry A. Kazakov @ 2008-01-03 16:58 UTC (permalink / raw)


On Thu, 3 Jan 2008 08:22:24 -0800 (PST), Adam Beneschan wrote:

> On Jan 3, 7:51 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> wrote:
> 
>> 3. Aggregation instead of inheritance:
>>
>>    type Item is record
>>       Next  : Item_Ptr;
>>       Value : Data;
>>    end record;
>>
>> No inheritance, no problem.
> 
> Actually, I think the OP really needs a darn good reason why he would
> want Item to be inherited from his generic formal type, rather than
> simply a record containing a value and a link as in your above
> suggestion.  Conceptually, at least to me, a type extension is
> supposed to define a type that is a "kind of" the parent type.  In
> this case, Item, as the OP originally defined it, doesn't really fit
> the concept.  It's not really a "kind of" Data with additional
> properties.  I'm sorry that my "pedagogical" understanding of object-
> oriented programming isn't solid enough that I understand what terms
> to use, but hopefully I'm getting some sort of notion across.

A reason might be to be able to use list items and their content
interchangeably, another could be to handle unconstrained data.

However, these are certainly not the case for the OP's code. Because Item
is private there and Data is constrained. And even if Item were visible,
then the right way would likely be #2, because "anything tagged" as in OP's
code does not tell much about the inherited semantics of list elements.

IMO, your understanding of OOP is quite right.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: tagged type as generic parameter
  2008-01-03 16:58     ` Dmitry A. Kazakov
@ 2008-01-03 17:47       ` Jean-Pierre Rosen
  2008-01-03 18:13         ` Pascal Obry
                           ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Jean-Pierre Rosen @ 2008-01-03 17:47 UTC (permalink / raw)


Dmitry A. Kazakov a �crit :
> However, these are certainly not the case for the OP's code. Because Item
> is private there and Data is constrained. And even if Item were visible,
> then the right way would likely be #2, because "anything tagged" as in OP's
> code does not tell much about the inherited semantics of list elements.
> 
> IMO, your understanding of OOP is quite right.
> 
Yeap. In these times where everybody is talking about OOP, people tend 
to move from "everything can be done with inheritance" to "everything 
must be done with inheritance". To be honnest, some languages offer 
inheritance as the only way, so there is no choice.

When you are lucky enough to have a language that supports multiple 
paradigms, composition has its value.
-- 
---------------------------------------------------------
            J-P. Rosen (rosen@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: tagged type as generic parameter
  2008-01-03 17:47       ` Jean-Pierre Rosen
@ 2008-01-03 18:13         ` Pascal Obry
  2008-01-03 19:20         ` Dmitry A. Kazakov
  2008-01-03 21:37         ` Jeffrey R. Carter
  2 siblings, 0 replies; 14+ messages in thread
From: Pascal Obry @ 2008-01-03 18:13 UTC (permalink / raw)
  To: Jean-Pierre Rosen

Jean-Pierre Rosen a �crit :
> When you are lucky enough to have a language that supports multiple
> paradigms, composition has its value.

I fully agree. There is some very wrong use of inheritance those days.

Pascal.

-- 

--|------------------------------------------------------
--| Pascal Obry                           Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--|              http://www.obry.net
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: tagged type as generic parameter
  2008-01-03 17:47       ` Jean-Pierre Rosen
  2008-01-03 18:13         ` Pascal Obry
@ 2008-01-03 19:20         ` Dmitry A. Kazakov
  2008-01-03 21:37         ` Jeffrey R. Carter
  2 siblings, 0 replies; 14+ messages in thread
From: Dmitry A. Kazakov @ 2008-01-03 19:20 UTC (permalink / raw)


On Thu, 03 Jan 2008 18:47:12 +0100, Jean-Pierre Rosen wrote:

> To be honnest, some languages offer 
> inheritance as the only way, so there is no choice.

There is nothing automatically wrong in doing aggregation per inheritance
if one can hide undesired side effects in public interfaces:

   type Container is private;
private
   type Container is new Contained...;

I can imagine Ada without built-in record types, but with record interfaces
implemented via privately made multiple inheritance. One can always escape
the base type class in Ada by deriving privately. Unfortunately "type X is
new Y" does not work for tagged types. Otherwise it would be even better.

Important to me is consistency of the language design preventing suspicious
code from being compiled. It did not compile because in Ada:

1. Generics are contracted;
2. Primitive operations are ones in all arguments and the result;
3. Private does not leak.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: tagged type as generic parameter
  2008-01-03 17:47       ` Jean-Pierre Rosen
  2008-01-03 18:13         ` Pascal Obry
  2008-01-03 19:20         ` Dmitry A. Kazakov
@ 2008-01-03 21:37         ` Jeffrey R. Carter
  2008-01-04 13:08           ` Philippe Tarroux
  2 siblings, 1 reply; 14+ messages in thread
From: Jeffrey R. Carter @ 2008-01-03 21:37 UTC (permalink / raw)


Jean-Pierre Rosen wrote:
> Yeap. In these times where everybody is talking about OOP, people tend 
> to move from "everything can be done with inheritance" to "everything 
> must be done with inheritance". To be honnest, some languages offer 
> inheritance as the only way, so there is no choice.

Given the OP's comment that the formal is tagged so that he will be able to 
build lists of the type implies that he comes from a background in such a language.

> When you are lucky enough to have a language that supports multiple 
> paradigms, composition has its value.

I agree. Programming by extension, emphasizing, as it does, ease of writing over 
ease of reading, should be avoided whenever possible by SW engineers, and used 
with the same reluctance and care that they give to gotos and access types.

-- 
Jeff Carter
"Have you gone berserk? Can't you see that that man is a ni?"
Blazing Saddles
38



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: tagged type as generic parameter
  2008-01-03 15:51 ` Dmitry A. Kazakov
  2008-01-03 16:22   ` Adam Beneschan
@ 2008-01-04 13:08   ` Philippe Tarroux
  2008-01-04 13:22     ` Georg Bauhaus
  2008-01-04 14:17     ` Dmitry A. Kazakov
  1 sibling, 2 replies; 14+ messages in thread
From: Philippe Tarroux @ 2008-01-04 13:08 UTC (permalink / raw)


Dmitry A. Kazakov a �crit :
>
> The function A_Data returns Data. It is a primitive operation of Data and
> thus covariant in the result. So when you derive anything from Data, you
> have to override it in order to provide a correct implementation that would
> return the derived type rather than the base.
>   
Ok. But does it mean that only the constructor is a primitive operation 
of the data type, not the print procedure? In this case why Print 
doesn't need to be redefined?
> There are many ways to resolve the issue, the choice depends on other
> factors:
>
> 1. Class-wide A_Data:
>
>    function A_Data (V : Integer) return Data'Class;
>
> This will be same (contravariant) for all descendants of A_Data and thus
> need not to overridden.
>
> 2. Data-specific List package:
>
> generic
>    type Data is abstract new Data_Handler.Data with private;
> package Data_List is
>    ...
>    type Item is new Data with record
>       Next : Item_Ptr;
>    end record;
>    function A_Data (V : Integer) return Item;
>
> We know here that Data is a descendant of Data_Handler.Data, so we can
> provide an override for A_Data.
>
> 3. Aggregation instead of inheritance:
>
>    type Item is record
>       Next  : Item_Ptr;
>       Value : Data;
>    end record;
>
> No inheritance, no problem.
>
> 4. Non-generic implementation of lists. You can define a list interface and
> derive Data_Handler.Data from a list item. (In Ada 2005 it is easier to do
> than it was in Ada 95) That would reverse the inheritance order and thus
> solve the problem with A_Data.
>
> 5. Storage-pool based implementation of lists. You can design a storage
> pool that would maintain lists of allocated there items. In this case,
> unlikely to all other variants, the list item is not a fully separate type
> but just a pool-specific access to Data type. Because there again is no
> inheritance involved, the problem is solved.
>   
Thanks for all these suggestions that bring to me interesting insights. 
Especially i know that #4 solves the problem (it is the alternative 
proposed in Barnes for the construction of list items). I won't be aware 
of #5. I will try it.

Regards

Philippe Tarroux



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: tagged type as generic parameter
  2008-01-03 21:37         ` Jeffrey R. Carter
@ 2008-01-04 13:08           ` Philippe Tarroux
  2008-01-04 15:03             ` Jean-Pierre Rosen
  0 siblings, 1 reply; 14+ messages in thread
From: Philippe Tarroux @ 2008-01-04 13:08 UTC (permalink / raw)


Jeffrey R. Carter a �crit :
> Jean-Pierre Rosen wrote:
>> Yeap. In these times where everybody is talking about OOP, people 
>> tend to move from "everything can be done with inheritance" to 
>> "everything must be done with inheritance". To be honnest, some 
>> languages offer inheritance as the only way, so there is no choice.
>
> Given the OP's comment that the formal is tagged so that he will be 
> able to build lists of the type implies that he comes from a 
> background in such a language.
What i wanted is not the "best" way to implement lists. I just wanted to 
explore this way. The strong OOP orientation is due to the fact that i 
tried this example after a discussion with one of my student arguing 
that Ada is too complex compared to Java. I wanted to explore '� la 
Java' solutions.
>
>> When you are lucky enough to have a language that supports multiple 
>> paradigms, composition has its value.
I agree too.

Philippe Tarroux



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: tagged type as generic parameter
  2008-01-04 13:08   ` Philippe Tarroux
@ 2008-01-04 13:22     ` Georg Bauhaus
  2008-01-04 15:38       ` Philippe Tarroux
  2008-01-04 14:17     ` Dmitry A. Kazakov
  1 sibling, 1 reply; 14+ messages in thread
From: Georg Bauhaus @ 2008-01-04 13:22 UTC (permalink / raw)



On Fri, 2008-01-04 at 14:08 +0100, Philippe Tarroux wrote:
> Dmitry A. Kazakov a écrit :
> >
> > The function A_Data returns Data. It is a primitive operation of Data and
> > thus covariant in the result. So when you derive anything from Data, you
> > have to override it in order to provide a correct implementation that would
> > return the derived type rather than the base.
> >   
> Ok. But does it mean that only the constructor is a primitive operation 
> of the data type, not the print procedure? In this case why Print 
> doesn't need to be redefined?

Data's Print operation works for objects of any type rooted at
Data. There is always a Data view of such an object.

OTOH, a function that is to return an object of a type
derived from Data will have to provide all components
of the derived type. That's not the LRM reason for the need
to override the function. But it should be a hint as to
why this need exists (the variance issue Dmitry has mentioned).

Imagine this

   Data
         function make (...) return Data;
    ^
    |  -- inheritance, IS A
  Special_Data


When you have a variable V of type Special_Data
and you call

  V := make (...);

then---without an overridden make---this Make would have to be
the Make defined with type Data. However, the Make defined
with Data cannot return objects of type Special_Data, which
is needed.

OTOH, When you have a variable V of type Special_Data
and you call

  print(V);

there is no problem because Print works with Data
objects and V "IS A" Data object (its type is derived
from Data.) So Print views V as being of type Data,
not Special_Data, in a sense.

HTH, Georg





^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: tagged type as generic parameter
  2008-01-04 13:08   ` Philippe Tarroux
  2008-01-04 13:22     ` Georg Bauhaus
@ 2008-01-04 14:17     ` Dmitry A. Kazakov
  1 sibling, 0 replies; 14+ messages in thread
From: Dmitry A. Kazakov @ 2008-01-04 14:17 UTC (permalink / raw)


On Fri, 04 Jan 2008 14:08:52 +0100, Philippe Tarroux wrote:

> Dmitry A. Kazakov a �crit :

>> The function A_Data returns Data. It is a primitive operation of Data and
>> thus covariant in the result. So when you derive anything from Data, you
>> have to override it in order to provide a correct implementation that would
>> return the derived type rather than the base.
>>   
> Ok. But does it mean that only the constructor is a primitive operation 
> of the data type, not the print procedure? In this case why Print 
> doesn't need to be redefined?

Right, the reason why Print need not to be overridden is that it has Data
passed in the in-mode. So the caller has Data already constructed
elsewhere. For the same reason a procedure with an in-out-mode parameter
can be safely inherited too. Considering strictly out-mode parameters, it
could be otherwise, in general case. But in Ada tagged types have to be
constrained and constructed even when they are outs.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: tagged type as generic parameter
  2008-01-04 13:08           ` Philippe Tarroux
@ 2008-01-04 15:03             ` Jean-Pierre Rosen
  0 siblings, 0 replies; 14+ messages in thread
From: Jean-Pierre Rosen @ 2008-01-04 15:03 UTC (permalink / raw)


Philippe Tarroux a �crit :
>> Given the OP's comment that the formal is tagged so that he will be 
>> able to build lists of the type implies that he comes from a 
>> background in such a language.
> What i wanted is not the "best" way to implement lists. I just wanted to 
> explore this way. The strong OOP orientation is due to the fact that i 
> tried this example after a discussion with one of my student arguing 
> that Ada is too complex compared to Java. I wanted to explore '� la 
> Java' solutions.
Of course, '� la Java' solutions coded in Ada will always be 
disadvantaged; the converse is also true.

When discussing language complexity, I think you should start from a 
real problem (without overspecification!), code it in each language 
following each language's philosophy, and compare the result. Everything 
else is biased.

-- 
---------------------------------------------------------
            J-P. Rosen (rosen@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: tagged type as generic parameter
  2008-01-04 13:22     ` Georg Bauhaus
@ 2008-01-04 15:38       ` Philippe Tarroux
  0 siblings, 0 replies; 14+ messages in thread
From: Philippe Tarroux @ 2008-01-04 15:38 UTC (permalink / raw)


Georg Bauhaus a écrit :
> On Fri, 2008-01-04 at 14:08 +0100, Philippe Tarroux wrote:
>   
>> Dmitry A. Kazakov a écrit :
>>     
>>> The function A_Data returns Data. It is a primitive operation of Data and
>>> thus covariant in the result. So when you derive anything from Data, you
>>> have to override it in order to provide a correct implementation that would
>>> return the derived type rather than the base.
>>>   
>>>       
>> Ok. But does it mean that only the constructor is a primitive operation 
>> of the data type, not the print procedure? In this case why Print 
>> doesn't need to be redefined?
>>     
>
> Data's Print operation works for objects of any type rooted at
> Data. There is always a Data view of such an object.
>
> OTOH, a function that is to return an object of a type
> derived from Data will have to provide all components
> of the derived type. That's not the LRM reason for the need
> to override the function. But it should be a hint as to
> why this need exists (the variance issue Dmitry has mentioned).
>
> Imagine this
>
>    Data
>          function make (...) return Data;
>     ^
>     |  -- inheritance, IS A
>   Special_Data
>
>
> When you have a variable V of type Special_Data
> and you call
>
>   V := make (...);
>
> then---without an overridden make---this Make would have to be
> the Make defined with type Data. However, the Make defined
> with Data cannot return objects of type Special_Data, which
> is needed.
>
> OTOH, When you have a variable V of type Special_Data
> and you call
>
>   print(V);
>
> there is no problem because Print works with Data
> objects and V "IS A" Data object (its type is derived
> from Data.) So Print views V as being of type Data,
> not Special_Data, in a sense.
>
> HTH, Georg
>
>   
Thanks for your explanations. That's all clear for me now.

 I have missed this point which is similar to the one raised in Barnes 
about Geometry.Triangles. He suggests that a way to avoid the 
redefinition of the constructor when there is no need of it or when the 
constructor of the derived type hasn't the same structure of parameters, 
is to use a child function. In this case the function is not a primitive 
operation of the type.

I am going to look if it can apply to the present case.

Philippe



^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2008-01-04 15:38 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-01-03 15:20 tagged type as generic parameter Philippe Tarroux
2008-01-03 15:51 ` Dmitry A. Kazakov
2008-01-03 16:22   ` Adam Beneschan
2008-01-03 16:58     ` Dmitry A. Kazakov
2008-01-03 17:47       ` Jean-Pierre Rosen
2008-01-03 18:13         ` Pascal Obry
2008-01-03 19:20         ` Dmitry A. Kazakov
2008-01-03 21:37         ` Jeffrey R. Carter
2008-01-04 13:08           ` Philippe Tarroux
2008-01-04 15:03             ` Jean-Pierre Rosen
2008-01-04 13:08   ` Philippe Tarroux
2008-01-04 13:22     ` Georg Bauhaus
2008-01-04 15:38       ` Philippe Tarroux
2008-01-04 14:17     ` Dmitry A. Kazakov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox