comp.lang.ada
 help / color / mirror / Atom feed
* Dispatch on the result still does not work?
@ 2009-07-11 10:04 Dmitry A. Kazakov
  2009-07-11 11:09 ` Chris Moore
                   ` (3 more replies)
  0 siblings, 4 replies; 30+ messages in thread
From: Dmitry A. Kazakov @ 2009-07-11 10:04 UTC (permalink / raw)


Considering this one:

package P is
   type T is tagged null record;
   function Value return T;
      
   type S is new T with null record;
   function Value return S;
end P;
      
package body P is
   function Value return T is
   begin
      return (null record);
   end Value;
      
   function Value return S is
   begin
      return (T with null record);
   end Value;
end P;

use P;
   
   X : T'Class := S'(Value);
begin
   X := Value; -- Ambiguous?

I would expect it rather dispatching on the tag of X, i.e. selecting Value,
which returns S.

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



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

* Re: Dispatch on the result still does not work?
  2009-07-11 10:04 Dispatch on the result still does not work? Dmitry A. Kazakov
@ 2009-07-11 11:09 ` Chris Moore
  2009-07-11 12:05   ` Dmitry A. Kazakov
  2009-07-11 11:32 ` Hibou57 (Yannick Duchêne)
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 30+ messages in thread
From: Chris Moore @ 2009-07-11 11:09 UTC (permalink / raw)


Dmitry A. Kazakov wrote:
> Considering this one:
> 
> package P is
>    type T is tagged null record;
>    function Value return T;
>       
>    type S is new T with null record;
>    function Value return S;
> end P;
>       
> package body P is
>    function Value return T is
>    begin
>       return (null record);
>    end Value;
>       
>    function Value return S is
>    begin
>       return (T with null record);
>    end Value;
> end P;
> 
> use P;
>    
>    X : T'Class := S'(Value);
> begin
>    X := Value; -- Ambiguous?
> 
> I would expect it rather dispatching on the tag of X, i.e. selecting Value,
> which returns S.
> 

But X is of type T'Class.  Or did you mean X := X.Value;?



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

* Re: Dispatch on the result still does not work?
  2009-07-11 10:04 Dispatch on the result still does not work? Dmitry A. Kazakov
  2009-07-11 11:09 ` Chris Moore
@ 2009-07-11 11:32 ` Hibou57 (Yannick Duchêne)
  2009-07-11 12:20   ` Dmitry A. Kazakov
  2009-07-11 18:54 ` Georg Bauhaus
  2009-07-13 15:13 ` Adam Beneschan
  3 siblings, 1 reply; 30+ messages in thread
From: Hibou57 (Yannick Duchêne) @ 2009-07-11 11:32 UTC (permalink / raw)


On 11 juil, 12:04, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> use P;
>
>    X : T'Class := S'(Value);
> begin
>    X := Value; -- Ambiguous?
>
> I would expect it rather dispatching on the tag of X, i.e. selecting Value,
> which returns S.
>
> --
> Regards,
> Dmitry A. Kazakovhttp://www.dmitry-kazakov.de

Using this main program:

> with P;
> procedure Q is
>    X : P.T'Class := P.S'(P.Value);
> begin
>    X := P.Value;
> end;

I indeed got an ambiguity error. What was predictable.

There is no tagged argument here which controls the dispatching.

This is not like some other language which assume an implicite
argument.

Doing this:

> with P;
> procedure Q is
>    X : P.T'Class := P.S'(P.Value);
> begin
>    X := P.T'(P.Value);
> end;

works fine.

But doing so:
> with P;
> procedure Q is
>    X : P.T'Class := P.S'(P.Value);
> begin
>    X := P.S'(P.Value);
> end;

is rejected, whith a reference to RM 5.2(6), which states:
> RM 5.2 6
> If the target is of a tagged class-wide type T'Class,
> then the expression shall either be dynamically tagged,
> or of type T and tag-indeterminate (see 3.9.2).

In your example, Value is tag-indeterminate, as there is not tagged
argument to control the dispatching (back to the first assertion about
the fact).

Hint: the ARM excerpt makes a reference to 3.9.2, which is titled “
Dispatching Operations of Tagged Types
 ” and seems indeed worth reading in this purpose.

My personal opinion is that there is no trouble here, as there is no
tagged type to control the execution. While in the mean time, I
understand what you mean : you are consedering the return value target
as the out parameter of a procedure. But this is not an out parameter
of a procedure, this is a result returned by a function.




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

* Re: Dispatch on the result still does not work?
  2009-07-11 11:09 ` Chris Moore
@ 2009-07-11 12:05   ` Dmitry A. Kazakov
  2009-07-11 17:50     ` Chris Moore
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry A. Kazakov @ 2009-07-11 12:05 UTC (permalink / raw)


On Sat, 11 Jul 2009 12:09:57 +0100, Chris Moore wrote:

> Dmitry A. Kazakov wrote:
>> Considering this one:
>> 
>> package P is
>>    type T is tagged null record;
>>    function Value return T;
>>       
>>    type S is new T with null record;
>>    function Value return S;
>> end P;
>>       
>> package body P is
>>    function Value return T is
>>    begin
>>       return (null record);
>>    end Value;
>>       
>>    function Value return S is
>>    begin
>>       return (T with null record);
>>    end Value;
>> end P;
>> 
>> use P;
>>    
>>    X : T'Class := S'(Value);
>> begin
>>    X := Value; -- Ambiguous?
>> 
>> I would expect it rather dispatching on the tag of X, i.e. selecting Value,
>> which returns S.
>> 
> 
> But X is of type T'Class.  Or did you mean X := X.Value;?

No. I meant function Value that has no arguments.

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



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

* Re: Dispatch on the result still does not work?
  2009-07-11 11:32 ` Hibou57 (Yannick Duchêne)
@ 2009-07-11 12:20   ` Dmitry A. Kazakov
  2009-07-11 13:36     ` Hibou57 (Yannick Duchêne)
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry A. Kazakov @ 2009-07-11 12:20 UTC (permalink / raw)


