comp.lang.ada
 help / color / mirror / Atom feed
* Quick question regarding limited type return syntax
@ 2014-07-30 23:51 NiGHTS
  2014-07-31  0:02 ` Adam Beneschan
  2014-07-31  0:48 ` Shark8
  0 siblings, 2 replies; 40+ messages in thread
From: NiGHTS @ 2014-07-30 23:51 UTC (permalink / raw)


I am designing a package which features a "Create" function that returns a newly instantiated "Object" which is a discriminated limited type. The code compiles and operates correctly but gives me a warning that "New_Object" is not used. See below (ellipses represent omitted code):

-----

package Test is
   type Object (Parameters : access String) is tagged limited private;
   function Create (...) return Object;
   ...
private
   type Object (Parameters : access String) is tagged limited
   record
      Database : PQ.Database (Parameters);
      ...
   end record;
   ...
end Test;

package body Test is
   function Create(...) return Object is
      ...
   begin
      return New_Object : Object (Connection_String'Access) do 
         null;
      end return;
   end;
   ...
end Test;

-----

To remove this warning I've tried this:

   return  Object (Connection_String'Access) do null; end return;

and it gives an error about expecting a ';'. I've also tried this:

   return  Object (Connection_String'Access);

Compiler tells me "argument of conversion cannot be access". 


I have tried other syntax variants but all produce errors. My goal here is to avoid using "new" which is why I am trying to return the instance in this way.

How can I rewrite this code so that I won't get any errors or warnings?


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

* Re: Quick question regarding limited type return syntax
  2014-07-30 23:51 Quick question regarding limited type return syntax NiGHTS
@ 2014-07-31  0:02 ` Adam Beneschan
  2014-07-31  0:56   ` NiGHTS
  2014-07-31  0:48 ` Shark8
  1 sibling, 1 reply; 40+ messages in thread
From: Adam Beneschan @ 2014-07-31  0:02 UTC (permalink / raw)


On Wednesday, July 30, 2014 4:51:10 PM UTC-7, NiGHTS wrote:
> I am designing a package which features a "Create" function that returns a newly instantiated "Object" which is a discriminated limited type. The code compiles and operates correctly but gives me a warning that "New_Object" is not used. See below (ellipses represent omitted code):

> package Test is
>    type Object (Parameters : access String) is tagged limited private;
>    function Create (...) return Object;
>    ...
> private
>    type Object (Parameters : access String) is tagged limited
>    record
>       Database : PQ.Database (Parameters);
>       ...
>    end record;
>    ...
> end Test;
> 
> package body Test is
>    function Create(...) return Object is
>       ...
>    begin
>       return New_Object : Object (Connection_String'Access) do 
>          null;
>       end return;
>    end;
>    ...
> end Test;

> To remove this warning I've tried this:
> 
>    return  Object (Connection_String'Access) do null; end return;
> 
> and it gives an error about expecting a ';'. I've also tried this:
> 
> 
> 
>    return  Object (Connection_String'Access);
> 
> Compiler tells me "argument of conversion cannot be access". 
> 
> I have tried other syntax variants but all produce errors. My goal here is to avoid using "new" which is why I am trying to return the instance in this way.
> 
> How can I rewrite this code so that I won't get any errors or warnings?

What is a PQ.Database?  

I've tried this with various dummy types for the Database, and when I get a warning it's that the object is "read but never assigned".  Is that the warning you're getting?  That's different from a warning that says it's never used.

It appears to me that if this field were assigned in New_Object, or if Database had an initial value in the record or if all components of Database had initial values, you wouldn't get the warning.

                              -- Adam


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

* Re: Quick question regarding limited type return syntax
  2014-07-30 23:51 Quick question regarding limited type return syntax NiGHTS
  2014-07-31  0:02 ` Adam Beneschan
@ 2014-07-31  0:48 ` Shark8
  2014-07-31  1:00   ` NiGHTS
  1 sibling, 1 reply; 40+ messages in thread
From: Shark8 @ 2014-07-31  0:48 UTC (permalink / raw)


On 30-Jul-14 17:51, NiGHTS wrote:
>   return  Object (Connection_String'Access) do null; end return;

That should be
    return Object'(Connection_String'Access);
the extended-return is the form
   return object:type [:= value] do
     sequence_of_statements
   end return;

as you can see there's no 'do' there -- which is what the compiler was 
complaining about: there was no ';' between the value and "do".

> return  Object (Connection_String'Access);

The reason this is failing is because it's reading the parens as 
conversion, not qualification -- for qualification you need a "'"; 
personally I'm a fan of using named parameters when using qualification 
and generating objects.

    return Object'(Parameters => Connection_String'Access, others => <>);


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

* Re: Quick question regarding limited type return syntax
  2014-07-31  0:02 ` Adam Beneschan
@ 2014-07-31  0:56   ` NiGHTS
  0 siblings, 0 replies; 40+ messages in thread
From: NiGHTS @ 2014-07-31  0:56 UTC (permalink / raw)


On Wednesday, July 30, 2014 8:02:59 PM UTC-4, Adam Beneschan wrote:
> 
> What is a PQ.Database?  
> 

The complete name is GNATCOLL.SQL.Postgres.Gnade.Database. Its from the GNATColl library.

https://github.com/ThomasLocke/GNATColl/blob/master/src/postgres/with_postgres/gnatcoll-sql-postgres-gnade.ads

> 
> 
> I've tried this with various dummy types for the Database, and when I get a warning it's that the object is "read but never assigned".  Is that the warning you're getting?  That's different from a warning that says it's never used.
> 

I'm sorry about that. You are right. That is the warning I am getting.

> 
> It appears to me that if this field were assigned in New_Object, or if Database had an initial value in the record or if all components of Database had initial values, you wouldn't get the warning.
> 
> 

The initial value is given during the return. It won't let me give it an initial value at the record definition (unless I am doing it wrong).


Can you give me an example?

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

* Re: Quick question regarding limited type return syntax
  2014-07-31  0:48 ` Shark8
@ 2014-07-31  1:00   ` NiGHTS
  2014-07-31  1:29     ` Adam Beneschan
  0 siblings, 1 reply; 40+ messages in thread
From: NiGHTS @ 2014-07-31  1:00 UTC (permalink / raw)


On Wednesday, July 30, 2014 8:48:34 PM UTC-4, Shark8 wrote:
> On 30-Jul-14 17:51, NiGHTS wrote:
> 
> >   return  Object (Connection_String'Access) do null; end return;
> 
> 
> 
> That should be
> 
>     return Object'(Connection_String'Access);
> 
> the extended-return is the form
> 
>    return object:type [:= value] do
> 
>      sequence_of_statements
> 
>    end return;
> 
> 
> 
> as you can see there's no 'do' there -- which is what the compiler was 
> 
> complaining about: there was no ';' between the value and "do".
> 
> 
> 
> > return  Object (Connection_String'Access);
> 
> 
> 
> The reason this is failing is because it's reading the parens as 
> 
> conversion, not qualification -- for qualification you need a "'"; 
> 
> personally I'm a fan of using named parameters when using qualification 
> 
> and generating objects.
> 
> 
> 
>     return Object'(Parameters => Connection_String'Access, others => <>);

This was another syntax I had tried. Here is the error I am getting with your syntax:

Expected type "Object" defined at (...)
Found type access to subtype of "Standard.String" at line (...)


Just to be clear this is my modification:

package body Test is
   function Create(...) return Object is
      ...
   begin
      return Object'(Connection_String'Access);
   end;
   ...
end Test; 


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

* Re: Quick question regarding limited type return syntax
  2014-07-31  1:00   ` NiGHTS
@ 2014-07-31  1:29     ` Adam Beneschan
  2014-07-31  1:38       ` NiGHTS
  2014-08-01  2:12       ` Randy Brukardt
  0 siblings, 2 replies; 40+ messages in thread
From: Adam Beneschan @ 2014-07-31  1:29 UTC (permalink / raw)


On Wednesday, July 30, 2014 6:00:43 PM UTC-7, NiGHTS wrote:
> On Wednesday, July 30, 2014 8:48:34 PM UTC-4, Shark8 wrote:
> 
> > On 30-Jul-14 17:51, NiGHTS wrote:
> 
> > >   return  Object (Connection_String'Access) do null; end return;

> package body Test is
>    function Create(...) return Object is
>       ...
>    begin
>       return Object'(Connection_String'Access);
>    end;
>    ...
> end Test;

What you need to do is return an aggregate.  And to return an aggregate, you need to specify both fields--the Parameters discriminant and the Database.  This syntax:

    Object'(Connection_String'Access)

is just wrong.  It tells the compiler that the value is Connection_String'Access, and asks the compiler to treat it as an Object.  It can't do that, because Object isn't an access type.  (This sort of syntax can be useful in overloading cases, when the compiler can't determine the correct access type without help.)

If you said

    Object'(Parameters => Connection_String'Access)

you'd get an error that Database is missing.  So you need

    Object'(Parameters => Connection_String'Access, Database => <>)

or just

    (Parameters => Connection_String'Access, Database => <>)

or    

    (Parameters => Connection_String'Access, others => <>)

(It's OK for a function that returns a limited type to return an aggregate like this.)

The effect is that subcomponents of Database that have default initial values will be initialized, and subcomponents that don't have default initial values will be initialized to garbage (except where the language says otherwise).  That's really the same as your original example was trying to do.  I guess that explicitly putting "others => <>" in an aggregate is enough to convince GNAT not to think you were accidentally leaving something initialized to garbage.  

                              -- Adam




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

* Re: Quick question regarding limited type return syntax
  2014-07-31  1:29     ` Adam Beneschan
@ 2014-07-31  1:38       ` NiGHTS
  2014-07-31  4:01         ` Shark8
  2014-08-01  2:12       ` Randy Brukardt
  1 sibling, 1 reply; 40+ messages in thread
From: NiGHTS @ 2014-07-31  1:38 UTC (permalink / raw)


On Wednesday, July 30, 2014 9:29:10 PM UTC-4, Adam Beneschan wrote:
> On Wednesday, July 30, 2014 6:00:43 PM UTC-7, NiGHTS wrote:
> 
> > On Wednesday, July 30, 2014 8:48:34 PM UTC-4, Shark8 wrote:
> 
> > 
> 
> > > On 30-Jul-14 17:51, NiGHTS wrote:
> 
> > 
> 
> > > >   return  Object (Connection_String'Access) do null; end return;
> 
> 
> 
> > package body Test is
> 
> >    function Create(...) return Object is
> 
> >       ...
> 
> >    begin
> 
> >       return Object'(Connection_String'Access);
> 
> >    end;
> 
> >    ...
> 
> > end Test;
> 
> 
> 
> What you need to do is return an aggregate.  And to return an aggregate, you need to specify both fields--the Parameters discriminant and the Database.  This syntax:
> 
> 
> 
>     Object'(Connection_String'Access)
> 
> 
> 
> is just wrong.  It tells the compiler that the value is Connection_String'Access, and asks the compiler to treat it as an Object.  It can't do that, because Object isn't an access type.  (This sort of syntax can be useful in overloading cases, when the compiler can't determine the correct access type without help.)
> 
> 
> 
> If you said
> 
> 
> 
>     Object'(Parameters => Connection_String'Access)
> 
> 
> 
> you'd get an error that Database is missing.  So you need
> 
> 
> 
>     Object'(Parameters => Connection_String'Access, Database => <>)
> 
> 
> 
> or just
> 
> 
> 
>     (Parameters => Connection_String'Access, Database => <>)
> 
> 
> 
> or    
> 
> 
> 
>     (Parameters => Connection_String'Access, others => <>)
> 
> 
> 
> (It's OK for a function that returns a limited type to return an aggregate like this.)
> 
> 
> 
> The effect is that subcomponents of Database that have default initial values will be initialized, and subcomponents that don't have default initial values will be initialized to garbage (except where the language says otherwise).  That's really the same as your original example was trying to do.  I guess that explicitly putting "others => <>" in an aggregate is enough to convince GNAT not to think you were accidentally leaving something initialized to garbage.  
> 
> 
> 
>                               -- Adam

You're a good man Adam. Thank you for your very clear explanation. This worked for me and I'm very pleased by how logical this ended up being.

And thank you as well Shark8 for your help.

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

* Re: Quick question regarding limited type return syntax
  2014-07-31  1:38       ` NiGHTS
@ 2014-07-31  4:01         ` Shark8
  0 siblings, 0 replies; 40+ messages in thread
From: Shark8 @ 2014-07-31  4:01 UTC (permalink / raw)


On 30-Jul-14 19:38, NiGHTS wrote:
> And thank you as well Shark8 for your help.
>

Quite welcome.

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

* Re: Quick question regarding limited type return syntax
  2014-07-31  1:29     ` Adam Beneschan
  2014-07-31  1:38       ` NiGHTS
@ 2014-08-01  2:12       ` Randy Brukardt
  2014-08-01  3:40         ` Shark8
  2014-08-01  7:57         ` J-P. Rosen
  1 sibling, 2 replies; 40+ messages in thread
From: Randy Brukardt @ 2014-08-01  2:12 UTC (permalink / raw)


"Adam Beneschan" <adambeneschan@gmail.com> wrote in message 
news:bf9193d6-e1a8-4df3-8e36-b07a2b07655e@googlegroups.com...
...
>The effect is that subcomponents of Database that have default initial 
>values
>will be initialized, and subcomponents that don't have default initial 
>values
>will be initialized to garbage (except where the language says otherwise).
>That's really the same as your original example was trying to do.  I guess
>that explicitly putting "others => <>" in an aggregate is enough to
>convince GNAT not to think you were accidentally leaving something
>initialized to garbage.

I'd hope so: the syntax you gave says that you explicitly wanted something 
initialized to garbage. :-) [OK, explicitly default-initialized, whatever 
that does.] It's not a compiler's job to second-guess explicit instructions, 
programmers would get really annoyed if it did (and have a hard time getting 
anything done).

It's annoying that we couldn't get this "explicit default-initialization" 
syntax more widely used. I prefer to ensure that everything is properly 
initialized, but sometimes the default value is good enough. It would be 
nice to be able to specify that:

      Obj : My_Type := <>;
or maybe
      Obj : My_Type := (<>);

so that I could verify that every object is either initialized or explicitly 
left default initialized. Right now, I use a comment:

     Obj : My_Type; -- Default initialize is OK here, because ...

but it's hard for a tool to tell that everything is as it should be.

(We tried to allow "(<>)" for private types for Ada 2005, but ran into a 
number of problems that eventually led us to give up. Too bad, I don't think 
they were insurmountable, but we were running short on time.)

                                            Randy.



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

* Re: Quick question regarding limited type return syntax
  2014-08-01  2:12       ` Randy Brukardt
@ 2014-08-01  3:40         ` Shark8
  2014-08-01  7:57         ` J-P. Rosen
  1 sibling, 0 replies; 40+ messages in thread
From: Shark8 @ 2014-08-01  3:40 UTC (permalink / raw)


On 31-Jul-14 20:12, Randy Brukardt wrote:
> (We tried to allow "(<>)" for private types for Ada 2005, but ran into a
> number of problems that eventually led us to give up. Too bad, I don't think
> they were insurmountable, but we were running short on time.)

That's unfortunate.


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

* Re: Quick question regarding limited type return syntax
  2014-08-01  2:12       ` Randy Brukardt
  2014-08-01  3:40         ` Shark8
@ 2014-08-01  7:57         ` J-P. Rosen
  2014-08-01 19:23           ` Randy Brukardt
  1 sibling, 1 reply; 40+ messages in thread
From: J-P. Rosen @ 2014-08-01  7:57 UTC (permalink / raw)


Le 01/08/2014 04:12, Randy Brukardt a écrit :
> t's annoying that we couldn't get this "explicit default-initialization" 
> syntax more widely used. I prefer to ensure that everything is properly 
> initialized, but sometimes the default value is good enough. It would be 
> nice to be able to specify that:
> 
>       Obj : My_Type := <>;
> or maybe
>       Obj : My_Type := (<>);
> 
> so that I could verify that every object is either initialized or explicitly 
> left default initialized.

One of my clients has a rule that every user-defined type must provide
an associated constant for the default value (and of course, AdaControl
can enforce that rule). Then it is enough to say that every variable
must be initialized.

Seems close enough to what you want...

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr

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

* Re: Quick question regarding limited type return syntax
  2014-08-01  7:57         ` J-P. Rosen
@ 2014-08-01 19:23           ` Randy Brukardt
  2014-08-01 19:37             ` J-P. Rosen
  2014-08-01 20:53             ` Shark8
  0 siblings, 2 replies; 40+ messages in thread
From: Randy Brukardt @ 2014-08-01 19:23 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1176 bytes --]

"J-P. Rosen" <rosen@adalog.fr> wrote in message 
news:lrfh8k$rpi$1@dont-email.me...
> Le 01/08/2014 04:12, Randy Brukardt a écrit :
>> t's annoying that we couldn't get this "explicit default-initialization"
>> syntax more widely used. I prefer to ensure that everything is properly
>> initialized, but sometimes the default value is good enough. It would be
>> nice to be able to specify that:
>>
>>       Obj : My_Type := <>;
>> or maybe
>>       Obj : My_Type := (<>);
>>
>> so that I could verify that every object is either initialized or 
>> explicitly
>> left default initialized.
>
> One of my clients has a rule that every user-defined type must provide
> an associated constant for the default value (and of course, AdaControl
> can enforce that rule). Then it is enough to say that every variable
> must be initialized.
>
> Seems close enough to what you want...

Not quite, since

    Default_Frobnitz : constant Frobnitz_Type;

is illegal. You could write:


    Junk_Frobnitz : Frobnitz_Type; -- To get this default-initialized.
    Default_Frobnitz : constant Frobnitz_Type := Junk_Frobnitz;

but that's awful.

                                         Randy.


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

* Re: Quick question regarding limited type return syntax
  2014-08-01 19:23           ` Randy Brukardt
@ 2014-08-01 19:37             ` J-P. Rosen
  2014-08-01 20:53             ` Shark8
  1 sibling, 0 replies; 40+ messages in thread
From: J-P. Rosen @ 2014-08-01 19:37 UTC (permalink / raw)


Le 01/08/2014 21:23, Randy Brukardt a écrit :
>> One of my clients has a rule that every user-defined type must provide
>> > an associated constant for the default value (and of course, AdaControl
>> > can enforce that rule). Then it is enough to say that every variable
>> > must be initialized.
>> >
>> > Seems close enough to what you want...
> Not quite, since
> 
>     Default_Frobnitz : constant Frobnitz_Type;
> 
> is illegal.
No, of course the constant has an explicitely stated value.

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr


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

* Re: Quick question regarding limited type return syntax
  2014-08-01 19:23           ` Randy Brukardt
  2014-08-01 19:37             ` J-P. Rosen
@ 2014-08-01 20:53             ` Shark8
  2014-08-02  7:11               ` Niklas Holsti
  2014-08-02  8:02               ` Jacob Sparre Andersen
  1 sibling, 2 replies; 40+ messages in thread
From: Shark8 @ 2014-08-01 20:53 UTC (permalink / raw)


...Too bad there's not a Default_Value sort of aspect/attribute.

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

* Re: Quick question regarding limited type return syntax
  2014-08-01 20:53             ` Shark8
@ 2014-08-02  7:11               ` Niklas Holsti
  2014-08-02  7:34                 ` Dmitry A. Kazakov
  2014-08-02  8:02               ` Jacob Sparre Andersen
  1 sibling, 1 reply; 40+ messages in thread
From: Niklas Holsti @ 2014-08-02  7:11 UTC (permalink / raw)


On 14-08-01 10:57 , J-P. Rosen wrote:
> Le 01/08/2014 04:12, Randy Brukardt a écrit :
>> It's annoying that we couldn't get this "explicit default-
>> initialization" syntax more widely used. I prefer to ensure that
>> everything is properly initialized, but sometimes the default
>> value is good enough. It would be nice to be able to specify that:
>>
>>       Obj : My_Type := <>;
>> or maybe
>>       Obj : My_Type := (<>);
>>
>> so that I could verify that every object is either initialized
>> or explicitly left default initialized.
>
> One of my clients has a rule that every user-defined type must
> provide an associated constant for the default value (and of
> course, AdaControl can enforce that rule). Then it is enough
> to say that every variable must be initialized.
>
> Seems close enough to what you want...

On 14-08-01 23:53 , Shark8 wrote:
> ...Too bad there's not a Default_Value sort of aspect/attribute.

Do you mean that Default_Value would be an aspect of a type, and would
define the default initialization value of objects of that type?

More elegantly IMO, the language could allow a default initialization
expression to be assigned in the type or subtype declaration:

   type My_Type is <type definition> := <expression>;

The elaboration of the type declaration would evalate the expression
into a value, and then any declaration of an object of this type would
use that value as the initialization expression, unless the object
declaration itself provides an initialization expression.

J-P's client's rule could then be reformulated as a rule that every type
(and subtype) declaration must have a default-initialization expression.

This suggestion seems so trivial that it has probably been made before,
and rejected for some reason. Perhaps using ":=" to "assign a value to a
type" is too strange.

Randy's suggestion for an explicit indication that an object is
default-initialized is an orthogonal isssue.

IMO the risk of using uninitialized variables, and the resulting
non-deterministic bugs, is one of the major remaining holes in the
safety of Ada. On the other hand, explicit initialization of all
variables (buffer arrays in particular) is often far too costly in
real-time applications. The above suggestions of explicit default
initialization expressions would not reduce the cost, of course. At
present, the only remedy that does not impose run-time costs is to use
provers to show that the uninitialized variables (for example,
uninitialized array elements) are never read.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .


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

* Re: Quick question regarding limited type return syntax
  2014-08-02  7:11               ` Niklas Holsti
@ 2014-08-02  7:34                 ` Dmitry A. Kazakov
  2014-08-02 13:20                   ` Robert A Duff
  0 siblings, 1 reply; 40+ messages in thread
From: Dmitry A. Kazakov @ 2014-08-02  7:34 UTC (permalink / raw)


On Sat, 02 Aug 2014 10:11:59 +0300, Niklas Holsti wrote:

> More elegantly IMO, the language could allow a default initialization
> expression to be assigned in the type or subtype declaration:
> 
>    type My_Type is <type definition> := <expression>;

This suggests assigning something to the type.

(The only way to have default initialization is by having a default
constructor. Which is just same.)

BTW,

   type Integer is range ... := 0;
   subtype Positive is Integer range 1..Integer'Last;

   X : Positive; -- Oops!

[...]
> Randy's suggestion for an explicit indication that an object is
> default-initialized is an orthogonal isssue.

Yes, and it would have sense if implicitly uninitialized objects were
illegal. Unfortunately they are not.

> IMO the risk of using uninitialized variables, and the resulting
> non-deterministic bugs, is one of the major remaining holes in the
> safety of Ada.

All initialization/finalization issues are. E.g. parent's Initialize not
called. Finalization deadlock with task components. Dispatching calls
through class-wide access discriminants upon initialization/finalization.
The holes are as big as the hull...

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


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

* Re: Quick question regarding limited type return syntax
  2014-08-01 20:53             ` Shark8
  2014-08-02  7:11               ` Niklas Holsti
@ 2014-08-02  8:02               ` Jacob Sparre Andersen
  2014-08-02 19:20                 ` Shark8
  1 sibling, 1 reply; 40+ messages in thread
From: Jacob Sparre Andersen @ 2014-08-02  8:02 UTC (permalink / raw)


Shark8 <OneWingedShark@gmail.com> writes:

> ...Too bad there's not a Default_Value sort of aspect/attribute.

LRM 3.5(56.3/3)

Enjoy,

Jacob
-- 
"I'm going as a barrel of toxic waste!"

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

* Re: Quick question regarding limited type return syntax
  2014-08-02  7:34                 ` Dmitry A. Kazakov
@ 2014-08-02 13:20                   ` Robert A Duff
  2014-08-02 13:44                     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 40+ messages in thread
From: Robert A Duff @ 2014-08-02 13:20 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

>...Dispatching calls
> through class-wide access discriminants upon initialization/finalization.

Can you please give an example of what you mean?

- Bob

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

* Re: Quick question regarding limited type return syntax
  2014-08-02 13:20                   ` Robert A Duff
@ 2014-08-02 13:44                     ` Dmitry A. Kazakov
  2014-08-02 14:34                       ` Robert A Duff
  0 siblings, 1 reply; 40+ messages in thread
From: Dmitry A. Kazakov @ 2014-08-02 13:44 UTC (permalink / raw)


On Sat, 02 Aug 2014 09:20:45 -0400, Robert A Duff wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>>...Dispatching calls
>> through class-wide access discriminants upon initialization/finalization.
> 
> Can you please give an example of what you mean?

Components not discriminants. I had Rosen's trick in mind:

   type T is ...
       Self : not null access T := T'Unchecked_Access;

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


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

* Re: Quick question regarding limited type return syntax
  2014-08-02 13:44                     ` Dmitry A. Kazakov
@ 2014-08-02 14:34                       ` Robert A Duff
  2014-08-02 16:56                         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 40+ messages in thread
From: Robert A Duff @ 2014-08-02 14:34 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> On Sat, 02 Aug 2014 09:20:45 -0400, Robert A Duff wrote:
>
>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>> 
>>>...Dispatching calls
>>> through class-wide access discriminants upon initialization/finalization.
>> 
>> Can you please give an example of what you mean?
>
> Components not discriminants. I had Rosen's trick in mind:
>
>    type T is ...
>        Self : not null access T := T'Unchecked_Access;

Sorry, I still don't get it.  I don't see any class-wide types or
dispatching calls there.  Also, it's illegal as written (the Rosen trick
is only allowed for limited types.)  Perhaps a complete compilable
example would help illustrate the language anomaly you are talking
about.

The Rosen trick allows you to obtain a variable view of a constant,
but that has nothing to do with initialization/finalization, so I assume
that's not what you meant.

- Bob


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

* Re: Quick question regarding limited type return syntax
  2014-08-02 14:34                       ` Robert A Duff
@ 2014-08-02 16:56                         ` Dmitry A. Kazakov
  2014-08-02 20:35                           ` Niklas Holsti
  2014-08-03 16:35                           ` Robert A Duff
  0 siblings, 2 replies; 40+ messages in thread
From: Dmitry A. Kazakov @ 2014-08-02 16:56 UTC (permalink / raw)


On Sat, 02 Aug 2014 10:34:53 -0400, Robert A Duff wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> On Sat, 02 Aug 2014 09:20:45 -0400, Robert A Duff wrote:
>>
>>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>>> 
>>>>...Dispatching calls
>>>> through class-wide access discriminants upon initialization/finalization.
>>> 
>>> Can you please give an example of what you mean?
>>
>> Components not discriminants. I had Rosen's trick in mind:
>>
>>    type T is ...
>>        Self : not null access T := T'Unchecked_Access;
> 
> Sorry, I still don't get it.  I don't see any class-wide types or
> dispatching calls there.  Also, it's illegal as written (the Rosen trick
> is only allowed for limited types.)  Perhaps a complete compilable
> example would help illustrate the language anomaly you are talking
> about.

with Ada.Finalization;
with Ada.Text_IO;
procedure Test is
   package P is
      type T is new Ada.Finalization.Limited_Controlled with record
         Self : not null access T'Class := T'Unchecked_Access;
      end record;
      overriding procedure Initialize (X : in out T);
      procedure Foo (X : in out T) is null;
   end P;
   
   package body P is
      procedure Initialize (X : in out T) is
      begin
         X.Self.Foo;
      end Initialize;   
   end P;
   
   package Q is
      use P;
      type S is new T with record
         I : Integer;
      end record;
      overriding procedure Initialize (X : in out S);
      overriding procedure Foo (X : in out S);
   end Q;
   
   package body Q is
      procedure Initialize (X : in out S) is
      begin
         T (X).Initialize;
         X.I := 1;
      end Initialize;
      procedure Foo (X : in out S) is
      begin
         X.I := X.I + 1;
      end Foo;
   end Q;
   
   Y : Q.S;
begin
   Ada.Text_IO.Put_Line (Integer'Image (Y.I));
end Test;

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

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

* Re: Quick question regarding limited type return syntax
  2014-08-02  8:02               ` Jacob Sparre Andersen
@ 2014-08-02 19:20                 ` Shark8
  2014-08-03 16:07                   ` Default values (Was: Quick question regarding limited type return syntax) Jacob Sparre Andersen
  0 siblings, 1 reply; 40+ messages in thread
From: Shark8 @ 2014-08-02 19:20 UTC (permalink / raw)


On 02-Aug-14 02:02, Jacob Sparre Andersen wrote:
> Shark8 <OneWingedShark@gmail.com> writes:
>
>> ...Too bad there's not a Default_Value sort of aspect/attribute.
>
> LRM 3.5(56.3/3)
>
> Enjoy,
>
> Jacob

It's only for scalar types though.


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

* Re: Quick question regarding limited type return syntax
  2014-08-02 16:56                         ` Dmitry A. Kazakov
@ 2014-08-02 20:35                           ` Niklas Holsti
  2014-08-03  7:30                             ` Dmitry A. Kazakov
  2014-08-03 16:35                           ` Robert A Duff
  1 sibling, 1 reply; 40+ messages in thread
From: Niklas Holsti @ 2014-08-02 20:35 UTC (permalink / raw)


On 14-08-02 19:56 , Dmitry A. Kazakov wrote:
> On Sat, 02 Aug 2014 10:34:53 -0400, Robert A Duff wrote:
> 
>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>>
>>> On Sat, 02 Aug 2014 09:20:45 -0400, Robert A Duff wrote:
>>>
>>>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>>>>
>>>>> ...Dispatching calls
>>>>> through class-wide access discriminants upon initialization/finalization.
>>>>
>>>> Can you please give an example of what you mean?
>>>
>>> Components not discriminants. I had Rosen's trick in mind:
>>>
>>>    type T is ...
>>>        Self : not null access T := T'Unchecked_Access;
>>
>> Sorry, I still don't get it.  I don't see any class-wide types or
>> dispatching calls there.  Also, it's illegal as written (the Rosen trick
>> is only allowed for limited types.)  Perhaps a complete compilable
>> example would help illustrate the language anomaly you are talking
>> about.
> 
> with Ada.Finalization;
> with Ada.Text_IO;
> procedure Test is
>    package P is
>       type T is new Ada.Finalization.Limited_Controlled with record
>          Self : not null access T'Class := T'Unchecked_Access;
>       end record;
>       overriding procedure Initialize (X : in out T);
>       procedure Foo (X : in out T) is null;
>    end P;
>    
>    package body P is
>       procedure Initialize (X : in out T) is
>       begin
>          X.Self.Foo;
>       end Initialize;   
>    end P;
>    
>    package Q is
>       use P;
>       type S is new T with record
>          I : Integer;
>       end record;
>       overriding procedure Initialize (X : in out S);
>       overriding procedure Foo (X : in out S);
>    end Q;
>    
>    package body Q is
>       procedure Initialize (X : in out S) is
>       begin
>          T (X).Initialize;
>          X.I := 1;
>       end Initialize;
>       procedure Foo (X : in out S) is
>       begin
>          X.I := X.I + 1;
>       end Foo;
>    end Q;
>    
>    Y : Q.S;
> begin
>    Ada.Text_IO.Put_Line (Integer'Image (Y.I));
> end Test;

(Dmitry, I find it quite annoying that you just dump this code on us
without bothering to explain why you think it shows some problem in Ada.)

The code indeed accesses an uninitialized datum: when Y is initialized,
Initialize (S) calls Initialize (T), which makes a dispatching call to
Foo (S), which accesses the component S.I, which is not yet initialized.

The flow of control in the example is a bit sneaky, but the
self-referring component T.Self is in no way essential to the
sneakiness; the same could be achieved by simply making a redispatching
call to Foo in Initialize(T).

There are many other ways to create even sneakier flow of control with
even more obscure opportunities for accessing uninitialized data.

Perhaps you have some personal design and coding rules which would
prevent access to uninitialized data except for the kind of code shown
in the example? That is, perhaps the ability to write such code in Ada
breaks the safety of your design and coding rules? Perhaps the rule is
that the Initialize operation of a derived type should first call
Initialize on the parent type, and only then initialize the components
added in the derivation (the extension components)? That is not a bad
rule, but combining it with (re-)dispatching calls to operations
overridden in the derived type obviously invites errors of the kind
shown in the example.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .


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

* Re: Quick question regarding limited type return syntax
  2014-08-02 20:35                           ` Niklas Holsti
@ 2014-08-03  7:30                             ` Dmitry A. Kazakov
  2014-08-04  9:24                               ` Niklas Holsti
  0 siblings, 1 reply; 40+ messages in thread
From: Dmitry A. Kazakov @ 2014-08-03  7:30 UTC (permalink / raw)


On Sat, 02 Aug 2014 23:35:34 +0300, Niklas Holsti wrote:

> On 14-08-02 19:56 , Dmitry A. Kazakov wrote:
>> On Sat, 02 Aug 2014 10:34:53 -0400, Robert A Duff wrote:
>> 
>>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>>>
>>>> On Sat, 02 Aug 2014 09:20:45 -0400, Robert A Duff wrote:
>>>>
>>>>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>>>>>
>>>>>> ...Dispatching calls
>>>>>> through class-wide access discriminants upon initialization/finalization.
>>>>>
>>>>> Can you please give an example of what you mean?
>>>>
>>>> Components not discriminants. I had Rosen's trick in mind:
>>>>
>>>>    type T is ...
>>>>        Self : not null access T := T'Unchecked_Access;
>>>
>>> Sorry, I still don't get it.  I don't see any class-wide types or
>>> dispatching calls there.  Also, it's illegal as written (the Rosen trick
>>> is only allowed for limited types.)  Perhaps a complete compilable
>>> example would help illustrate the language anomaly you are talking
>>> about.
>> 
>> with Ada.Finalization;
>> with Ada.Text_IO;
>> procedure Test is
>>    package P is
>>       type T is new Ada.Finalization.Limited_Controlled with record
>>          Self : not null access T'Class := T'Unchecked_Access;
>>       end record;
>>       overriding procedure Initialize (X : in out T);
>>       procedure Foo (X : in out T) is null;
>>    end P;
>>    
>>    package body P is
>>       procedure Initialize (X : in out T) is
>>       begin
>>          X.Self.Foo;
>>       end Initialize;   
>>    end P;
>>    
>>    package Q is
>>       use P;
>>       type S is new T with record
>>          I : Integer;
>>       end record;
>>       overriding procedure Initialize (X : in out S);
>>       overriding procedure Foo (X : in out S);
>>    end Q;
>>    
>>    package body Q is
>>       procedure Initialize (X : in out S) is
>>       begin
>>          T (X).Initialize;
>>          X.I := 1;
>>       end Initialize;
>>       procedure Foo (X : in out S) is
>>       begin
>>          X.I := X.I + 1;
>>       end Foo;
>>    end Q;
>>    
>>    Y : Q.S;
>> begin
>>    Ada.Text_IO.Put_Line (Integer'Image (Y.I));
>> end Test;
> 
> (Dmitry, I find it quite annoying that you just dump this code on us
> without bothering to explain why you think it shows some problem in Ada.)

Sorry, but the problem was self-evident to me. Robert asked for a working
example so I scraped together one without much thinking.

> The code indeed accesses an uninitialized datum: when Y is initialized,
> Initialize (S) calls Initialize (T), which makes a dispatching call to
> Foo (S), which accesses the component S.I, which is not yet initialized.

The code prematurely dispatches on an not yet initialized object. Again, it
was evident that this would happen when having a class-wide accessible in
Initialize when the parent's Initialize is to be called at the beginning of
the derived type Initialize.

> The flow of control in the example is a bit sneaky, but the
> self-referring component T.Self is in no way essential to the
> sneakiness; the same could be achieved by simply making a redispatching
> call to Foo in Initialize(T).

Yes, but as you probably remember, re-dispatching is already damned as
inconsistent regardless initialization.

> There are many other ways to create even sneakier flow of control with
> even more obscure opportunities for accessing uninitialized data.

There is no safe way to do initialization in Ada because it is not properly
typed. You should not be able to dispatch until the class-wide instance is
fully initialized, but you can because types are broken.

> Perhaps you have some personal design and coding rules which would
> prevent access to uninitialized data except for the kind of code shown
> in the example? That is, perhaps the ability to write such code in Ada
> breaks the safety of your design and coding rules? Perhaps the rule is
> that the Initialize operation of a derived type should first call
> Initialize on the parent type, and only then initialize the components
> added in the derivation (the extension components)? That is not a bad
> rule, but combining it with (re-)dispatching calls to operations
> overridden in the derived type obviously invites errors of the kind
> shown in the example.

The problem is with the semantics of Initialize, with its types.

1. IF Initialize does the specific type THEN it cannot dispatch AND it must
be through before any derived type's Initialize.

2. IF Initialize does class-wide type THEN it can dispatch AND must be
called after derived type's initialization.

It is sometimes one, sometimes another, sometimes both. It is a mess. Note
that there is a similar problem with constraints (with type invariants,
more generally):

   type Not_Working is
       Ref : not null access Something;
   end record;

This does not work for the same reason. There is no constructor which would
see Not_Working.Ref not yet initialized (without the constraint, when type
invariant not in place). Compare this with a class-wide access component to
itself. There is no constructor of the type itself which would see it not
initialized.

In both cases there can be a second level initialization where the
offending component is fully operational. But it cannot be both. Both means
types broken.

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


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

* Default values (Was: Quick question regarding limited type return syntax)
  2014-08-02 19:20                 ` Shark8
@ 2014-08-03 16:07                   ` Jacob Sparre Andersen
  2014-08-04 21:29                     ` Randy Brukardt
  0 siblings, 1 reply; 40+ messages in thread
From: Jacob Sparre Andersen @ 2014-08-03 16:07 UTC (permalink / raw)


Shark8 wrote:
> On 02-Aug-14 02:02, Jacob Sparre Andersen wrote:
>> Shark8 <OneWingedShark@gmail.com> writes:

>> LRM 3.5(56.3/3)
>
> It's only for scalar types though.

That's because the one for arrays is named Default_Component_Value - and
record components can have their default values declared without
aspects.

Enjoy,

Jacob
-- 
"You've got to build bypasses!"

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

* Re: Quick question regarding limited type return syntax
  2014-08-02 16:56                         ` Dmitry A. Kazakov
  2014-08-02 20:35                           ` Niklas Holsti
@ 2014-08-03 16:35                           ` Robert A Duff
  1 sibling, 0 replies; 40+ messages in thread
From: Robert A Duff @ 2014-08-03 16:35 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

>       procedure Initialize (X : in out T) is
>       begin
>          X.Self.Foo;
>       end Initialize;   

Thanks.  Yes, dispatching on a not-fully-constructed object is
problematic.

- Bob


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

* Re: Quick question regarding limited type return syntax
  2014-08-03  7:30                             ` Dmitry A. Kazakov
@ 2014-08-04  9:24                               ` Niklas Holsti
  2014-08-04 10:42                                 ` G.B.
                                                   ` (2 more replies)
  0 siblings, 3 replies; 40+ messages in thread
From: Niklas Holsti @ 2014-08-04  9:24 UTC (permalink / raw)


On 14-08-03 10:30 , Dmitry A. Kazakov wrote:
> On Sat, 02 Aug 2014 23:35:34 +0300, Niklas Holsti wrote:
> 
>> On 14-08-02 19:56 , Dmitry A. Kazakov wrote:
>>> On Sat, 02 Aug 2014 10:34:53 -0400, Robert A Duff wrote:
>>>
>>>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>>>>
>>>>> On Sat, 02 Aug 2014 09:20:45 -0400, Robert A Duff wrote:
>>>>>
>>>>>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>>>>>>
>>>>>>> ...Dispatching calls
>>>>>>> through class-wide access discriminants upon initialization/finalization.
>>>>>>
>>>>>> Can you please give an example of what you mean?
>>>>>
>>>>> Components not discriminants. I had Rosen's trick in mind:
>>>>>
>>>>>    type T is ...
>>>>>        Self : not null access T := T'Unchecked_Access;
>>>>
>>>> Sorry, I still don't get it.  I don't see any class-wide types or
>>>> dispatching calls there.  Also, it's illegal as written (the Rosen trick
>>>> is only allowed for limited types.)  Perhaps a complete compilable
>>>> example would help illustrate the language anomaly you are talking
>>>> about.
>>>
>>> with Ada.Finalization;
>>> with Ada.Text_IO;
>>> procedure Test is
>>>    package P is
>>>       type T is new Ada.Finalization.Limited_Controlled with record
>>>          Self : not null access T'Class := T'Unchecked_Access;
>>>       end record;
>>>       overriding procedure Initialize (X : in out T);
>>>       procedure Foo (X : in out T) is null;
>>>    end P;
>>>    
>>>    package body P is
>>>       procedure Initialize (X : in out T) is
>>>       begin
>>>          X.Self.Foo;
>>>       end Initialize;   
>>>    end P;
>>>    
>>>    package Q is
>>>       use P;
>>>       type S is new T with record
>>>          I : Integer;
>>>       end record;
>>>       overriding procedure Initialize (X : in out S);
>>>       overriding procedure Foo (X : in out S);
>>>    end Q;
>>>    
>>>    package body Q is
>>>       procedure Initialize (X : in out S) is
>>>       begin
>>>          T (X).Initialize;
>>>          X.I := 1;
>>>       end Initialize;
>>>       procedure Foo (X : in out S) is
>>>       begin
>>>          X.I := X.I + 1;
>>>       end Foo;
>>>    end Q;
>>>    
>>>    Y : Q.S;
>>> begin
>>>    Ada.Text_IO.Put_Line (Integer'Image (Y.I));
>>> end Test;
>>
>> (Dmitry, I find it quite annoying that you just dump this code on us
>> without bothering to explain why you think it shows some problem in Ada.)
> 
> Sorry, but the problem was self-evident to me. Robert asked for a working
> example so I scraped together one without much thinking.

Apology accepted, no hard feelings.

>> The code indeed accesses an uninitialized datum: when Y is initialized,
>> Initialize (S) calls Initialize (T), which makes a dispatching call to
>> Foo (S), which accesses the component S.I, which is not yet initialized.
> 
> The code prematurely dispatches on an not yet initialized object. Again, it
> was evident that this would happen when having a class-wide accessible in
> Initialize when the parent's Initialize is to be called at the beginning of
> the derived type Initialize.

I see what you mean, and I remember that you have often criticized Ada
for lacking "proper constructors".

Controlled types in Ada provide hooks (Initialize/Finalize/Adjust) that
can be used as constructors and destructors, but it is up to the
programmer to design the logic, for example to decide which object
components are initialized in Initialize, and when. In this area, Ada is
perhaps more liberal than languages which have a stricter
object-oriented view.

I don't agree that dispatching on a controlled object should be illegal
until the Initialize operation on that object has been completed. I
believe that such dispatching may be quite useful in some designs, just
as re-dispatching is useful in some designs - IMO.

Moreover, I think this question of constructor/destructor control flow
is separate from the general question of preventing access to
uninitialized data. As I understand it, even in the languages which do
have specific constructor/destructor facilities, there is no requirement
or check that a constructor must initialize all the components of the
object (but I'm not sure how Java works in this case).

> There is no safe way to do initialization in Ada because it is not properly
> typed. You should not be able to dispatch until the class-wide instance is
> fully initialized, 

I don't agree on that.

> but you can because types are broken.

If dispatching hurts you, don't do it :-)

(I'll think more about the rest of the points you made, and perhaps
reply later.)

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .


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

* Re: Quick question regarding limited type return syntax
  2014-08-04  9:24                               ` Niklas Holsti
@ 2014-08-04 10:42                                 ` G.B.
  2014-08-04 11:39                                   ` Peter Chapin
  2014-08-04 11:36                                 ` Peter Chapin
  2014-08-04 12:43                                 ` Dmitry A. Kazakov
  2 siblings, 1 reply; 40+ messages in thread
From: G.B. @ 2014-08-04 10:42 UTC (permalink / raw)


On 04.08.14 11:24, Niklas Holsti wrote:
> As I understand it, even in the languages which do
> have specific constructor/destructor facilities, there is no requirement
> or check that a constructor must initialize all the components of the
> object (but I'm not sure how Java works in this case).


Java lets you write Ada:

class T
{
     public T() {
         this.foo();
     }
     protected void foo() {}
}

class S extends T
{
     public Integer I;
     public S() {
         // calls super
         // I not initialized (and not allocated)
         this.I = 1;
     }

     @Override
     protected void foo() {
         this.I += 1;
     }
}

class Dispatching
{
     public static void main(String[] args) {
         S Y = new S();
     }
}

This program will stop after throwing a NullPointerException.
If S.I is made an int, the default value is 0, and the above
program is considered bad style(*).
   C++, I think, lets "this" stand for the type at the current "level"
during construction, so there is no dispatching to lower levels IIUC;
however, Stroustrup mentions some pointer tricks that let the
programmer circumvent the restriction.


(*) http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html


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

* Re: Quick question regarding limited type return syntax
  2014-08-04  9:24                               ` Niklas Holsti
  2014-08-04 10:42                                 ` G.B.
@ 2014-08-04 11:36                                 ` Peter Chapin
  2014-08-04 12:43                                 ` Dmitry A. Kazakov
  2 siblings, 0 replies; 40+ messages in thread
From: Peter Chapin @ 2014-08-04 11:36 UTC (permalink / raw)


On 2014-08-04 05:24, Niklas Holsti wrote:

> Moreover, I think this question of constructor/destructor control flow
> is separate from the general question of preventing access to
> uninitialized data. As I understand it, even in the languages which do
> have specific constructor/destructor facilities, there is no requirement
> or check that a constructor must initialize all the components of the
> object.

With C++ the language does not require this check but there are tools
that do it. The tools are nice because if you add a member they will
remind you to take care of it in your constructors.

The tools are not perfect. I suspect full handling of this issue may be
undecidable because the constructor can call arbitrary recursive methods
as part of it's work. So tracking precisely which members get
initialized would be quite difficult in the general case.

Peter



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

* Re: Quick question regarding limited type return syntax
  2014-08-04 10:42                                 ` G.B.
@ 2014-08-04 11:39                                   ` Peter Chapin
  2014-08-04 17:49                                     ` Niklas Holsti
  0 siblings, 1 reply; 40+ messages in thread
From: Peter Chapin @ 2014-08-04 11:39 UTC (permalink / raw)


On 2014-08-04 06:42, G.B. wrote:

>   C++, I think, lets "this" stand for the type at the current "level"
> during construction, so there is no dispatching to lower levels IIUC;
> however, Stroustrup mentions some pointer tricks that let the
> programmer circumvent the restriction.

It's true that in C++ dynamic dispatch is "turned off" during the
execution of a constructor (and destructor). This is precisely to
prevent the use of an uninitialized object when a base subobject is
being constructed (or destroyed). It's a feature! It seems to me that
circumventing it would be like circumventing the type system. You might
be able to do it but... it would be a big warning flag that something is
wrong.

Peter



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

* Re: Quick question regarding limited type return syntax
  2014-08-04  9:24                               ` Niklas Holsti
  2014-08-04 10:42                                 ` G.B.
  2014-08-04 11:36                                 ` Peter Chapin
@ 2014-08-04 12:43                                 ` Dmitry A. Kazakov
  2014-08-04 16:19                                   ` G.B.
  2014-08-04 19:37                                   ` Niklas Holsti
  2 siblings, 2 replies; 40+ messages in thread
From: Dmitry A. Kazakov @ 2014-08-04 12:43 UTC (permalink / raw)


On Mon, 04 Aug 2014 12:24:19 +0300, Niklas Holsti wrote:

> Controlled types in Ada provide hooks (Initialize/Finalize/Adjust) that
> can be used as constructors and destructors,

Not really. The problem is that they hook too late to be specific type
constructor and too early for a specific type destructor. This is why you
can dispatch from there. The problem arise when you attempt both: use
Initialize as if it were a specific constructor hook and dispatch from it.

> I don't agree that dispatching on a controlled object should be illegal
> until the Initialize operation on that object has been completed.

Then you cannot call Initialize a constructor's hook. These two are
mutually exclusive. You can dispatch not before all specific descendants
are constructed and T'Class itself.

To make it clearer consider what would be the post-condition of Initialize:

   type T is ...;
   type S is new T ...;

   Initialize (X : in out T)
      ensure
         T'Operational (X)

[*] or, maybe

         S'Operational (X)
         T'Class'Operational (X)
         S'Class'Operational (X)

Now, the precondition of a dispatching call on T'Class is obviously:

   require
      T'Class'Is_Operational (X)

Of course:

   T'Class'Operational (X) => T'Operational (X)
   T'Class'Operational (X) => S'Operational (X)

From this you can formally analyse if initialization is correct.

> I believe that such dispatching may be quite useful in some designs,

Yes it is. This is why there must be a hook at the end of construction of
T'Class. The earliest point you can dispatch if when T'Class'Operational
turns true.

> just as re-dispatching is useful in some designs - IMO.

No. This is a totally different case.

> Moreover, I think this question of constructor/destructor control flow
> is separate from the general question of preventing access to
> uninitialized data.

? Initialization = construction. I don't see how are they different.
-----------------
* T'Operational (X) is true when the object X can operate as an instance of
T.

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

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

* Re: Quick question regarding limited type return syntax
  2014-08-04 12:43                                 ` Dmitry A. Kazakov
@ 2014-08-04 16:19                                   ` G.B.
  2014-08-04 16:38                                     ` Dmitry A. Kazakov
  2014-08-04 19:37                                   ` Niklas Holsti
  1 sibling, 1 reply; 40+ messages in thread
From: G.B. @ 2014-08-04 16:19 UTC (permalink / raw)


On 04.08.14 14:43, Dmitry A. Kazakov wrote:

> To make it clearer consider what would be the post-condition of Initialize:
>
>     type T is ...;
>     type S is new T ...;
>
>     Initialize (X : in out T)
>        ensure
>           T'Operational (X)
>
> [*] or, maybe
>
>           S'Operational (X)
>           T'Class'Operational (X)
>           S'Class'Operational (X)
>
> Now, the precondition of a dispatching call on T'Class is obviously:
>
>     require
>        T'Class'Is_Operational (X)

The model is circular, I think, in that you stipulate
that 'Operational must be a "premiss" for a dispatching call,
using "obvious" as the sole reason. But while I think that
everything else is a hack, some specific dispatching scenario
need not even require the allocation of any of the derived
type's components, for when no callee needs them, they don't
matter, and still the whole object is 'Operational (in this
sense).

Not that I can now think of a case that is both useful and
cannot be "architected" in some other, perhaps better way.

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

* Re: Quick question regarding limited type return syntax
  2014-08-04 16:19                                   ` G.B.
@ 2014-08-04 16:38                                     ` Dmitry A. Kazakov
  2014-08-04 16:51                                       ` G.B.
  0 siblings, 1 reply; 40+ messages in thread
From: Dmitry A. Kazakov @ 2014-08-04 16:38 UTC (permalink / raw)


On Mon, 04 Aug 2014 18:19:16 +0200, G.B. wrote:

> On 04.08.14 14:43, Dmitry A. Kazakov wrote:
> 
>> To make it clearer consider what would be the post-condition of Initialize:
>>
>>     type T is ...;
>>     type S is new T ...;
>>
>>     Initialize (X : in out T)
>>        ensure
>>           T'Operational (X)
>>
>> [*] or, maybe
>>
>>           S'Operational (X)
>>           T'Class'Operational (X)
>>           S'Class'Operational (X)
>>
>> Now, the precondition of a dispatching call on T'Class is obviously:
>>
>>     require
>>        T'Class'Is_Operational (X)
> 
> The model is circular, I think, in that you stipulate
> that 'Operational must be a "premiss" for a dispatching call,
> using "obvious" as the sole reason.

How isn't obvious and how is it circular?

A dispatching = primitive operation is defined on the whole class. That is
the definition of. The argument of a dispatching call is of the type
T'Class. This is also per definition.

How can you call an operation of the type on an object of this type when
the former is not yet operational?

> But while I think that
> everything else is a hack, some specific dispatching scenario
> need not even require the allocation of any of the derived
> type's components, for when no callee needs them, they don't
> matter, and still the whole object is 'Operational (in this
> sense).

Maybe, but this does not follow from the types at hand.

If the language allowed partial classes you could be able to express
something like

   T'Class \ S   -- All types derived from T but S

a dispatching call to anything but Foo of S might work. That would require
definition of a primitive operation of a partial class.

   procedure Foo (X : in out T \ S); -- Whatever

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


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

* Re: Quick question regarding limited type return syntax
  2014-08-04 16:38                                     ` Dmitry A. Kazakov
@ 2014-08-04 16:51                                       ` G.B.
  2014-08-04 17:23                                         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 40+ messages in thread
From: G.B. @ 2014-08-04 16:51 UTC (permalink / raw)


On 04.08.14 18:38, Dmitry A. Kazakov wrote:
> How can you call an operation of the type on an object of this type when
> the former is not yet operational?

In a way that is somewhat like you say, namely on a partial
object when it is needed only partially:

    T.comp_1: allocated and possibly initialized
    S.comp_2: not even allocated

    overriding
    procedure Foo (X : in out S) is
    begin
       null;
    end Foo;

may "validly" become:

   alloc	comp_1
   jump	s.foo

s.foo:
   ret

Lousy, but it may "work", even when, without optimization,
some "non-existing junk" is copied for X (if it's not by ref).
Not that I want that! Just imagine the outcome should the
arbitrary location happen to be volatile…




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

* Re: Quick question regarding limited type return syntax
  2014-08-04 16:51                                       ` G.B.
@ 2014-08-04 17:23                                         ` Dmitry A. Kazakov
  0 siblings, 0 replies; 40+ messages in thread
From: Dmitry A. Kazakov @ 2014-08-04 17:23 UTC (permalink / raw)


On Mon, 04 Aug 2014 18:51:47 +0200, G.B. wrote:

> On 04.08.14 18:38, Dmitry A. Kazakov wrote:
>> How can you call an operation of the type on an object of this type when
>> the former is not yet operational?
> 
> In a way that is somewhat like you say, namely on a partial
> object when it is needed only partially:

As I said you must define "partially." This must be in type terms. So long
you don't do that, it is an untyped mess.

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

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

* Re: Quick question regarding limited type return syntax
  2014-08-04 11:39                                   ` Peter Chapin
@ 2014-08-04 17:49                                     ` Niklas Holsti
  0 siblings, 0 replies; 40+ messages in thread
From: Niklas Holsti @ 2014-08-04 17:49 UTC (permalink / raw)


On 14-08-04 14:39 , Peter Chapin wrote:
> On 2014-08-04 06:42, G.B. wrote:
> 
>>   C++, I think, lets "this" stand for the type at the current "level"
>> during construction, so there is no dispatching to lower levels IIUC;
>> however, Stroustrup mentions some pointer tricks that let the
>> programmer circumvent the restriction.
> 
> It's true that in C++ dynamic dispatch is "turned off" during the
> execution of a constructor (and destructor). This is precisely to
> prevent the use of an uninitialized object when a base subobject is
> being constructed (or destroyed). It's a feature! It seems to me that
> circumventing it would be like circumventing the type system.

It is a circumvention of the C++ type (or class) system because it has
been made so intentionally, by the logical meaning given to constructors
in the language.

> You might
> be able to do it but... it would be a big warning flag that something is
> wrong.

"Wrong" from the point of view of the C++ object philosophy, yes, but
IMO not necessarily wrong for the Ada object philosophy, where the
Initialize primitive does not have such a strong predefined meaning
(which is just what Dmitry complains about).

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .

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

* Re: Quick question regarding limited type return syntax
  2014-08-04 12:43                                 ` Dmitry A. Kazakov
  2014-08-04 16:19                                   ` G.B.
@ 2014-08-04 19:37                                   ` Niklas Holsti
  2014-08-05  8:30                                     ` Dmitry A. Kazakov
  1 sibling, 1 reply; 40+ messages in thread
From: Niklas Holsti @ 2014-08-04 19:37 UTC (permalink / raw)


On 14-08-04 15:43 , Dmitry A. Kazakov wrote:
> On Mon, 04 Aug 2014 12:24:19 +0300, Niklas Holsti wrote:
> 
>> Controlled types in Ada provide hooks (Initialize/Finalize/Adjust) that
>> can be used as constructors and destructors,
> 
> Not really.

Ok, I should have said "for similar purposes as constructors and
destructors".

> The problem is that they hook too late to be specific type
> constructor and too early for a specific type destructor. This is why you
> can dispatch from there. The problem arise when you attempt both: use
> Initialize as if it were a specific constructor hook and dispatch from it.

You have a certain concept of what a "constructor" should do, and should
not do; the latter includes dispatching. Ada allows dispatching from
Initialize, but you can disallow it by a personal design and coding rule.

>> I don't agree that dispatching on a controlled object should be illegal
>> until the Initialize operation on that object has been completed.
> 
> Then you cannot call Initialize a constructor's hook.

Depends on the meaning you assign to "constructor".

In Ada, the object is created and default-initialized (or initialized by
component-specific Initialize calls) before Initialize is called on it.
In this sense, construction in Ada is automatic, and Initialize is only
a "post-constructor" hook.

> To make it clearer consider what would be the post-condition of Initialize:
> 
>    type T is ...;
>    type S is new T ...;
> 
>    Initialize (X : in out T)
>       ensure
>          T'Operational (X)
> 
> [*] or, maybe
> 
>          S'Operational (X)
>          T'Class'Operational (X)
>          S'Class'Operational (X)

You have invented a boolean predicate "Operational". In practice,
objects do not have only two states: "not operational" and
"operational"; they have several states, and "initialization" is often a
multi-step process which takes the object through a sequence of logical
states, from its default-initialized state to whatever level of
initialization is desired at this stage.

For a well-worn example, a File object is usually born in a "closed"
state, and is then "operational" only in a limited sense; later, opening
the File makes it more "operational".

Some steps in the initialization process, while described in the
semantics of the parent type (the 'Class), may need assistance that is
specific to a derived type, and therefore dispatching from Initialize
may be useful. For example, the 'Class semantics may include
registration of all objects in some registry, but this registry may need
some object-specific data that depends on the particular type of the
object and is provided by a dispatching operation.

> Now, the precondition of a dispatching call on T'Class is obviously:
> 
>    require
>       T'Class'Is_Operational (X)
> 
> Of course:
> 
>    T'Class'Operational (X) => T'Operational (X)
>    T'Class'Operational (X) => S'Operational (X)
> 
> From this you can formally analyse if initialization is correct.

Only in your limited, two-state formalization, which IMO is not realistic.

>> Moreover, I think this question of constructor/destructor control flow
>> is separate from the general question of preventing access to
>> uninitialized data.
> 
> ? Initialization = construction. I don't see how are they different.

The point is that for some data structures, it is not desirable to
initialize (= store data in) all allocated storage locations when the
data structure is created. The reason can be that initialization is too
costly, and the initialization values are never used; or the reason can
be that the initialization could only assign dummy values, and therefore
would only ensure that later errors have a deterministic effect, but
could not ensure that no dummy initial values are used by mistake as
non-dummy values.

The canonical example is a large array that will be used as a stack, or
in which data blocks will be allocated and deallocated in some other
controlled way. Thus, the array is created (i.e. allocated or
constructed) but usually it still contains uninitialized and therefore
unpredictable data (at least in traditional processors and operating
systems -- some new or security-conscious systems have memory allocators
which do initialize all allocated memory areas, albeit with dummy values
such as zeros).

Such data structures usually have special components which "indicate"
which parts of the data structure are initialized and usable, and which
parts are not. For example, a stack pointer can perform this role for an
array that implements a stack. But current programming languages,
including Ada, do not provide any general support for this logical
connection between "indicators" and initialized/uninitialized data; the
connection must in each case be specifically formalized and then used to
prove that any data that is read has first been initialized (with real
values).

My aim was to complain about this lack of language support for such
"indicators" and other features that help to prove that a program never
uses uninitialized variables (nor dummy values). I don't know what form
this support should take, however.

As a partial analogy, discriminant checks for variant records in Ada
ensure that non-existent components are not accessed, but do not ensure
that the accessed components are initialized with useful values.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
      .      @       .

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

* Re: Default values (Was: Quick question regarding limited type return syntax)
  2014-08-03 16:07                   ` Default values (Was: Quick question regarding limited type return syntax) Jacob Sparre Andersen
@ 2014-08-04 21:29                     ` Randy Brukardt
  0 siblings, 0 replies; 40+ messages in thread
From: Randy Brukardt @ 2014-08-04 21:29 UTC (permalink / raw)


"Jacob Sparre Andersen" <jacob@jacob-sparre.dk> wrote in message 
news:87sild4kvs.fsf_-_@adaheads.sparre-andersen.dk...
> Shark8 wrote:
>> On 02-Aug-14 02:02, Jacob Sparre Andersen wrote:
>>> Shark8 <OneWingedShark@gmail.com> writes:
>
>>> LRM 3.5(56.3/3)
>>
>> It's only for scalar types though.
>
> That's because the one for arrays is named Default_Component_Value - and
> record components can have their default values declared without
> aspects.

And access types are already default initialized to null, protected type 
components are like record components, and there's nothing visible in a task 
that needs initialization.

It's not a perfect solution in that you can't change the default 
initialization of an access type nor of an array type with non-scalar 
components, but it ensures that it is possible to provide (or have one by 
definition) a real default initialization for every type.

                                                  Randy.



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

* Re: Quick question regarding limited type return syntax
  2014-08-04 19:37                                   ` Niklas Holsti
@ 2014-08-05  8:30                                     ` Dmitry A. Kazakov
  2014-08-05 19:24                                       ` Randy Brukardt
  0 siblings, 1 reply; 40+ messages in thread
From: Dmitry A. Kazakov @ 2014-08-05  8:30 UTC (permalink / raw)


On Mon, 04 Aug 2014 22:37:27 +0300, Niklas Holsti wrote:

> On 14-08-04 15:43 , Dmitry A. Kazakov wrote:
>> On Mon, 04 Aug 2014 12:24:19 +0300, Niklas Holsti wrote:
>> 
>>> Controlled types in Ada provide hooks (Initialize/Finalize/Adjust) that
>>> can be used as constructors and destructors,
>> 
>> Not really.
> 
> Ok, I should have said "for similar purposes as constructors and
> destructors".
>
>> The problem is that they hook too late to be specific type
>> constructor and too early for a specific type destructor. This is why you
>> can dispatch from there. The problem arise when you attempt both: use
>> Initialize as if it were a specific constructor hook and dispatch from it.
> 
> You have a certain concept of what a "constructor" should do, and should
> not do; the latter includes dispatching. Ada allows dispatching from
> Initialize, but you can disallow it by a personal design and coding rule.

No. I use the standard meaning of the constructor. Constructor is a thing
that makes a type instance from the chunk of raw memory.

Then I consider types T, S, T'Class, S'Class and conclude whether the
corresponding constructors could dispatch from within. This has nothing to
do with specifically Ada or with my personal choices.

>>> I don't agree that dispatching on a controlled object should be illegal
>>> until the Initialize operation on that object has been completed.
>> 
>> Then you cannot call Initialize a constructor's hook.
> 
> Depends on the meaning you assign to "constructor".

See above.

> In Ada, the object is created and default-initialized (or initialized by
> component-specific Initialize calls) before Initialize is called on it.

The object is allocated and initialized by whatever means. The second part
is called constructor. Initialize is a part of the constructor (a hook).

> In this sense, construction in Ada is automatic, and Initialize is only
> a "post-constructor" hook.

Yes. It is always so, because per definition a constrictor cannot be a
typed subprogram since it *changes* the object's type from nothing to a
distinct type. We can only hook it, as Initialize does. C++ "constructors'
are just hooks as well.
 
>> To make it clearer consider what would be the post-condition of Initialize:
>> 
>>    type T is ...;
>>    type S is new T ...;
>> 
>>    Initialize (X : in out T)
>>       ensure
>>          T'Operational (X)
>> 
>> [*] or, maybe
>> 
>>          S'Operational (X)
>>          T'Class'Operational (X)
>>          S'Class'Operational (X)
> 
> You have invented a boolean predicate "Operational". In practice,
> objects do not have only two states: "not operational" and
> "operational"; they have several states, and "initialization" is often a
> multi-step process which takes the object through a sequence of logical
> states, from its default-initialized state to whatever level of
> initialization is desired at this stage.

You could refine that in the terms of language types, I gave an example
when answering to Georg.

But presently Ada has it in the all-or-nothing form.

> For a well-worn example, a File object is usually born in a "closed"
> state, and is then "operational" only in a limited sense; later, opening
> the File makes it more "operational".

No. File_Type from Ada.Text_IO is operational in all its states = you are
allowed to use any operations of Ada.Text_IO on a closed file. No problem.

You could attempt to introduce a file type that were operational only when
open. In that case you would have to ensure it open before you leave the
constructor. You could not close it before running the destructor.

Formally speaking it is whether Is_Open is a part of the type invariant or
not.

> Some steps in the initialization process, while described in the
> semantics of the parent type (the 'Class), may need assistance that is
> specific to a derived type, and therefore dispatching from Initialize
> may be useful.

Nobody argues that dispatching from constructors were not useful. The point
is - dispatching from the constructor of WHAT?

You can dispatch only at the end of the constructor of T'Class. You cannot
dispatch nowhere from the constructor of T.

>> Now, the precondition of a dispatching call on T'Class is obviously:
>> 
>>    require
>>       T'Class'Is_Operational (X)
>> 
>> Of course:
>> 
>>    T'Class'Operational (X) => T'Operational (X)
>>    T'Class'Operational (X) => S'Operational (X)
>> 
>> From this you can formally analyse if initialization is correct.
> 
> Only in your limited, two-state formalization, which IMO is not realistic.

Show me tree-state, four-state formalization. My sole requirement is, don't
break types, Ada is supposed to be a typed language.

>>> Moreover, I think this question of constructor/destructor control flow
>>> is separate from the general question of preventing access to
>>> uninitialized data.
>> 
>> ? Initialization = construction. I don't see how are they different.
> 
> The point is that for some data structures, it is not desirable to
> initialize (= store data in) all allocated storage locations when the
> data structure is created.

They are still initialized with the garbage. No problem. You think of
initialization as of spending some CPU cycles. It is not. The only purpose
of initialization is to bring the type invariant up and thus to make the
object operational. The invariant can be just True.

> My aim was to complain about this lack of language support for such
> "indicators" and other features that help to prove that a program never
> uses uninitialized variables (nor dummy values).

This is an unrelated issue. An "uninitialized" object like:

   X : Integer;

is still fully constructed, operational and initialized, but not in the
sense of initialization you used = an explicit specification that the new
object must be in the state so and so.

> I don't know what form
> this support should take, however.

1. An ability do disallow default constructors, as it was done for
indefinite types:

   X : String; -- Illegal (no constructor)

2. Integration of SPARK. When you about prove X having certain value, the
prover will not be able to do that if the thing was never assigned.

3. Proper construction model. You must be able to write

   type ... is record
      P : not null access Something;

and then the compiler must require you to provide a constructor and add the
post-condition on P to it.

4. Proper construction model.

   X : T := Y;

must call to a constructor (hook) with the parameter Y.

5. Proper construction model.

   X : T (Y, Z);

must call to a constructor with the parameters (Y, Z).

6. Proper construction model.

   X : T := (Y, Z);

must call to a constructor with the parameters (Y, Z), *not* with an
aggregate.

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

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

* Re: Quick question regarding limited type return syntax
  2014-08-05  8:30                                     ` Dmitry A. Kazakov
@ 2014-08-05 19:24                                       ` Randy Brukardt
  0 siblings, 0 replies; 40+ messages in thread
From: Randy Brukardt @ 2014-08-05 19:24 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:a9ius0ptyh6x.x33ggbcx3wo3$.dlg@40tude.net...
...
> Yes. It is always so, because per definition a constrictor cannot be a
> typed subprogram ...

This typo gave me a good laugh! In future examples, I'll have to remember to 
name constructor functions "Boa" Then I'll have a "Boa constructor". :-)

                                                Randy.





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

end of thread, other threads:[~2014-08-05 19:24 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-30 23:51 Quick question regarding limited type return syntax NiGHTS
2014-07-31  0:02 ` Adam Beneschan
2014-07-31  0:56   ` NiGHTS
2014-07-31  0:48 ` Shark8
2014-07-31  1:00   ` NiGHTS
2014-07-31  1:29     ` Adam Beneschan
2014-07-31  1:38       ` NiGHTS
2014-07-31  4:01         ` Shark8
2014-08-01  2:12       ` Randy Brukardt
2014-08-01  3:40         ` Shark8
2014-08-01  7:57         ` J-P. Rosen
2014-08-01 19:23           ` Randy Brukardt
2014-08-01 19:37             ` J-P. Rosen
2014-08-01 20:53             ` Shark8
2014-08-02  7:11               ` Niklas Holsti
2014-08-02  7:34                 ` Dmitry A. Kazakov
2014-08-02 13:20                   ` Robert A Duff
2014-08-02 13:44                     ` Dmitry A. Kazakov
2014-08-02 14:34                       ` Robert A Duff
2014-08-02 16:56                         ` Dmitry A. Kazakov
2014-08-02 20:35                           ` Niklas Holsti
2014-08-03  7:30                             ` Dmitry A. Kazakov
2014-08-04  9:24                               ` Niklas Holsti
2014-08-04 10:42                                 ` G.B.
2014-08-04 11:39                                   ` Peter Chapin
2014-08-04 17:49                                     ` Niklas Holsti
2014-08-04 11:36                                 ` Peter Chapin
2014-08-04 12:43                                 ` Dmitry A. Kazakov
2014-08-04 16:19                                   ` G.B.
2014-08-04 16:38                                     ` Dmitry A. Kazakov
2014-08-04 16:51                                       ` G.B.
2014-08-04 17:23                                         ` Dmitry A. Kazakov
2014-08-04 19:37                                   ` Niklas Holsti
2014-08-05  8:30                                     ` Dmitry A. Kazakov
2014-08-05 19:24                                       ` Randy Brukardt
2014-08-03 16:35                           ` Robert A Duff
2014-08-02  8:02               ` Jacob Sparre Andersen
2014-08-02 19:20                 ` Shark8
2014-08-03 16:07                   ` Default values (Was: Quick question regarding limited type return syntax) Jacob Sparre Andersen
2014-08-04 21:29                     ` Randy Brukardt

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