From jwagener@amoco.com Mon Oct 10 05:25:01 1994
Received: from interlock.amoco.com by dkuug.dk with SMTP id AA08024
  (5.65c8/IDA-1.4.4j for <sc22wg5@dkuug.dk>); Mon, 10 Oct 1994 16:30:52 +0100
Received: by interlock.amoco.com id AA10910
  (InterLock SMTP Gateway 1.1 for sc22wg5@dkuug.dk);
  Mon, 10 Oct 1994 10:30:32 -0500
Received: by interlock.amoco.com (Internal Mail Agent-3);
  Mon, 10 Oct 1994 10:30:32 -0500
Received: by interlock.amoco.com (Internal Mail Agent-2);
  Mon, 10 Oct 1994 10:30:32 -0500
Received: by interlock.amoco.com (Internal Mail Agent-1);
  Mon, 10 Oct 1994 10:30:32 -0500
From: jwagener@amoco.com
X-Openmail-Hops: 1
Date: Mon, 10 Oct 94 10:25:01 -0500
Message-Id: <H000015001264430@MHS>
Subject: Technical comments on the Allocatable Components ballot
To: sc22wg5@dkuug.dk
X-Charset: ASCII
X-Char-Esc: 29

Item Subject: Message text
To X3J3 -

Attached are the technical comments associated with the letter ballot on
Allocatable Components.  As with the technical comments on the ENABLE ballot,
distributed last week, I have attempted to excise all (and only) nontechnical
comments and all references to specific individuals.

In the printed version of the attached, copies of which I will bring to the
Boston meeting, there are 14 pages of comments, the first five and a half of
which are ballot comments and the rest being various "rebuttals" and WG5
comments.  Both categories of comments are identified in the attached.

You will recall that this ballot failed and the item is a firm WG5 requirement
for Fortran 95.  Therefore I will be asking for a "best-guess" recommendation
from /OOF at the Boston meeting as to when we could have this item ready, if not
for 95-007 (following the January meeting - see 94-286).

Jerry

.......................................................................

Item Subject: technical comments - alloc comp
Technical Comments
associated with the ballot on
Allocatable Components

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

(a) allocatable dummy arguments and allocatable function results should be added to improve language consistency.

(b) an editorial cleanup is needed in order to use the term "allocatable array component" consistently instead of 
occasionally using "allocatable component",

(c) all mention of auto deallocation paper, "allocatable strings" and other things not addressed by the proposal should 
be removed from the Technical Description

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

1)  I believe the restriction against ALLOCATABLE dummy arguments is an unreasonable one.  It disallows the 
easy thing that people will want to do, yet apparently allows people to circumvent the restriction. 

What I think is Good Programming Style is something like:

       Program Example
       Allocatable :: A(:),B(:),C(:)
       Call Problem Setup (A,B,C)
       Call Do The Computations (A,B,C)
       Call Print The Report (A,B,C)
       End

Subroutine Problem Setup reads a few input cards and gets things organized for the rest of the computation.  Neat 
and fairly modular.  With this proposal I believe the program would have to be written something like

       Program Example
       Type Unused Name
            Allocatable :: array
       Ent Type Unused Name
       Type (Unused Name) :: A,B,C
       Call Problem Setup (A,B,C)
       Call Do The Computations (A%array,B%array,C%array)
       Call Print The Report (A%array,B%array,C%array)
       End
Except ... we'd have to use a module to define the Unused Name type.

I do not believe there are significant differences in implementation or complexity in allowing allocatable dummy 
arguments.  I believe that the inconsistency will be too confusing for users to understand.

2)  I really am unhappy with the edit for 32:28.  As edited the sentence will read:

"Ultimately, a derived type is resolved into ultimate components that are either of intrinsic type, are allocatable, or 
are pointers."

I realize I am complaining about existing F90 language, but there is no reason to make it worse.  While we're at it, 
we should fix obvious bugs.

In normal English the word "ultimately" means "at the end".  Given a data type HUSBAND which has allocatable 
components WIVES which have allocatable components KIDS which have allocatable components PETS.  I'd read 
this definition to mean that the ultimate components are not PETS but WIVES.  That can't be what was intended.

Don't we want this to say:

"Ultimately, a derived type is resolved into ultimate components that are either of intrinsic type or are pointers to 
entities of intrinsic type."

3)  What is allowed for deallocation of an array that has components that also have allocatable arrays if the sub-
components (non-ultimate components?) are not currently allocated?  [69:1] says it is an error condition to deallocate 
an unallocated array.  Does this apply recurrsively?  If the KIDS don't have PETS can I deallocate the WIVES?

4)  The restriction on allocatable components in I/O does not make sense. I recall that the restriction on pointer 
components had to do with  prohibiting the writing out of the dope-vector, not with writing out the values.  Since 
I/O is sort of like assignment, that is:
               WRITE(10) X
               REWIND 10
               READ (10) Y
is like
               Y = X
if X and Y are intrinsic types.