On Sat, 11 Jul 2009 04:32:49 -0700 (PDT), Hibou57 (Yannick Duch�ne) wrote:

> There is no tagged argument here which controls the dispatching.
[...]
> My personal opinion is that there is no trouble here, as there is no
> tagged type to control the execution. While in the mean time, I
> understand what you mean : you are consedering the return value target
> as the out parameter of a procedure. But this is not an out parameter
> of a procedure, this is a result returned by a function.

Yes the tagged "parameter" in this case is the result X, the target.
Conceptually there is no any difference between parameters and results of a
subprogram (I leave subtle issues about object constraints, which are
irrelevant here).

Since the target is class-wide of the type T'Class with the actual tag of
S'Tag, the call to Value should be considered dispatching, and resolved to
S'(Value).

Unfortunately it is still not. In Ada 95 it didn't work either. I don't
know if there is an AI to fix this problem, or it is still considered
"right" thing.

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



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

* Re: Dispatch on the result still does not work?
  2009-07-11 12:20   ` Dmitry A. Kazakov
@ 2009-07-11 13:36     ` Hibou57 (Yannick Duchêne)
  2009-07-11 13:39       ` Hibou57 (Yannick Duchêne)
  2009-07-11 15:19       ` Dmitry A. Kazakov
  0 siblings, 2 replies; 30+ messages in thread
From: Hibou57 (Yannick Duchêne) @ 2009-07-11 13:36 UTC (permalink / raw)


On 11 juil, 14:20, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> Conceptually there is no any difference between parameters and results of a
> subprogram

IMHO, there is a difference. A result is something created, not
something assigned to. It is not like an out formal parameter, which
is intended to be use for an assignment.

Until the function creates the return value, the return value does not
exist. The result of the function may be may or may be not later
assigned to a variable, this matter it out of the function's
responsabilities.

Here is how it works with an out parameter:
+ an instance of a variable exists
+ a procedure is invoked giving it the instance of this variable as a
formal out parameter
+ the procedure assign something to an instance which already exists

Here is how it works with a function (conceptually):
+ the function is invoked
+ it creates a result
+ the returned created result is handled in various way by the calle

This is onceptually not the same.

Then if you have “ A := F (B); ”, for optimization purpose, the
compiler may implement it passing a reference to A to the function F,
and F may directly assign the result to the A reference, but this is
not the concept, this is a particular implementation.

Now, what if the function is invoked for a formal parameter which is,
let say “ Parameter : T'Class ” ? You view of the “ concept ” is no
more valid in this context (no more tagged value any more, unless you
expect to rely on a default for this formal parameter), and in any
way, the compiler will no more be able to apply the later optimization
exemple.

Conceptually, returning a result from a function, is not an
assignment, this is.... just returning a result from a function. If it
later turns into an assignment, this is a matter of the usage of the
function, not a matter of the work of the function. As a proof, this
happens only later, after the function was invoked, and more than
that, the result may not be assigned to any variable.

Have a nice time Dmitry



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

* Re: Dispatch on the result still does not work?
  2009-07-11 13:36     ` Hibou57 (Yannick Duchêne)
@ 2009-07-11 13:39       ` Hibou57 (Yannick Duchêne)
  2009-07-11 15:19       ` Dmitry A. Kazakov
  1 sibling, 0 replies; 30+ messages in thread
From: Hibou57 (Yannick Duchêne) @ 2009-07-11 13:39 UTC (permalink / raw)


P.S. I've forgot to underline: the invokation of a function, is
conceptually an expression.



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

* Re: Dispatch on the result still does not work?
  2009-07-11 13:36     ` Hibou57 (Yannick Duchêne)
  2009-07-11 13:39       ` Hibou57 (Yannick Duchêne)
@ 2009-07-11 15:19       ` Dmitry A. Kazakov
  2009-07-11 18:08         ` Hibou57 (Yannick Duchêne)
  1 sibling, 1 reply; 30+ messages in thread
From: Dmitry A. Kazakov @ 2009-07-11 15:19 UTC (permalink / raw)


On Sat, 11 Jul 2009 06:36:48 -0700 (PDT), Hibou57 (Yannick Duchêne) wrote:

> On 11 juil, 14:20, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> wrote:
>> Conceptually there is no any difference between parameters and results of a
>> subprogram
> 
> IMHO, there is a difference. A result is something created, not
> something assigned to.
>
> Until the function creates the return value, the return value does not
> exist.

(You mean here "the return object". The value has existed and continues to
exist. Value is a property of the type, e.g. 123 exists even if you don't
have any Integer variable holding it.)

> Now, what if the function is invoked for a formal parameter which is,
> let say “ Parameter : T'Class ” ?

The actual object is converted to T'Class (per view conversion). This is a
different case,... or not. All depends on how to treat the assignment
statement.

> Conceptually, returning a result from a function, is not an
> assignment, this is.... just returning a result from a function. If it
> later turns into an assignment, this is a matter of the usage of the
> function, not a matter of the work of the function. As a proof, this
> happens only later, after the function was invoked, and more than
> that, the result may not be assigned to any variable.

Well, I used to think the way like you do until Ada 2005 introduced limited
aggregates and initialization of limited objects and their components using
functions... (:-))

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



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

* Re: Dispatch on the result still does not work?
  2009-07-11 12:05   ` Dmitry A. Kazakov
@ 2009-07-11 17:50     ` Chris Moore
  2009-07-11 19:22       ` Dmitry A. Kazakov
  0 siblings, 1 reply; 30+ messages in thread
From: Chris Moore @ 2009-07-11 17:50 UTC (permalink / raw)


