On 2016-05-07 8:54 AM,
herrman...@gmail.com wrote:
> On Friday, May 6, 2016 at 3:33:45 PM UTC-7, Ian Harvey wrote:
>
> (snip, I wrote)
>
>>> I was thinking about something like:
>>> real(kind=xx), parameter :: bar(*) = [real(kind=*)::z'0']
>
>>> where the * means the kind for the variable being initialized.
>>> (And an additional use for * in the standard, since there aren't enough yet.)
>
>> It would be far more general and coherent to have that arranged the
>> other way around.
>
>> real(*), parameter :: bar(*) = [real(kind=xx)::z'0']
>
> Maybe more coherent, but not so general as one might want:
>
> real(kind=xx) :: bar(*) = sqrt([*:: 10, 20, 30]]) + sqrt([*::11, 22, 33])
>
> so now the type and kind of two arrays depends on the type and kind
> of bar.
Consider the special cases that you would require to defend against the
following forms of nonsense:
! Apply the kind of one type to another.
real(kind=xx) :: bar = sqrt([integer(*) :: 10, 20, 30])
! I want to initialize with the precise values of the contstant, but
! this is going to do kind conversion of a default real value to
! something more precise.
DOUBLE PRECISION :: bar(3) = [ real(*) :: 0.1, 0.1, 0.1 ]
! The structure constructor assumes the kind of ... PRINT?
PRINT *, [real(*) :: 1.0, 2.0, 3.0]
! Specific procedures for different kinds, which one do we call?
CALL GenericProcedure([real(*) :: 1.0, 2.0, 3.0])
You are describing a feature for expressions (and *only* for structure
constructor primaries, why not all the other cases where kind can be
specified in a primary?), which otherwise have very consistent rules for
their syntax and semantics where ever they appear, and are then going to
have to restrict that feature to one particular use case.
Such a irregular special case is the antithesis of "general".
>> The kind of the named constant (or it could be more general) is assumed
>> from the kind of its initializer, symmetric to how the shape of the
>> named constant is assumed from the shape of its initializer.
>
> You are right that it might be more coherent in many cases, and might
> have a better chance of getting through the standardization.
>
>> (Use of an array constructor is just an example - the initializer could
>> be any constant expression, in all cases the type and kind of which can
>> be determined by the compiler without knowing the context of how the
>> expression is to be used.)
>
>> Some statically typed languages permit the assumption of type in this way.
>
>> Initializers are converted by the rules of intrinsic assignment to the
>> type, type parameters and shape of the thing being initialized. That
>> conversion would need to be excluded (or otherwise specified - perhaps
>> as per mixed mode numeric operations) in the event of initialization of
>> something with assumed kind.
>
>> (The shape conversion aspect around how named constants are given a
>> value from their initializer must be excluded/modified in some way when
>> the named constant is using the F2008 implied shape feature, but in the
>> current committee draft I don't see where that is done (or such syntax
>> prevented).
>
>> integer, parameter :: array(*) = 4
>
> Seems to me that you can't do that.
>
> Probably also not good to try:
>
> real :: yy(*) = spread(1.,1,size(yy))
In Fortran 2008, a specification inquiry in a constant expression is not
permitted to inquire about something specified in the same entity
declaration that the constant expression is used in. This excludes the
above syntax (and for that matter, I think most of the examples in this
thread that have `kind(bar)` appearing in the initializer for bar
itself, but that does depend on the interpretation of where something
like an kind type parameter for an entity is specified).
(Fortran 2008 also requires that something declared with an implied
shape spec be a named constant.)
However, the current draft of the next revision relaxes the requirement
when the constant expression appears in an initialization (16-007r1
7.1.12p2). If you add the parameter attribute to the above, I think
this would be problematic in F201X.
real, parameter :: yy(*) = spread(1.,1,size(yy))
(If you adopted the assumed kind stuff above, you would also need
something to stop circular definition of kind. Consequently I really
don't this relaxation of the requirement that a specification inquiry
cannot depend on something in the same entity-decl is a good idea - you
are chopping off potential avenues of language development that are down
the direction where many other statically typed languages have gone.)