However, if X and Y are derived types which contain pointer components then the assignment is done NOT with the 
values of the things pointed to but with pointer assignment.  I believe the I/O restriction was to prevent confusion 
and misuse of the difference between
                Y%p = X%p
and
                Y%p => X%p
Especially if Y in the example above had a different type.  We didn't want people to get at the dope vector.  

The proposal justification states that allocatable components might be scattered throughout memory and this is a 
burden.  But, we allow I/O on allocatable arrays with vector valued subscripts (which might themselves be 
allocatable and have vector valued subscripts (....)) and they are also  scattered around memory.  It doesn't seem like a 
burden on implementation  to me and seems like a hinderence to user understanding.

5)  ... misunderstand the restriction on allocatable dummy arguments.  This suggests that more examples or text are 
needed.

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

   ... the irregularity of allowing dummy arguments and function results of derived types with allocatable 
components but disallowing the direct application of the allocatable attribute to dummy arguments and function 
results.  ... I agree that this irregularity is undesirable.  However, I do not feel this irregularity is sufficient reason to 
vote against the proposal.

   ... the restriction against I/O.  I am quite willing to admit that we may not wish to retain this restriction in the 
long run, but there are enough questions about exactly which cases should be allowed and exactly what should be 
done in those cases that I am far more comfortable disallowing it now and considering what relaxation of that 
restriction is appropriate in Fortran 2000.

   I strongly disagree with the suggestion that zero-size arrays and unallocated arrays should somehow be equivalent 
or interchangeable.

   I regret that this proposal did not include "allocatable strings". Much of the character handling power of the 