Dmitry A. Kazakov wrote:
> On Sat, 11 Jul 2009 12:09:57 +0100, Chris Moore wrote:
> 
>> Dmitry A. Kazakov wrote:
>>> Considering this one:
>>>
>>> package P is
>>>    type T is tagged null record;
>>>    function Value return T;
>>>       
>>>    type S is new T with null record;
>>>    function Value return S;
>>> end P;
>>>       
>>> package body P is
>>>    function Value return T is
>>>    begin
>>>       return (null record);
>>>    end Value;
>>>       
>>>    function Value return S is
>>>    begin
>>>       return (T with null record);
>>>    end Value;
>>> end P;
>>>
>>> use P;
>>>    
>>>    X : T'Class := S'(Value);
>>> begin
>>>    X := Value; -- Ambiguous?
>>>
>>> I would expect it rather dispatching on the tag of X, i.e. selecting Value,
>>> which returns S.
>>>
>> But X is of type T'Class.  Or did you mean X := X.Value;?
> 
> No. I meant function Value that has no arguments.

Then both versions of Value are in scope and return types that can be
assigned to T'Class.  Sounds ambiguous to me.

X := S'(Value);?



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

* Re: Dispatch on the result still does not work?
  2009-07-11 15:19       ` Dmitry A. Kazakov
@ 2009-07-11 18:08         ` Hibou57 (Yannick Duchêne)
  2009-07-11 19:29           ` Dmitry A. Kazakov
  0 siblings, 1 reply; 30+ messages in thread
From: Hibou57 (Yannick Duchêne) @ 2009-07-11 18:08 UTC (permalink / raw)


On 11 juil, 17:19, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> Well, I used to think the way like you do until Ada 2005 introduced limited
> aggregates and initialization of limited objects and their components using
> functions... (:-))
This does not stand for the general case of a function. This is a
specific requirement, which may in some way be compared to the
previoulsy given implementation optimization exemple. The difference
here, is that this is not an implementation optimization, but a “ low
level ” semantic requirement like the support for controling
initialization/adjustement of objects... the kind of aspect which
tipically reside in the private part of a package specification  ;-) .
This is a special subset of what a function may-be, which is not the
same as the general case of a function. Any way, this still handled
separately, this is something standing around the function, this is
not the function. The extended return statement is still a return
statement, which may be used in any others functions... which finally
makes it rather conform to what a function is in its general case.

BTW: Yes, you're right about the value vs the object (I did not get
the good word)

Annotated ARM 7.5 - “ Limited Types ”
> 8.1/2 {AI95-00287-01} {AI95-00318-02} For an aggregate of a limited
> type used to initialize an object as allowed above, the
> implementation shall not create a separate anonymous object for the
> aggregate. For a function_call of a type with a part that is of a
> task, protected, or explicitly limited record type that is used to
> initialize an object as allowed above, the implementation shall not
> create a separate return object (see 6.5) for the function_call. The
> aggregate or function_call shall be constructed directly in the new
> object.
> -
> 8.a/2Discussion: {AI95-00318-02} For a function_call, we only
> require build-in-place{build-in-place [partial]} for a limited type
> that would have been a return-by-reference type in Ada 95. We do
> this because we want to minimize disruption to Ada 95
> implementations and users.
> -
> NOTES
> 9/214 {AI95-00287-01} {AI95-00318-02} While it is allowed to write
> initializations of limited objects, such initializations never copy
> a limited object. The source of such an assignment operation must be
> an aggregate or function_call, and such aggregates and
> function_calls must be built directly in the target object. The
> following are consequences of the rules for limited types:

Yes, but how would you initialize a limited type another way, while it
cannot be assigned by copy ? This is a mandatory semantic requirement.
But the function still acts as an initializer expression in the user's
view point.

Annotated ARM 7.5 (again)
> 2.e/2 Discussion: All of these contexts normally require copying; by
> restricting the uses as above, we can require the new object to be
> built-in-place.
> -
> [...]
> -
> 9/214 {AI95-00287-01} {AI95-00318-02} While it is allowed to write
> initializations of limited objects, such initializations never copy
> a limited object. The source of such an assignment operation must be
> an aggregate or function_call, and such aggregates and
> function_calls must be built directly in the target object. The
> following are consequences of the rules for limited types:

The requirement is well based



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

* Re: Dispatch on the result still does not work?
  2009-07-11 10:04 Dispatch on the result still does not work? Dmitry A. Kazakov
  2009-07-11 11:09 ` Chris Moore
  2009-07-11 11:32 ` Hibou57 (Yannick Duchêne)
@ 2009-07-11 18:54 ` Georg Bauhaus
  2009-07-11 19:40   ` Dmitry A. Kazakov
  2009-07-13 15:13 ` Adam Beneschan
  3 siblings, 1 reply; 30+ messages in thread
From: Georg Bauhaus @ 2009-07-11 18:54 UTC (permalink / raw)


Dmitry A. Kazakov wrote:
> Considering this one:

> I would expect it rather dispatching on the tag of X, i.e. selecting Value,
> which returns S.
> 

Another one, I don't like to call this a solution,
and the running program differs per compiler
used. But both compilers compile the units without errors:

package P is

   type T is tagged null record;

   function Value return T;
   function Dispatched(X, V: T) return T'Class;

   type S is new T with null record;

   function Value return S;
   function Dispatched(X, V: S) return T'Class;

end P;

with Ada.Text_IO;
package body P is

   function Dispatched(X, V: T) return T'Class is
   begin
      return V;
   end Dispatched;

   function Dispatched(X, V: S) return T'Class is
   begin
      return V;
   end Dispatched;

   function Value return T is
   begin
      Ada.Text_IO.Put_Line("Value returns a T");
      return T'(null record);
   end Value;

   function Value return S is
   begin
      Ada.Text_IO.Put_Line("Value returns an S");
      return S'(T with null record);
   end Value;

end P;


with P;
procedure Run_P is

   use P;

   X: T'Class := S'(Value);
begin
   X := Dispatched(X, Value);
end Run_P;



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

* Re: Dispatch on the result still does not work?
  2009-07-11 17:50     ` Chris Moore
@ 2009-07-11 19:22       ` Dmitry A. Kazakov
  0 siblings, 0 replies; 30+ messages in thread
From: Dmitry A. Kazakov @ 2009-07-11 19:22 UTC (permalink / raw)


On Sat, 11 Jul 2009 18:50:42 +0100, Chris Moore wrote:

> Dmitry A. Kazakov wrote:
>> On Sat, 11 Jul 2009 12:09:57 +0100, Chris Moore wrote:
>> 
>>> Dmitry A. Kazakov wrote:
>>>> Considering this one:
>>>>
>>>> package P is
>>>>    type T is tagged null record;
>>>>    function Value return T;
>>>>       
>>>>    type S is new T with null record;
>>>>    function Value return S;
>>>> end P;
>>>>       
>>>> package body P is
>>>>    function Value return T is
>>>>    begin
>>>>       return (null record);
>>>>    end Value;
>>>>       
>>>>    function Value return S is
>>>>    begin
>>>>       return (T with null record);
>>>>    end Value;
>>>> end P;
>>>>
>>>> use P;
>>>>    
>>>>    X : T'Class := S'(Value);
>>>> begin
>>>>    X := Value; -- Ambiguous?
>>>>
>>>> I would expect it rather dispatching on the tag of X, i.e. selecting Value,
>>>> which returns S.
>>>>
>>> But X is of type T'Class.  Or did you mean X := X.Value;?
>> 
>> No. I meant function Value that has no arguments.
> 
> Then both versions of Value are in scope and return types that can be
> assigned to T'Class.  Sounds ambiguous to me.

It is, if you don't consider them dispatching, which was the question.

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



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

* Re: Dispatch on the result still does not work?
  2009-07-11 18:08         ` Hibou57 (Yannick Duchêne)
@ 2009-07-11 19:29           ` Dmitry A. Kazakov
  2009-07-11 23:22             ` Hibou57 (Yannick Duchêne)
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry A. Kazakov @ 2009-07-11 19:29 UTC (permalink / raw)


On Sat, 11 Jul 2009 11:08:55 -0700 (PDT), Hibou57 (Yannick Duch�ne) wrote:

> Yes, but how would you initialize a limited type another way, while it
> cannot be assigned by copy?

I would not. A limited object (actually any object) is to be constructed,
by a constructor, which cannot be a function or procedure. (The current
solution is like a conceptual Swiss cheese)

> This is a mandatory semantic requirement.
> But the function still acts as an initializer expression in the user's
> view point.

It does not return any object in this case.

If a function can act as an "initializer", it can also act as the right
side of the assignment in a dispatching way. (I am not sure if I really
wanted this, just out of curiosity.)

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



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

* Re: Dispatch on the result still does not work?
  2009-07-11 18:54 ` Georg Bauhaus
@ 2009-07-11 19:40   ` Dmitry A. Kazakov
  2009-07-12 10:40     ` Chris Moore
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry A. Kazakov @ 2009-07-11 19:40 UTC (permalink / raw)


On Sat, 11 Jul 2009 20:54:05 +0200, Georg Bauhaus wrote:

> Dmitry A. Kazakov wrote:

>> Considering this one:
> 
>> I would expect it rather dispatching on the tag of X, i.e. selecting Value,
>> which returns S.
> 
> Another one, I don't like to call this a solution,
> and the running program differs per compiler
> used. But both compilers compile the units without errors:
[...]

I am not sure that it indeed should be resolved. The question is whether
there exist or should exist cases where one could indeed dispatch on the
result's type. The construct with assignment was admittedly artificial, it
was first that came to mind.

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



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

* Re: Dispatch on the result still does not work?
  2009-07-11 19:29           ` Dmitry A. Kazakov
@ 2009-07-11 23:22             ` Hibou57 (Yannick Duchêne)
  2009-07-12  9:46               ` Dmitry A. Kazakov
  0 siblings, 1 reply; 30+ messages in thread
From: Hibou57 (Yannick Duchêne) @ 2009-07-11 23:22 UTC (permalink / raw)


On 11 juil, 21:29, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> I would not. A limited object (actually any object) is to be constructed,
> by a constructor, which cannot be a function or procedure. (The current
> solution is like a conceptual Swiss cheese)

Your mean another syntatic construct would be welcome to make things
more distinct ?



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

* Re: Dispatch on the result still does not work?
  2009-07-11 23:22             ` Hibou57 (Yannick Duchêne)
@ 2009-07-12  9:46               ` Dmitry A. Kazakov
  0 siblings, 0 replies; 30+ messages in thread
From: Dmitry A. Kazakov @ 2009-07-12  9:46 UTC (permalink / raw)


On Sat, 11 Jul 2009 16:22:01 -0700 (PDT), Hibou57 (Yannick Duch�ne) wrote:

> On 11 juil, 21:29, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> wrote:
>> I would not. A limited object (actually any object) is to be constructed,
>> by a constructor, which cannot be a function or procedure. (The current
>> solution is like a conceptual Swiss cheese)
> 
> Your mean another syntatic construct would be welcome to make things
> more distinct ?

No, the syntax is already here:

   X : T (<parameter-list>);

What is needed is an ability to require some procedures (like Initialize)
to be called at a certain stages of object construction. There are three
key stages of construction where a user-defined procedure can be called:

1. Determination of constraints (discriminants, bounds, etc)
    |
    V
   allocation
    |
    V
   construction of the components
    |
    V
   construction of the parents
    |
    V
2. Type-specific initialization
    |
    V   (if class-wide)
   construction of the parent classes
    |
    V
3. Class-specific initialization

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



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

* Re: Dispatch on the result still does not work?
  2009-07-11 19:40   ` Dmitry A. Kazakov
@ 2009-07-12 10:40     ` Chris Moore
  2009-07-12 11:30       ` Dmitry A. Kazakov
  0 siblings, 1 reply; 30+ messages in thread
From: Chris Moore @ 2009-07-12 10:40 UTC (permalink / raw)