language is invested in character strings.  Forcing users to use allocatable arrays of characters in place of allocatable 
strings means having to "reinvent the wheel" for much of this.  I think this is a serious irregularity. (The 
seriousness of this irregularity will become more obvious when we parameterize user-defined types and tell users that 
they can have an allocatable array but not an allocatable MATRIX, so I expect that will fix it eventually; I just think 
it is unfortunate we aren't fixing it now.)

   As with allocatable dummy arguments and function results, I do not see this irregularity as sufficient reason to 
vote NO.

   I regret that this proposal did not include the fix to DEALLOCATE to ignore attempts to DEALLOCATE an 
allocatable array that is not currently allocated.  (I do not consider the current behavior to be irregular, but the change 
would have been simple and would have made the language more "user-friendly".)

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

... "complications with constructors" are serious.  In particular, I think there needs to be a way to accomplish 
assignment using a constructor without allocating the allocatable  components, for example a syntax like ".NULL." 
that means "unallaocated component."

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

  In F90, as the motivation says, allocatable arrays are similar to pointers which have not been pointer-assigned. 
Thus a trivial check and a flag in the compiler would preserve the behaviour of local allocatables. Optimization on 
local allocatables (pointers) would be unaffected. Passing the dereferenced pointer is the same as passing an 
allocatable. Deallocation of a host/use associated allocatable could  be handled with a run-time 'not pointer assigned' 
flag. So, a way to simplify the language would be to get rid of allocatables and rely on compilers to deal with 
special cases of pointers. Has WG5   considered this? The only benefit alluded to is a concern with    optimization. 

  I assume allocatable component is only an allocatable array?

  Other -
    4.4 edit - isn't an allocatable array a component of intrinsic type? Does the ALLOCATABLE or POINTER 
attribute make a type non-intrinsic? 4.3 doesn't suggest so.
    
    Could we introduce a term for 'allocatable array or derived type object containing an ultimate allocatable 
component' - perhaps 'deferred-size object' or some such.
    
   The rationale is verbose. Could we delete or trim the 1st paragraph, and remove paragraph on IO.
   
----------------------------------------------------------------------

This proposal claims to move allocatable arrays toward becoming "first class objects" in the language, but it only 
goes a short distance on that route.  I find the cutoff point to be rather strange and irregular, but that, in itself, would 
not cause me to vote no on the proposal.  Unfortunately, because the objective changed during the course of 
preparing the proposal, it is not always clear what is allowed and what isn't.

I believe it was not the intention to allow allocatable objects (character strings where the length type parameter was 
determined by an ALLOCATE statement) as components in objects of derived type.  Some text mentions 
"allocatable components" while other text uses the more specific term "allocatable array components". The latter 
term should be used throughout.  Certainly there is no example of an allocatable object as a component and no text 
drawing attention to this "new feature".  It would be very strange if this facility were provided for subobjects but not 
for variables of intrinsic type.  If I am mistaken and allocatable nonarray components are intended, then I must vote 
NO categorically.  ... we should not mix the concepts of type parameterization (KIND and LEN) and arrayness in 
this way.  It is a violation of the integrity of the language as established when the character data type was added.

I believe the only finally agreed extensions for allocatable arrays are:

  - allow allocatable arrays as components in derived type objects

  - allow objects of derived type with allocatable array components to be passed as arguments and returned as function 
results

For the latter extension, the type definition must be accessible (in at least two different scoping units) by use or host 
association.  That is, it must be the SAME type definition because SEQUENCE is not allowed in a type definition 
containing an allocatable array component.  The Rationale accompanying the proposal states "the primary purpose of 
SEQUENCE is to allow derived-type objects to appear in [storage-associated] contexts". My recollection is that this 
was one of two equally important purposes.  The other was to allow for global type definitions without resort to 
modules.  A type definition with an allocatable array component is the only case where this is no longer possible.  
This does not bother me personally, because I believe everyone should use modules, but there were a number of 
people who felt strongly about it at one time.  This is one of the irregularities involved with the cutoff point.  
Another is, of course, that objects with allocatable array components can be arguments or function results, but 
allocatable arrays cannot. [See comments on the Rationale in the final paragraph below.]

The issue of assigning a zero-sized array to an unallocated component is a bit of a red herring.  If the rules set down 
in the proposal are followed, this is not allowed; and I believe that is the way it should be.  It may seem laborious to 
have to allocate a zero-sized array before another zero-sized array can be assigned to it, but that is the way it is for 
nonzero-sized arrays; so why should it be different for zero-sized ones?

Appended below is a proposal that I could vote for.  I have not attempted to revise the Rationale, but I believe it 
needs attention.  The first two paragraphs expound the benefits of making allocatable arrays first class objects.  The 
remaining paragraphs list some of the ways in which this proposal falls short of that goal.  There needs to be 
something in the middle explaining why this particular cutoff was chosen and intimating that it is a temporary 
situation (perhaps until the next revision).

Alternative Proposal:

Detailed EDITS:

[32:28] after: "Ultimately, a derived type is resolved into ultimate components that are"
        change:  "either of intrinsic type"
        to:  "of intrinsic type, are allocatable arrays,"

[33:20] after: "R427  component-attr-spec        is POINTER"
        add new line:
                                                 or ALLOCATABLE"

[33:26]  add new constraints following the third constraint of R427:
        "Constraint: POINTER and ALLOCATABLE must not both appear in the same component-def-stmt."

        "Constraint: The ALLOCATABLE attribute must not be specified if SEQUENCE is present in the derived-
type- def."

[33:31-32] in the first constraint of R429,
         change: "If the POINTER attribute is not specified"
         to: "If neither the POINTER attribute nor the ALLOCATABLE attribute is specified"

[33:33] in the second constraint of R429,
        change: "POINTER attribute" to "POINTER attribute or the ALLOCATABLE attribute"

[33:33+] add an IMPORTANT new constraint
        "Constraint: If the ALLOCATABLE attribute is specified for a component, the component must be a deferred- 
shape array."

[33:38+] {default initialization, per 94-138}
      after:  "the POINTER attribute must not appear"
      add:  "and the ALLOCATABLE attribute must not appear"

[34:2] change:  "or both"
       to:  "the ALLOCATABLE attribute, or any combination thereof"

[35:35+] {edits to object initialization proposal in 94-009.006}
     in paragraph 3 (immediately following the first example in this edit),
     after:  "If a component is of intrinsic type and is not"
     insert:  "an allocatable array or"
     {{before "a pointer, a default initial value may be specified..."}}
     later in the same paragraph,
     after:  "If the component is of derived type and does not have the"
     replace:  "pointer attribute"
     with:     "ALLOCATABLE attribute or POINTER attribute"

[35:35+] add new paragraphs:
        "A derived type may have a component that is an allocatable array.  For example:

          TYPE STACK
               INTEGER :: INDEX
               INTEGER, ALLOCATABLE, DIMENSION(:) :: CONTENTS
          END TYPE STACK

For each variable of type STACK, the shape of the component CONTENTS is determined by execution of an 
ALLOCATE statement."

[35:46+] add note:
         "Note that for two objects with allocatable array components to be of the same type, they must be declared 
with reference to the same type definition, because allocatable array components are not permitted in sequence types."

[37:28] Add, at the end of this subclause, new paragraphs:
       "Where a component of the derived type is an allocatable array, the corresponding constructor expression must 
evaluate to an array. The value of the constructor will have a component that is allocated (has an allocation status of 
allocated), and with contents as given by the constructor expression.  Note that the allocation status of the 
allocatable array component is available to the user program if the constructor is associated with a dummy argument, 
but generally not for other uses.  Note, also, that when the constructor value is used in assignment, the 
corresponding component of the target must already be allocated.

Where a derived type contains an ultimate allocatable array component, the constructor must not appear as a data-
stmt-constant in a DATA statement (5.2.9), as an initialization-expr in an entity-decl (5.1), or as an initialization-
expr in a component-initialization (4.4.1)."

[40:5] after:  "an allocatable array,"
       add:  "a derived-type object containing an ultimate allocatable array component,"

[40:20]  after:  "allocatable arrays,"
         add: "derived-type objects with an ultimate allocatable component that is a pointer or allocatable array,"

[44:24+] change:  "a stat-variable"
         to:  "an allocate-object or stat-variable"

[46:8] in the first line of the second paragraph, change: "a named array" to "an array"

[46:10]  add to end of sentence:
         "or evaluation of a structure constructor for a derived type with an allocatable array component"

[46:11] after:  "in a type declaration statement"
        add:  ", a component definition statement,"

[46:13] after:  "in a type declaration statement,"
        add:  "a component definition statement,"

[46:15] after:  "type declaration statement"
        add:  "or a component definition statement"

[52:34] change:  "or an allocatable array"
        to:  "an allocatable array, or a variable of a type that has a pointer or allocatable array as an ultimate 
component"

[56:11] change:  ", or an allocatable array"
        to:  ", an allocatable array, or a variable of a type that has a pointer or an allocatable array as an ultimate 
component"

[57:1] [The following edit is not needed because allocatable arrays can appear only in nonsequence derived types and 
according to 94-287, nonsequence derived types are prohibited as equivalence objects.]
xxx   after: "an allocatable array,"
xxx   add: "a derived-type object containing an ultimate allocatable component,"

[63:8] after:  "attribute"
       add:  "and must not have the ALLOCATABLE attribute"

[68:7+] Add new paragraph at the end of this subclause:
"If an object of derived type is created by an ALLOCATE statement, any ultimate allocatable array components have 
an allocation status of not currently allocated."

[69:8] add footnote: "Allocatable array components of derived- type objects with the SAVE attribute also retain their 
allocation status."
     {{note: similar issue for 69:29, for pointers }}

[69:9]
      "(2) An allocatable array that is part of the return value of a function,
       (3) An allocatable array that is part of a dummy argument,"

[77:40] after: "(3) A structure constructor where each component is an initialization expression"
        add:       "and no component has the ALLOCATABLE attribute"

[91:20] after:  "nonpointer components."
        add: "Note that for allocatable array components the component in the variable being defined must already be 
allocated, and the shapes of the corresponding allocatable array components of the variable being defined and the 
expression must be the same."

[124:17] after:  "If a derived type ultimately contains a pointer component"
         add:  "or allocatable array component"

Annex A
[254:12-13] change: "A named"
            to:  "An"
            append to end of definition:
            "An allocatable array may be a named array or a structure component"

[261:21-22] after:  "a component that is of intrinsic type"
            add:  ", has the ALLOCATABLE attribute,"

[261:23] after:  "does not have the"
         add:  "ALLOCATABLE attribute or"

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

Rebuttals and comments from WG5 members

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

>        In addition, if an ALLOCATABLE object is still allocated when it goes
>out of scope, its allocation status becomes undefined.  There is a desire that
>the deallocation be provided "automatically" by the processor.  That is
>addressed in a separate paper (X3J3/94-270r2).

I am in favor of the automatic deallocation proposed in 94-270r2; however, this paragraph seems to be setting up 
automatic deallocation as a general requirement for all ALLOCATABLE objects, including such possible future 
enhancements as ALLOCATABLE dummies and function return values.  I do not understand how the latter could be 
implemented efficiently, or, for that matter, exactly _when_ a function return value goes "out of scope".  I assume 
ALLOCATABLE dummies would have to correspond to ALLOCATABLE actual argument variables which would 
have their own scope so this case is more understandable, though not, in my opinion, adequately spelled out in this 
overview.  I suggest that the above paragraph be qualified somehow to indicate that automatic deallocation is not a 
general requirement for all future objects that might be given an ALLOCATABLE attribute.

>        The current paper provides a major step towards ALLOCATABLE arrays as
>full, first-class entities.  It provides for them to appear as components of
>derived types, as per WG5-N931, "Requirements for Allowing Allocatable
>Derived-type Components".
>        Still outstanding from the general request:
>                - ALLOCATABLE dummy arguments and function return values

The present proposal appears to leave in place the restriction against ALLOCATABLE _whole_ arrays as dummy 
arguments and function return values but to permit ALLOCATABLE arrays as subobjects of such entities -- was this 
the intent?  If so, I strongly oppose such an ad hoc compromise -- it won't significantly reduce the complexity of the 
standard or of implementations, it will only annoy users and undermine our credibility.  If this was not the intent, 
the edits proposed below are completely inadequate.

>                - ALLOCATABLE strings
>                - ALLOCATABLE derived types (needs Parameterized Derived Types)

I'm not certain what distinction is being made here between "ALLOCATABLE derived types" and "ALLOCATABLE 
components in structures", unless the former is being treated as a synonym for derived types with non-kind 
parameters.

>While these are mostly fairly straightforward, a large number of edits appear
>to be required.  Due to the shortage of time, we recommend that this
>development be undertaken for Fortran 2000.
>        Per direction from X3J3, this proposal does not provide for allowing
>ALLOCATABLE objects, nor derived type objects with ALLOCATABLE components in
>COMMON or EQUIVALENCE.
>
>Motivation:
>        ALLOCATABLE provides functionality which shares much with that of the
>POINTER features.  Indeed, the underlying implementation is probably nearly
>identical, with one important difference.  The address pointer implicit in
>ALLOCATABLE objects is not accessible to the user.  ALLOCATABLE objects,
>therefore, cannot be aliased with other objects as a result of pointer
>assignments.  For this reason, they behave much better than pointers with
>respect to optimization.
>        Given the benefits of ALLOCATABLE, it appears advisable to extend the
>facility to handle derived type components as well as normal variables.  The
>extension introduces little additional complexity into either the language
>definition or implementation; in fact, one can argue that the generalization
>serves to remove an arbitrary restriction from the language.
>        The duties of the implementor follow directly from current practice.
>If a local object has the ALLOCATABLE attribute, the implementation must
>arrange to set the object to non-allocated status at the time that the object
>is created.  This duty is now extended to components of derived type objects.
>In addition, if a derived type object with an ALLOCATABLE component is itself
>created via an ALLOCATE statement, the component must be set to non-allocated
>status as part of the creation.
>        There exists some complication with regards to constructors.  There is
>no "null" value for an allocatable object, so the constructor must specify an
>actual value set for an allocatable component.  (This will generally be an
>array constructor with an implied DO to provide the right number of elements.)
>(Note that, even though "assignment semantics" apply, this value cannot be
>given as a scalar, as there is no size given in the type definition.)
>        The value of the constructor will include the allocatable component in
>an "allocated" state with the indicated contents.  Note that the rules of
>assignment for allocatable arrays involve copying the contents, not the
>implicit pointer.  Thus, if the constructor is used in an assignment
>statement, the allocatable components of the target variable must already be
>allocated.
>        Lastly, because allocation cannot be done prior to execution,
>allocatable components cannot be initialized in DATA statements or with =
>initialization.
>        (Note that some of these conditions may be changed slightly if we
>approve the proposal for constructors with keyword and optional fields.)

Can a structure with an allocated component of zero size be assigned to a structure where the corresponding 
component has not been allocated?  If not, why not?  I would find such a restriction quite artificial, and I would 
expect many implementations to make such an obvious extension.  If such an assignment _is_ allowed, why can't 
allocated components be initialized with zero-sized array constructors?  I think the inability to initialize the non-
allocatable components of such a structure except via default initialization is a serious flaw.

>Where a derived type contains an ultimate allocatable component, the
>constructor must not appear as a data-stmt-constant in a DATA statement
>(5.2.9), as an initialization-expr in an entity-decl (5.1), or as an
>initialization-expr in a component-initialization (4.4.1)."

[See above comments on unallocated vs. zero-sized allocated components.]

>Subclause 5.1
>[40:5] [=initialization]
>        after:  "an allocatable array,"
>        add:    "a derived-type object containing an ultimate allocatable component,"

If the intent was to prohibit dummies and functions results from containing ALLOCATABLE subobjects, the 
constraint at lines [40:8-9] needs to be generalized.

>[40:20] [addition to constraint so it is clear they cannot be initialised at compile time]
>        after:  "allocatable arrays,"
>        add: "derived-type objects containing an ultimate allocatable component,"
>
>Subclause 5.1.2.3
>[44:24+] [edit to interpretation edit, paper 94-274r1]
>        change: "a stat-variable"
>        to:     "an allocate-object or stat-variable"

This text pertains to the INTENT attribute which is only permitted for dummy arguments, so if the intent was to 
prohibit dummies from containing ALLOCATABLE subobjects, this edit should be deleted.

>        add: "Note that for allocatable components the component in the
>              variable being defined must already be allocated, and the shapes
>              of the corresponding allocatable components of the variable
>              being defined and the expression must be the same."

[See above comments on unallocated vs. zero-sized allocated components.]

>Subclause 9.4.2
>[124:17] [we do not allow derived-types with pointer components in i/o
>          statements, neither should we allow ones with allocatable components]
>        after:  "If a derived type ultimately contains a pointer component"
>        add:    "or allocatable component"

I don't see any need for this restriction -- see my further comments in the rationale section, below.

>        Array variables, and components of derived types, can be specified as
>ALLOCATABLE when it is desired to calculate their size as a function of some
>value determined during execution.
>        Explicit initialization of allocatable arrays is not permitted for
>SAVEd variables, because such initialization may take place prior to
>execution, but the ALLOCATE action only occurs during execution.

[See above comments on unallocated vs. zero-sized allocated components.]

>        Input/output of derived types containing allocatable components is not
>permitted.  This is because the storage of an allocatable component is
>typically far removed from that of the other derived type components, so it
>would be a non-trivial burden to the implementor for unformatted i/o.  ...

This argument is specious -- an ALLOCATABLE component is no more difficult for the implementer to deal with 
than an extra ALLOCATABLE array in the i/o-list

>                                                                  ...  Also,
>for derived types containing allocatable components, as for derived types
>containing pointer components, the i/o action desired by the user is unlikely
>to be that which can be provided automatically.  ...

Perhaps, but the same argument can be made for _any_ derived type, not just those containing pointers.  I believe 
the real problem with pointer components is the possibility of circular links.

>                                            ...  User-defined i/o of derived
>types is not part of this standard but we wish to avoid adding a facility
>which will be little used and likely to conflict with the addition of the
>proper facility in a later revision of the standard (or as a vendor
>extension).

I'm not so sure that it would be little used -- though pointer components will often be used to build lists, trees, and 
other complex structures for which the intuitively "right" style of I/O is unclear, ALLOCATABLE components 
cannot be used in such ways.  I would guess that most of the time ALLOCATABLE components will be used just 
like any other ALLOCATABLE array, and that I/O will therefore be handled similarly.

In any case, why would default I/O for ALLOCATABLE structure components be any more likely to conflict with 
some possible future extension for user-defined derived type I/O than the default I/O we have currently for ordinary 
structures?

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

> >        In addition, if an ALLOCATABLE object is still allocated when it goes
> >out of scope, its allocation status becomes undefined.  There is a desire that
> >the deallocation be provided "automatically" by the processor.  That is
> >addressed in a separate paper (X3J3/94-270r2).
> 
> I am in favor of the automatic deallocation proposed in 94-270r2; however,
> this paragraph seems to be setting up automatic deallocation as a general
> requirement for all ALLOCATABLE objects, including such possible future
> enhancements as ALLOCATABLE dummies and function return values.  I do not
> understand how the latter could be implemented efficiently, or, for that
> matter, exactly _when_ a function return value goes "out of scope".  I assume

Actually this would be very easy; it would be exactly the same as the time one gets the storage back for any non-
pointer array-valued function.  And one would never "auto-dealloc" an ALLOCATABLE dummy - it is when the 
actual goes out of scope.

> I suggest that the above paragraph be qualified somehow to
> indicate that automatic deallocation is not a general requirement for
> all future objects that might be given an ALLOCATABLE attribute.

Er... this paragraph merely points to a separate paper (on which you voted YES).  As explanatory text it is certainly 
not setting up any requirement in itself.

[...]
> >        Still outstanding from the general request:
> >                - ALLOCATABLE dummy arguments and function return values
> 
> The present proposal appears to leave in place the restriction
> against ALLOCATABLE _whole_ arrays as dummy arguments and function
> return values but to permit ALLOCATABLE arrays as subobjects of such
> entities -- was this the intent?  If so, I strongly oppose such an ad

Yes, this was the position reached by meeting 129 (i.e. the one before last). As such it was treated as a 
recommendation to WG5 that ALLOCATABLE dummies and function results not be proceeded with for Fortran 95.

> hoc compromise -- it won't significantly reduce the complexity of
> the standard or of implementations, it will only annoy users and
> undermine our credibility.  If this was not the intent, the edits

I agree with you that leaving these out will not significantly reduce the complexity of implementations but I do 
think it reduces the complexity of the standard.

[...]
> >                - ALLOCATABLE strings
> >                - ALLOCATABLE derived types (needs Parameterized Derived Types)
> 
> I'm not certain what distinction is being made here between "ALLOCATABLE
> derived types" and "ALLOCATABLE components in structures", unless the former
> is being treated as a synonym for derived types with non-kind parameters.

Yes, this text should probably be struck since it is referring to a proposal which is not to be in F95.

> >implicit pointer.  Thus, if the constructor is used in an assignment
> >statement, the allocatable components of the target variable must already be
> >allocated.
> >        Lastly, because allocation cannot be done prior to execution,
> >allocatable components cannot be initialized in DATA statements or with =
> >initialization.
> >        (Note that some of these conditions may be changed slightly if we
> >approve the proposal for constructors with keyword and optional fields.)
> 
> Can a structure with an allocated component of zero size be assigned
> to a structure where the corresponding component has not been
> allocated?  If not, why not?  I would find such a restriction quite

Because we are following the existing model for allocatable arrays in the Fortran 90 standard.  Currently, if one has 
an allocatable array name on the LHS of an assignment it must be allocated with the shape conformable to that of 
the expression on the RHS.

> artificial, and I would expect many implementations to make such an
> obvious extension.  If such an assignment _is_ allowed, why can't

This extension is just as obvious and the restriction is just as artificial as for allocatable arrays now.  Adding such a 
facility in F95 or F2000 is not precluded by 94-269r2, but allocatable arrays should be treated consistently whether 
or not they are components.

Also, in the case of derived types the user has the opportunity to define their own assignment with their required 
semantics, so I do not believe this to be a serious problem.

[...]
> >        Input/output of derived types containing allocatable components is not
> >permitted.  This is because the storage of an allocatable component is
> >typically far removed from that of the other derived type components, so it
> >would be a non-trivial burden to the implementor for unformatted i/o.  ...
> 
> This argument is specious -- an ALLOCATABLE component is no more
> difficult for the implementer to deal with than an extra ALLOCATABLE
> array in the i/o-list

Not so: an extra allocatable array (which does not contain allocatable components!) is a single contiguous object.  A 
derived-type object containing allocatable components (some of which could contain allocatable components of their 
own) will have its storage scattered throughout memory in a tree-like fashion.

[...]
> I believe the real problem with pointer components is the possibility of
> circular links.

Certainly that is a problem which allocatable components cannot have; however the Fortran 90 standard goes much 
further than prohibiting circularity (it does not even allow i/o on derived-type objects containing pointers to intrinsic 
types -- which cannot possibly be circular!).

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

... my main problem is that the current proposal is seriously incomplete and as a result introduces an unacceptable 
irregularity in the language.  One of the reasons that allocatable components were not proposed for F90 was that if 
you have a component that is allocatable you have to deal with the issue of passing allocatable objects or you have 
the strange restriction of a type for which it is illegal to declare a dummy argument or function result. 

I strongly believe that an adequate proposal must allow derived types with allocatable components to appear as 
dummy arguments and as function results. Thus the issues of how an allocatable dummy and result must be faced 
and solved both for allocatable components and allocatable arrays.

On the other hand I do not believe that character strings allocated via the LEN parameter are desirable in principle. 
Type parameters, even non-kind ones that are internally to the type something like an array bound are externally very 
different and we should not mix the concepts of arrayness and type-parameterisation in this way.

... assignment of zero sized allocatable component to an unallocated component of the same type. I think this would 
be very useful and it should be allowed. However if it is then it should similarly permissable for a zero-sized 
allocatable array to be assigned to an unallocated array. We should not have behaviour for a component which would 
not be permissable for the simple object of the same characteristics. 

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

Detailed EDITS:
    {{note: edits are marked with a brief comment about the particular subject area being addressed.  In some cases, a 
subject area is relevant but requires no edits; in such cases, a null edit (plus comment) is given. }}

[throughout]    {general nomenclature}
    {no problem.  The Standard references the term "allocatable array" throughout.  There is no problem, in general, 
with this terminology applying equitably to either data entities or to components; so no pervasive change is 
required.}

Subclause 4.4
[32:28] {make allocatable components ultimate}
    after: "Ultimately, a derived type is resolved into ultimate components that are"
    change:    "either of intrinsic type"
    to:    "of intrinsic type, are allocatable,"

Subclause 4.4.1
[33:20] {definition of component-attr-spec}
    after:    "R427  component-attr-spec        is    POINTER"
    add new line:
                                         or ALLOCATABLE"

>COMMENT> [33:22-23]
>COMMENT> Consider the source fragment
>COMMENT> TYPE PETE
>COMMENT>   TYPE(PETE), POINTER :: A(:)
>COMMENT>   TYPE(PETE), ALLOCATABLE :: B(:)
>COMMENT> END TYPE
>COMMENT> Why was is thought necessary to disallow the declaration for B above,
>COMMENT> while allowing the declaration for A. The motivation states 'ALLOCATABLE
>COMMENT> provides functionality which shares much with that of the POINTER features.
>COMMENT> Indeed the underlying implementation is probably nearly identical ...'
>COMMENT> This would seem to be a surprising difference to a user. Is there a
>COMMENT> technical reason for the difference that I'm missing?

[33:26]
    add a new constraint following the third constraint of R427:
        "Constraint: POINTER and ALLOCATABLE must not both appear inthe same component-def-stmt."

[33:26+] {{WG5: Since allocatable components prohibit appearance in storage-associated contexts, do not allow 
sequence types to contain allocatable components.}}
    add a new constraint following the above:
        "Constraint: The ALLOCATABLE attribute must not be specified if SEQUENCE is present in the derived-
type-def."

[33:31-32] {WG5(reworded):dimension info} in the first constraint of R429,
    change:    "If the POINTER attribute is not specified"
    to: "If neither the POINTER attribute nor the ALLOCATABLE attribute is specified"

[33:33] {WG5(reworded):dimension info}
    in the second constraint of R429,
    change: "POINTER attribute" to "POINTER attribute or the ALLOCATABLE attribute"

[33:38+] {default initialization, per 94-138}
    after:    "the POINTER attribute must not appear"
    add:    "and the ALLOCATABLE attribute must not appear"

[33:39] {sequence types}
    {{WG5: No changes needed.  A sequence type cannot have allocatable components.}}

[34:2] {when one needs to have "::" in a component definition}
    change:    "or both"
    to    "the ALLOCATABLE attribute, or any combination thereof"

[35:35+] {edits to object initialization proposal in 94-009.006}
    in paragraph 3 (immediately following the first example in this edit),
    after:    "If a component is of intrinsic type and is not"
    insert:    "allocatable or"
    {{before "a pointer, a default initial value may be specified..."}}
    later in the same paragraph,
    after:    "If the component is of derived type and does not have the"
    replace:    "pointer attribute"
    with:    "ALLOCATABLE attribute or POINTER attribute"

[35:35+] {examples}
    add new paragraphs:
    "A derived type may have a component that is allocatable.  For example:

        TYPE STACK
            INTEGER :: INDEX
            INTEGER, ALLOCATABLE, DIMENSION(:) :: CONTENTS
        END TYPE STACK

      For each variable of type STACK, the shape of the component CONTENTS is determined by execution of an 
ALLOCATE statement."

Subclause 4.4.4
[37:28] {constructors}{{WG5: Interaction with 94-009.006 in last sentence of this addition}}
    Add, at the end of this subclause, new paragraphs:
    "Where a component of the derived type is an allocatable array, the corresponding constructor expression must 
evaluate to an array.  The value of the constructor will have a component that is allocated (has an allocation status of 
allocated), and with contents as given by the constructor expression.  Note that the allocation status of the 
allocatable component is available to the user program if the constructor is associated with a dummy argument, but 
generally not for other uses.  Note, also, that when the constructor value is used in assignment, the corresponding 
component of the target must already be allocated. 

Where a derived type contains an ultimate allocatable component, the constructor must not appear as a data-stmt-
constant in a DATA statement (5.2.9), as an initialization-expr in an entity-decl (5.1), or as an initialization-expr in 
a component-initialization (4.4.1)."

Subclause 5.1
[40:5] {=initialization}
    after:    "an allocatable array,"
    add:    "a derived-type object containing an ultimate allocatable component,"

[40:20] {addition to constraint so it is clear they cannot be initialised at compile time}
    after:    "allocatable arrays,"
    add: "derived-type objects containing an ultimate allocatable component,"

Subclause 5.1.2.3
[44:24+] {edit to interpretation edit, paper 94-274r1}
    change:    "a stat-variable"
    to:    "an allocate-object or stat-variable"

Subclause 5.1.2.4.3
[46:8] {allocatable arrays are no longer necessarily named}
    in the first line of the second paragraph, change: "a named array" to "an array"

[46:10] {shape of an allocatable component can also be determined by a structure constructor}
    add to end of sentence:
    "or evaluation of a structure constructor for a derived type with an allocatable component"

[46:11] {where & how you can declare ALLOCATABLEs}
    after:    "in a type declaration statement"
    add:    ", a component definition statement,"

[46:13] {ditto}
    after:    "in a type declaration statement,"
    add:    "a component definition statement,"

[46:15] {ditto}
    after:    "type declaration statement"
    add:    "or a component definition statement"

Subclause 5.1.2.9
[48:24] {storage units, sequence}
    {WG5: This change has been deleted as unnecessary since derived type objects containing allocatable components 
cannot appear in COMMON or EQUIVALENCE}. 

Subclause 5.2.9
[52:34] {DATA statement restrictions}
    change:    "or an allocatable array"
    to:     "an allocatable array, or a derived-type object containing an ultimate allocatable component"

Subclause 5.4
[56:11] {WG5: do not allow allocatable components in NAMELIST}
    change:    ", or an allocatable array"
    to:    ", an allocatable array, or a derived-type object containing an ultimate allocatable component"

Subclause 5.5.1
[57:1] {WG5: do not allow allocatable components in EQUIVALENCE}
    after:    "an allocatable array,"
    add: "a derived-type object containing an ultimate allocatable component,"

Subclause 5.5.2
[58:30] {{WG5: allocatable components are not allowed in COMMON since they are excluded from sequence types}}

Subclause 5.5.2.3
[59:42+] {Common Association}
    {{no edit needed; not allowed in COMMON}}

Subclause 6.1.2
[63:8] {corresponding restriction to that preventing array ops on pointer components}
    after:    "attribute"
    add:    "and must not have the ALLOCATABLE attribute"

Subclause 6.3.1
[67:16] {allocate statement}
    {ok - because POINTER components were allowed}

Subclause 6.3.1.1
[68:1+] {allocation of allocatable arrays - initial status}
    {ok, existing text appears to be sufficient}

[68:7+] {{WG5: Specify initial state of allocatable components after ALLOCATE}}
    Add new paragraph at the end of this subclause:
"If an object of derived type is created by an ALLOCATE statement, any ultimate allocatable components have an 
allocation status of not currently allocated."

Subclause 6.3.3.1
[69:8] {deallocation}
    add footnote: "Allocatable array components of derived-type objects with the SAVE attribute also retain their 
allocation status."
    {{note: similar issue for 69:29, for pointers }}

[69:9] add list items and renumber
    "(2) An allocatable array that is part of the return value of a function,
     (3) An allocatable array that is part of a dummy argument,"

Subclause 7.1.6.1
[77:40] {{remove derived-type constructors with allocatable array components from initialization exprs}}
    after: "(3) A structure constructor where each component is an initialization expression"
    add:    "and no component has the ALLOCATABLE attribute"

Subclause  7.5.1.5
[91:20] {interpretation of intrinsic assignment}
    after:    "nonpointer components."

    add: "Note that for allocatable components the component in the variable being defined must already be allocated, 
and the shapes of the corresponding allocatable components of the variable being defined and the expression must be 
the same."
  
Subclause 9.4.2
[124:17] {we do not allow derived-types with pointer components in i/o statements, neither should we allow ones 
with allocatable components}
    after:    "If a derived type ultimately contains a pointer component"
    add:    "or allocatable component"

Annex A
[254:12-13] {Fix glossary copy of the definition of an allocatable array}
    change:    "A named"
    to:    "An"
    append to end of definition:
        "An allocatable array may be a named array or a structure component"

[261:21-22] {Fix glossary copy of the definition of ultimate component}
    after:    "a component that is of intrinsic type"
    add:    ", has the ALLOCATABLE attribute,"

[261:23]
    after:    "does not have the"
    add:    "ALLOCATABLE attribute or"

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