Dmitry A. Kazakov wrote:
> On Sat, 11 Jul 2009 20:54:05 +0200, Georg Bauhaus wrote:
> 
>> Dmitry A. Kazakov wrote:
> 
>>> Considering this one:
>>> I would expect it rather dispatching on the tag of X, i.e. selecting Value,
>>> which returns S.
>> Another one, I don't like to call this a solution,
>> and the running program differs per compiler
>> used. But both compilers compile the units without errors:
> [...]
> 
> I am not sure that it indeed should be resolved. The question is whether
> there exist or should exist cases where one could indeed dispatch on the
> result's type. The construct with assignment was admittedly artificial, it
> was first that came to mind.
> 

But the results type is T'Class.  It is not S.  The original object to
which X refers is of type S.  But this is destroyed prior to the
assignment of the value returned by Value.  This can be either S or T.

With Georg's solution you now have three answers of the Ada way to
resolve the ambiguity.



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

* Re: Dispatch on the result still does not work?
  2009-07-12 10:40     ` Chris Moore
@ 2009-07-12 11:30       ` Dmitry A. Kazakov
  2009-07-12 16:05         ` Chris Moore
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry A. Kazakov @ 2009-07-12 11:30 UTC (permalink / raw)


On Sun, 12 Jul 2009 11:40:27 +0100, Chris Moore wrote:

> Dmitry A. Kazakov wrote:
>> On Sat, 11 Jul 2009 20:54:05 +0200, Georg Bauhaus wrote:
>> 
>>> Dmitry A. Kazakov wrote:
>> 
>>>> Considering this one:
>>>> I would expect it rather dispatching on the tag of X, i.e. selecting Value,
>>>> which returns S.
>>> Another one, I don't like to call this a solution,
>>> and the running program differs per compiler
>>> used. But both compilers compile the units without errors:
>> [...]
>> 
>> I am not sure that it indeed should be resolved. The question is whether
>> there exist or should exist cases where one could indeed dispatch on the
>> result's type. The construct with assignment was admittedly artificial, it
>> was first that came to mind.
>> 
> 
> But the results type is T'Class.  It is not S.

Exactly. To be of T'Class is a prerequisite for dispatch.

> The original object to
> which X refers is of type S.

Therefore it could dispatch using S'Tag.

> But this is destroyed prior to the
> assignment of the value returned by Value.

This is an implementation detail.

>  This can be either S or T.

No, if you drag this detail on the surface, then it is strictly neither,
because the object has been destroyed, and there is nothing in there. In
this case writing anything into the object is a type error.

To put it short assignment /= initialization. Assignment is indivisible
without breaking the type system.

Further depending on how assignment is annotated, considering it a
procedure or as finalization + initialization by a function, etc, one can
come different conclusions whether it should dispatch or not. For example
it can be annotated as

   procedure (Left, Right : T); -- doubly-dispatching, primitive

or

   procedure (Left : T'Class; Right : T);  -- primitive

or

   procedure (Left : T'Class; Right : T'Class);  -- class-wide

etc.

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



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

* Re: Dispatch on the result still does not work?
  2009-07-12 11:30       ` Dmitry A. Kazakov
@ 2009-07-12 16:05         ` Chris Moore
  2009-07-12 16:38           ` Dmitry A. Kazakov
  0 siblings, 1 reply; 30+ messages in thread
From: Chris Moore @ 2009-07-12 16:05 UTC (permalink / raw)


Dmitry A. Kazakov wrote:
> On Sun, 12 Jul 2009 11:40:27 +0100, Chris Moore wrote:

<snip>

>> But the results type is T'Class.  It is not S.
> 
> Exactly. To be of T'Class is a prerequisite for dispatch.
> 
>> The original object to
>> which X refers is of type S.
> 
> Therefore it could dispatch using S'Tag.

Only if you use X.Value.

>> But this is destroyed prior to the
>> assignment of the value returned by Value.
> 
> This is an implementation detail.

This is how assignment works no matter what the language!



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

* Re: Dispatch on the result still does not work?
  2009-07-12 16:05         ` Chris Moore
@ 2009-07-12 16:38           ` Dmitry A. Kazakov
  2009-07-12 17:11             ` AdaMagica
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry A. Kazakov @ 2009-07-12 16:38 UTC (permalink / raw)


On Sun, 12 Jul 2009 17:05:06 +0100, Chris Moore wrote:

> Dmitry A. Kazakov wrote:
>> On Sun, 12 Jul 2009 11:40:27 +0100, Chris Moore wrote:
> 
> <snip>
> 
>>> But the results type is T'Class.  It is not S.
>> 
>> Exactly. To be of T'Class is a prerequisite for dispatch.
>> 
>>> The original object to
>>> which X refers is of type S.
>> 
>> Therefore it could dispatch using S'Tag.
> 
> Only if you use X.Value.

Why shouldn't it? Consider:

   X : String := "abc";
begin
   X := ...;

You have to use the value of X here in order to know the constraint checked
in the assignment.

Your premise that there is no or cannot be any interaction between the left
and right hand sides of the assignment is wrong. In fact, in many cases it
is highly desirable to have an access to non-finalized LHS in assignment,
especially when dealing with memory-managed objects.

>>> But this is destroyed prior to the
>>> assignment of the value returned by Value.
>> 
>> This is an implementation detail.
> 
> This is how assignment works no matter what the language!

Strictly speaking it does not. An assignment cannot destroy anything before
assignment, i.e. itself. Destruction happens (if any) within the
assignment. Nothing tells at which point it has to be done.

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



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

* Re: Dispatch on the result still does not work?
  2009-07-12 16:38           ` Dmitry A. Kazakov
@ 2009-07-12 17:11             ` AdaMagica
  2009-07-12 20:30               ` sjw
  0 siblings, 1 reply; 30+ messages in thread
From: AdaMagica @ 2009-07-12 17:11 UTC (permalink / raw)


  X : T'Class := S'(Value);
begin
   X := Value; -- Ambiguous?

You know, I'm not a language lawyer, but after the initialization, X
is constrained to the tag with which it was initialized.

So to me, it should be dispatching as Dmitry expects.



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

* Re: Dispatch on the result still does not work?
  2009-07-12 17:11             ` AdaMagica
@ 2009-07-12 20:30               ` sjw
  2009-07-13 16:55                 ` Adam Beneschan
  0 siblings, 1 reply; 30+ messages in thread
From: sjw @ 2009-07-12 20:30 UTC (permalink / raw)


On Jul 12, 6:11 pm, AdaMagica <christoph.gr...@eurocopter.com> wrote:
>   X : T'Class := S'(Value);
> begin
>    X := Value; -- Ambiguous?
>
> You know, I'm not a language lawyer, but after the initialization, X
> is constrained to the tag with which it was initialized.
>
> So to me, it should be dispatching as Dmitry expects.

I think GNAT GPL 2009 might just have a problem in this area: this is
accepted

procedure Q is
   X : P.T'Class := P.S'(P.Value);
begin
   X := P.T'(P.Value);

but this fails

procedure Q is
   X : P.T'Class := P.T'(P.Value);
begin
   X := P.S'(P.Value);

saying 'tag-indeterminate expression must have type "T"(RM 5.2 (6))'



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

* Re: Dispatch on the result still does not work?
  2009-07-11 10:04 Dispatch on the result still does not work? Dmitry A. Kazakov
                   ` (2 preceding siblings ...)
  2009-07-11 18:54 ` Georg Bauhaus
@ 2009-07-13 15:13 ` Adam Beneschan
  2009-07-13 15:17   ` Adam Beneschan
  2009-07-13 18:46   ` Adam Beneschan
  3 siblings, 2 replies; 30+ messages in thread
From: Adam Beneschan @ 2009-07-13 15:13 UTC (permalink / raw)


On Jul 11, 3:04 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> Considering this one:
>
> package P is
>    type T is tagged null record;
>    function Value return T;
>
>    type S is new T with null record;
>    function Value return S;
> end P;
>
> package body P is
>    function Value return T is
>    begin
>       return (null record);
>    end Value;
>
>    function Value return S is
>    begin
>       return (T with null record);
>    end Value;
> end P;
>
> use P;
>
>    X : T'Class := S'(Value);
> begin
>    X := Value; -- Ambiguous?
>
> I would expect it rather dispatching on the tag of X, i.e. selecting Value,
> which returns S.

The problem here (I mean the problem with your program, not a problem
with the Ada language) is that the overloading rules, which determine
what the meaning of the identifier "Value" is when there is more than
one possibility, do not take the dynamic semantics into account.  The
overloading rules basically work like this: We consider all possible
combinations of all possible meanings of the identifiers, then keep
only the legal ones (legal according to the "legality rules"; a
construct can still be legal even if it will always raise an exception
at runtime).  If there is more than one legal possibility, the
construct is ambiguous.  (This oversimplifies things a bit; there are
some exceptions regarding abstract subprograms.)

Or, to put it another way: The compiler *first* has to determine what
each of the identifiers in the statement means.  Only after this is
determined, *then* can it apply the dynamic-semantics rules about
dispatching.

Suppose the Value that returns T does not exist:

  package P is
     type T is tagged null record;
  -- function Value return T;

     type S is new T with null record;
     function Value return S;
  end P;
  ...

  use P;

     X : T'Class := S'(Value);
  begin
     X := Value;

The question here is, is the assignment statement legal?  And the
answer is "Yes", because the expected type (the type of X) is T'Class,
and the type of Value is S, which is a type in that class (8.6(21)).
Since this is legal, then if we uncomment the first Value, there would
be two legal interpretations for the statement "X := Value", which
makes it ambiguous.

I believe this will work, although I'm not 100% certain; it is legal
and will dispatch, although the syntax could possibly make it look
like it won't dispatch:

     X : T'Class := S'(Value);
  begin
     X := T'(Value);

Making the call to Value a "qualified expression" tells the compiler
what the expected type of Value will be, and thus helps it determine
unambiguously which Value is meant.  If I have this straight, using a
qualified expression doesn't change the fact that the expression
("Value") is tag-indeterminate; and thus the assignment is still legal
by 5.2(6), and the call still dispatches by 3.9.2(18.1).

I think this also works:

     X : T'Class := S'(Value);
  begin
     declare
        function T_Value return T renames Pak1.Value;
     begin
        X := T_Value;
     end;

Again, the rename helps the compiler determine unambiguously which
Value subprogram is intended, but it doesn't change the fact that the
call to it is tag-indeterminate.  I'd need to pore over the rules more
closely to make sure of this, however.

Anyway, the important thing to remember is that the compiler first has
to determine which declaration is meant by every identifier in a
statement, and only *then* can it think about whether a call is
dispatching or not.

Hope this helps,

                                       -- Adam








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

* Re: Dispatch on the result still does not work?
  2009-07-13 15:13 ` Adam Beneschan
@ 2009-07-13 15:17   ` Adam Beneschan
  2009-07-13 16:33     ` AdaMagica
  2009-07-13 18:46   ` Adam Beneschan
  1 sibling, 1 reply; 30+ messages in thread
From: Adam Beneschan @ 2009-07-13 15:17 UTC (permalink / raw)


On Jul 13, 8:13 am, Adam Beneschan <a...@irvine.com> wrote:
> On Jul 11, 3:04 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> wrote:
>
>
>
>
>
> > Considering this one:
>
> > package P is
> >    type T is tagged null record;
> >    function Value return T;
>
> >    type S is new T with null record;
> >    function Value return S;
> > end P;
>
> > package body P is
> >    function Value return T is
> >    begin
> >       return (null record);
> >    end Value;
>
> >    function Value return S is
> >    begin
> >       return (T with null record);
> >    end Value;
> > end P;
>
> > use P;
>
> >    X : T'Class := S'(Value);
> > begin
> >    X := Value; -- Ambiguous?
>
> > I would expect it rather dispatching on the tag of X, i.e. selecting Value,
> > which returns S.
>
> The problem here (I mean the problem with your program, not a problem
> with the Ada language) is that the overloading rules, which determine
> what the meaning of the identifier "Value" is when there is more than
> one possibility, do not take the dynamic semantics into account.  The
> overloading rules basically work like this: We consider all possible
> combinations of all possible meanings of the identifiers, then keep
> only the legal ones (legal according to the "legality rules";

Technically, that should have read 'legal according to the "Name
Resolution Rules"'.  The rules listed as Legality Rules in the RM
aren't even considered here (thus, for example, a procedure call with
two meanings can be ambiguous even if one of them involves passing a
constant as an OUT parameter).  My point was that the rules in the
Dynamic Semantics are not considered at all during this phase.

                                  -- Adam




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

* Re: Dispatch on the result still does not work?
  2009-07-13 15:17   ` Adam Beneschan
@ 2009-07-13 16:33     ` AdaMagica
  0 siblings, 0 replies; 30+ messages in thread
From: AdaMagica @ 2009-07-13 16:33 UTC (permalink / raw)


Ah, thank you, Adam, for this fine explanation :-)



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

* Re: Dispatch on the result still does not work?
  2009-07-12 20:30               ` sjw
@ 2009-07-13 16:55                 ` Adam Beneschan
  2009-07-13 21:47                   ` sjw
  0 siblings, 1 reply; 30+ messages in thread
From: Adam Beneschan @ 2009-07-13 16:55 UTC (permalink / raw)


On Jul 12, 1:30 pm, sjw <simon.j.wri...@mac.com> wrote:
> On Jul 12, 6:11 pm, AdaMagica <christoph.gr...@eurocopter.com> wrote:
>
> >   X : T'Class := S'(Value);
> > begin
> >    X := Value; -- Ambiguous?
>
> > You know, I'm not a language lawyer, but after the initialization, X
> > is constrained to the tag with which it was initialized.
>
> > So to me, it should be dispatching as Dmitry expects.
>
> I think GNAT GPL 2009 might just have a problem in this area: this is
> accepted
>
> procedure Q is
>    X : P.T'Class := P.S'(P.Value);
> begin
>    X := P.T'(P.Value);
>
> but this fails
>
> procedure Q is
>    X : P.T'Class := P.T'(P.Value);
> begin
>    X := P.S'(P.Value);
>
> saying 'tag-indeterminate expression must have type "T"(RM 5.2 (6))'

No, that's not a GNAT problem.  The RM paragraph, which GNAT was good
enough to tell you about, specifically says that a tag-indeterminate
expression must have type T in this case.  I kind of think that if a
GNAT error message refers to a specific RM passage, it's probably a
good idea to read that passage before assuming there's a GNAT
problem.....

                               -- Adam




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

* Re: Dispatch on the result still does not work?
  2009-07-13 15:13 ` Adam Beneschan
  2009-07-13 15:17   ` Adam Beneschan
@ 2009-07-13 18:46   ` Adam Beneschan
  1 sibling, 0 replies; 30+ messages in thread
From: Adam Beneschan @ 2009-07-13 18:46 UTC (permalink / raw)


On Jul 13, 8:13 am, Adam Beneschan <a...@irvine.com> wrote:
> I think this also works:
>
>      X : T'Class := S'(Value);
>   begin
>      declare
>         function T_Value return T renames Pak1.Value;
>      begin
>         X := T_Value;
>      end;
>
> Again, the rename helps the compiler determine unambiguously which
> Value subprogram is intended, but it doesn't change the fact that the
> call to it is tag-indeterminate.  I'd need to pore over the rules more
> closely to make sure of this, however.

OK, I think I got this part wrong.  The AARM says that whether a call
on a subprogram rename is a dispatching operation depends on where the
renaming operation is declared, not on what it renames; here, the
rename is not a primitive subprogram (even though the thing it renames
*is* primitive), so the call on T_Value is not a dispatching operation
and thus can't be tag-indeterminate, and therefore the assignment
statement is illegal.  GNAT might be getting this wrong.

                                  -- Adam


>
> Anyway, the important thing to remember is that the compiler first has
> to determine which declaration is meant by every identifier in a
> statement, and only *then* can it think about whether a call is
> dispatching or not.
>
> Hope this helps,
>
>                                        -- Adam- Hide quoted text -
>
> - Show quoted text -




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

* Re: Dispatch on the result still does not work?
  2009-07-13 16:55                 ` Adam Beneschan
@ 2009-07-13 21:47                   ` sjw
  2009-07-13 22:50                     ` Adam Beneschan
  0 siblings, 1 reply; 30+ messages in thread
From: sjw @ 2009-07-13 21:47 UTC (permalink / raw)


On Jul 13, 5:55 pm, Adam Beneschan <a...@irvine.com> wrote:
> On Jul 12, 1:30 pm, sjw <simon.j.wri...@mac.com> wrote:

> > saying 'tag-indeterminate expression must have type "T"(RM 5.2 (6))'
>
> No, that's not a GNAT problem.  The RM paragraph, which GNAT was good
> enough to tell you about, specifically says that a tag-indeterminate
> expression must have type T in this case.  I kind of think that if a
> GNAT error message refers to a specific RM passage, it's probably a
> good idea to read that passage before assuming there's a GNAT
> problem.....

OK, mea culpa. However .. if I say P.S'(whatever) and the compiler
tells me it's tag-indeterminate my first reaction is that it must be
confused!

If I hadn't been too taken with the symmetry I'd have realised that I
should have written

procedure Q is
   X : P.T'Class := P.T'(P.Value);
begin
   X := P.T'Class (P.S'(P.Value));

(which (I think) is the 'dynamically tagged' alternative in 5.2(6)
which wasn't mentioned by GNAT).



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

* Re: Dispatch on the result still does not work?
  2009-07-13 21:47                   ` sjw
@ 2009-07-13 22:50                     ` Adam Beneschan
  2009-07-14 21:06                       ` sjw
  0 siblings, 1 reply; 30+ messages in thread
From: Adam Beneschan @ 2009-07-13 22:50 UTC (permalink / raw)


On Jul 13, 2:47 pm, sjw <simon.j.wri...@mac.com> wrote:
> On Jul 13, 5:55 pm, Adam Beneschan <a...@irvine.com> wrote:
>
> > On Jul 12, 1:30 pm, sjw <simon.j.wri...@mac.com> wrote:
> > > saying 'tag-indeterminate expression must have type "T"(RM 5.2 (6))'
>
> > No, that's not a GNAT problem.  The RM paragraph, which GNAT was good
> > enough to tell you about, specifically says that a tag-indeterminate
> > expression must have type T in this case.  I kind of think that if a
> > GNAT error message refers to a specific RM passage, it's probably a
> > good idea to read that passage before assuming there's a GNAT
> > problem.....
>
> OK, mea culpa. However .. if I say P.S'(whatever) and the compiler
> tells me it's tag-indeterminate my first reaction is that it must be
> confused!

Yeah, I can understand why this could be confusing.  The qualifier
P.S' doesn't say that the expression in parentheses will (dynamically)
have type P.S; it says that the operand must resolve to be of the type
P.S, which, I believe, implies that the expression's type will
actually be P.S **except** when dispatching is involved.

> If I hadn't been too taken with the symmetry I'd have realised that I
> should have written
>
> procedure Q is
>    X : P.T'Class := P.T'(P.Value);
> begin
>    X := P.T'Class (P.S'(P.Value));
>
> (which (I think) is the 'dynamically tagged' alternative in 5.2(6)
> which wasn't mentioned by GNAT).

I think this will work, but it will not dispatch.  It will always call
the Value that returns S.  (Putting the dispatching operation inside a
type conversion will kill any dispatching---see 3.9.2(17-19).)  And,
in this case, it will result in a Constraint_Error at runtime since X
is now constrained to values of type T.

                                     -- Adam





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

* Re: Dispatch on the result still does not work?
  2009-07-13 22:50                     ` Adam Beneschan
@ 2009-07-14 21:06                       ` sjw
  0 siblings, 0 replies; 30+ messages in thread
From: sjw @ 2009-07-14 21:06 UTC (permalink / raw)


On Jul 13, 11:50 pm, Adam Beneschan <a...@irvine.com> wrote:
> On Jul 13, 2:47 pm, sjw <simon.j.wri...@mac.com> wrote:

> > OK, mea culpa. However .. if I say P.S'(whatever) and the compiler
> > tells me it's tag-indeterminate my first reaction is that it must be
> > confused!
>
> Yeah, I can understand why this could be confusing.  The qualifier
> P.S' doesn't say that the expression in parentheses will (dynamically)
> have type P.S; it says that the operand must resolve to be of the type
> P.S, which, I believe, implies that the expression's type will
> actually be P.S **except** when dispatching is involved.
>
> > If I hadn't been too taken with the symmetry I'd have realised that I
> > should have written
>
> > procedure Q is
> >    X : P.T'Class := P.T'(P.Value);
> > begin
> >    X := P.T'Class (P.S'(P.Value));
>
> > (which (I think) is the 'dynamically tagged' alternative in 5.2(6)
> > which wasn't mentioned by GNAT).
>
> I think this will work, but it will not dispatch.  It will always call
> the Value that returns S.  (Putting the dispatching operation inside a
> type conversion will kill any dispatching---see 3.9.2(17-19).)  And,
> in this case, it will result in a Constraint_Error at runtime since X
> is now constrained to values of type T.

Exception name: CONSTRAINT_ERROR
Message: dmitry.ada:26 tag check failed

I was entertained by this:

   X : P.T'Class := P.S'(P.Value);
begin
   X := P.T'(P.Value);

where P.T'(P.Value) dispatched to the S version (in other words the
actual (dynamic?) type of the target was controlling).



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

end of thread, other threads:[~2009-07-14 21:06 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-07-11 10:04 Dispatch on the result still does not work? Dmitry A. Kazakov
2009-07-11 11:09 ` Chris Moore
2009-07-11 12:05   ` Dmitry A. Kazakov
2009-07-11 17:50     ` Chris Moore
2009-07-11 19:22       ` Dmitry A. Kazakov
2009-07-11 11:32 ` Hibou57 (Yannick Duchêne)
2009-07-11 12:20   ` Dmitry A. Kazakov
2009-07-11 13:36     ` Hibou57 (Yannick Duchêne)
2009-07-11 13:39       ` Hibou57 (Yannick Duchêne)
2009-07-11 15:19       ` Dmitry A. Kazakov
2009-07-11 18:08         ` Hibou57 (Yannick Duchêne)
2009-07-11 19:29           ` Dmitry A. Kazakov
2009-07-11 23:22             ` Hibou57 (Yannick Duchêne)
2009-07-12  9:46               ` Dmitry A. Kazakov
2009-07-11 18:54 ` Georg Bauhaus
2009-07-11 19:40   ` Dmitry A. Kazakov
2009-07-12 10:40     ` Chris Moore
2009-07-12 11:30       ` Dmitry A. Kazakov
2009-07-12 16:05         ` Chris Moore
2009-07-12 16:38           ` Dmitry A. Kazakov
2009-07-12 17:11             ` AdaMagica
2009-07-12 20:30               ` sjw
2009-07-13 16:55                 ` Adam Beneschan
2009-07-13 21:47                   ` sjw
2009-07-13 22:50                     ` Adam Beneschan
2009-07-14 21:06                       ` sjw
2009-07-13 15:13 ` Adam Beneschan
2009-07-13 15:17   ` Adam Beneschan
2009-07-13 16:33     ` AdaMagica
2009-07-13 18:46   ` Adam Beneschan

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