Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to use BOZ-literal-constants in an integer array constructor?

533 views
Skip to first unread message

FortranFan

unread,
May 3, 2016, 2:09:03 PM5/3/16
to
Hi,

I need to construct an integer array of a named constant using BOZ-literal-constants as in

integer(kind=xx), parameter :: SOME_DATA(*) = [ z'..', z'..', .. ]

but the current standard doesn't seem to allow this.

The standard states:

C4102 (R463) A boz-literal-constant shall appear only as a data-stmt-constant in a DATA statement, or where explicitly allowed in subclause 13.7 as an actual argument of an intrinsic procedure

So it would appear one can do:

integer(kind=xx), parameter :: foo = int( z'0', kind=kind(foo) ) !.. OK

but not the following, at least according to Intel Fortran:

integer(kind=xx), parameter :: bar(*) = int( [ z'0' ], kind=kind(bar) ) !.. Not OK per ifort

Now, of course, one can use INT intrinsic function for each element of the array as in

integer(kind=xx), parameter :: bar2(*) = [ int( z'0', kind=xx), int( z'1', kind=xx) ]

which is acceptable to me but it does seem a tad verbose, especially when the array size becomes. So I am wondering if I am overlooking some other option for better syntax in the language.

A couple of questions:

1. Am I correct in my understanding the standard does not allow constructs such as integer, parameter :: bar(*) = int( [ z'0' ], kind=kind(bar) ) ? Meaning prior to invoking the elemental INT intrinsic function, the array will be constructed and BOZ constants are not valid in an array-constructor, even when that array constructor is being passed to an intrinsic procedure?

2. Any other standard-conforming way to how to construct an integer array named constant using BOZ literals besides what I show above?

Steve Lionel

unread,
May 3, 2016, 3:25:19 PM5/3/16
to
On 5/3/2016 2:09 PM, FortranFan wrote:
> 1. Am I correct in my understanding the standard does not allow constructs such as integer, parameter :: bar(*) = int( [ z'0' ], kind=kind(bar) ) ? Meaning prior to invoking the elemental INT intrinsic function, the array will be constructed and BOZ constants are not valid in an array-constructor, even when that array constructor is being passed to an intrinsic procedure?
>
> 2. Any other standard-conforming way to how to construct an integer array named constant using BOZ literals besides what I show above?

The standard is quite explicit as to where BOZ constants are allowed:

C4102 (R463) A boz-literal-constant shall appear only as a
data-stmt-constant in a DATA statement, or where explicitly allowed in
subclause 13.7 as an actual argument of an intrinsic procedure.

This doesn't have the words "or in an array constructor". If use in an
array constructor was allowed, there would then need to be words to say
what data type the constructor had, since BOZ constants have no type. I
suppose one would then be required to add an explicit type-spec in the
constructor.

What you're asking for seems quite reasonable, but the language doesn't
currently allow for it in a concise fashion. Feel free to propose this
for "Fortran 2020" (or whatever it will be called.)

--
Steve Lionel
Developer Products Division
Intel Corporation
Merrimack, NH

For email address, replace "invalid" with "com"

User communities for Intel Software Development Products
http://software.intel.com/en-us/forums/
Intel Software Development Products Support
http://software.intel.com/sites/support/
My Fortran blog
http://www.intel.com/software/drfortran

Refer to http://software.intel.com/en-us/articles/optimization-notice
for more information regarding performance and optimization choices in
Intel software products.

herrman...@gmail.com

unread,
May 3, 2016, 8:50:44 PM5/3/16
to
On Tuesday, May 3, 2016 at 12:25:19 PM UTC-7, Steve Lionel wrote:

(snip)

> The standard is quite explicit as to where BOZ constants are allowed:

> C4102 (R463) A boz-literal-constant shall appear only as a
> data-stmt-constant in a DATA statement, or where explicitly allowed in
> subclause 13.7 as an actual argument of an intrinsic procedure.

> This doesn't have the words "or in an array constructor". If use in an
> array constructor was allowed, there would then need to be words to say
> what data type the constructor had, since BOZ constants have no type. I
> suppose one would then be required to add an explicit type-spec in the
> constructor.

> What you're asking for seems quite reasonable, but the language doesn't
> currently allow for it in a concise fashion. Feel free to propose this
> for "Fortran 2020" (or whatever it will be called.)

Seems to me that Fortran does allow for BOZ constants use in a concise
fashion in DATA statements, just like it says above. If the whole idea is to
efficiently (in program characters) initialize an array using BOZ, DATA does
just fine.

There are a fair number of cases where one needs an array of constant
(never changing) data, with state tables for state machines, as one
example.

Sometimes, one wants to know about the efficiency of the generate code,
not just the efficiency of writing the source. (Though it is usually easy to automate
source generation when needed.) On most machines, DATA generates the bytes
directly into the object program, where they are loaded into memory along with the
rest of the program.

For one, that makes them less efficient for initializing a large array.

interger x(100000)
data x/1000000*1/

is likely to generate a very large object file, where

integer x(1000000)
x=1

generates a loop, setting the whole array to 1 at run time. As the loop is
usually faster than reading from disk, the latter is often preferred.

I suspect that array initializers also generate large object programs, but haven't
tested it recently.

Richard Maine

unread,
May 3, 2016, 9:36:29 PM5/3/16
to
<herrman...@gmail.com> wrote:

> Seems to me that Fortran does allow for BOZ constants use in a concise
> fashion in DATA statements, just like it says above. If the whole idea is to
> efficiently (in program characters) initialize an array using BOZ, DATA does
> just fine.

Yes, but if you check the OP's post, he specifically was asking about a
named constant array. DATA statements only apply to variables - not
constants. That's why I didn't give a reply mentioning DATA.

One might argue that using a variable is a possible workaround,
depending on the exact application, but that would be a workaround
rather than doing what was actually asked. What was asked seems to me
like at least a reasonable desire. I recall being pleased when constant
arrays were introduced in f90, so that I no longer had to do that sort
of workaround for other cases, but I wasn't doing BOZ. In f77 all
constants were scalar.

--
Richard Maine
email: last name at domain . net
dimnain: summer-triangle

herrman...@gmail.com

unread,
May 3, 2016, 10:09:17 PM5/3/16
to
On Tuesday, May 3, 2016 at 6:36:29 PM UTC-7, Richard Maine wrote:


(snip, I wrote)
> > Seems to me that Fortran does allow for BOZ constants use in a concise
> > fashion in DATA statements, just like it says above. If the whole idea is to
> > efficiently (in program characters) initialize an array using BOZ, DATA does
> > just fine.

> Yes, but if you check the OP's post, he specifically was asking about a
> named constant array. DATA statements only apply to variables - not
> constants. That's why I didn't give a reply mentioning DATA.

I suppose it is nice to have something that the compiler will flag if you
put it on the wrong side of an assignment, but most often I don't have
so much of a problem with 'variables' that don't vary.

(Note that Java has 'static final variables' which have similar properties
to Fortran PARAMETER, including that you can't change them, but they
are still called variables.)

> One might argue that using a variable is a possible workaround,
> depending on the exact application, but that would be a workaround
> rather than doing what was actually asked. What was asked seems to me
> like at least a reasonable desire. I recall being pleased when constant
> arrays were introduced in f90, so that I no longer had to do that sort
> of workaround for other cases, but I wasn't doing BOZ. In f77 all
> constants were scalar.

Non-array PARAMETER are convenient in the places that you can put them
where you can't use variables, such as dimensions for non-dynamic arrays.
That is, places where the value is used at compile time, and often not generated
a place in memory.

But there aren't so many such uses for arrays. I suppose one use for a PARAMETER
array is initializing an actual array.

But otherwise, as I noted, the other way is to write a program in some language,
which may or may not be Fortran, to generate the verbose form required.

There are many cases where the legal form is not so convenient for use, and a program
to convert is useful.

But I certainly am not against adding it to a future version of the standard.


Richard Maine

unread,
May 3, 2016, 10:20:12 PM5/3/16
to
<herrman...@gmail.com> wrote:

> On Tuesday, May 3, 2016 at 6:36:29 PM UTC-7, Richard Maine wrote:
>
> (snip, I wrote)
> > > Seems to me that Fortran does allow for BOZ constants use in a concise
> > > fashion in DATA statements, just like it says above. If the whole
> > > idea is to efficiently (in program characters) initialize an array
> > > using BOZ, DATA does just fine.
>
> > Yes, but if you check the OP's post, he specifically was asking about a
> > named constant array. DATA statements only apply to variables - not
> > constants. That's why I didn't give a reply mentioning DATA.
>
> I suppose it is nice to have something that the compiler will flag if you
> put it on the wrong side of an assignment, but most often I don't have
> so much of a problem with 'variables' that don't vary.

It's a lot more than just the left-hand side of an assignment statement.
That one tends to be pretty obvious. But there are plenty of places
where the safety of having a constant is handy. One I can well imagine
for arrays is an actual argument for a dummy that isn't intent(in). Sure
you can throw out the extra safety and still have working programs. You
can throw out lots of safety features. To heck with making things
private, declaring intent at all, or a bunch of other things. Yep, you
can in principle do without them, but they are in the language for a
reason. I personally think it is a good reason.

FortranFan

unread,
May 3, 2016, 10:34:18 PM5/3/16
to
On Tuesday, May 3, 2016 at 9:36:29 PM UTC-4, Richard Maine wrote:

> .. What was asked seems to me
> like at least a reasonable desire. ..


Thanks, that is very helpful for me to know.

FortranFan

unread,
May 3, 2016, 10:35:21 PM5/3/16
to
On Tuesday, May 3, 2016 at 3:25:19 PM UTC-4, Steve Lionel wrote:

> ..
>
> What you're asking for seems quite reasonable, but the language doesn't
> currently allow for it in a concise fashion. Feel free to propose this
> for "Fortran 2020" (or whatever it will be called.)
>
> ..

Thanks for the feedback, Steve - will do.

robin....@gmail.com

unread,
May 4, 2016, 12:09:58 AM5/4/16
to
On Wednesday, May 4, 2016 at 12:09:17 PM UTC+10, herrman...@gmail.com wrote:
> On Tuesday, May 3, 2016 at 6:36:29 PM UTC-7, Richard Maine wrote:
>
>
> (snip, I wrote)
> > > Seems to me that Fortran does allow for BOZ constants use in a concise
> > > fashion in DATA statements, just like it says above. If the whole idea is to
> > > efficiently (in program characters) initialize an array using BOZ, DATA does
> > > just fine.
>
> > Yes, but if you check the OP's post, he specifically was asking about a
> > named constant array. DATA statements only apply to variables - not
> > constants. That's why I didn't give a reply mentioning DATA.
>
> I suppose it is nice to have something that the compiler will flag if you
> put it on the wrong side of an assignment, but most often I don't have
> so much of a problem with 'variables' that don't vary.

Constants that vary were a problem in FORTRAN. Might still be,
as uses in this NG are still using FORTRAN 77.

herrman...@gmail.com

unread,
May 4, 2016, 7:00:22 AM5/4/16
to
On Tuesday, May 3, 2016 at 7:20:12 PM UTC-7, Richard Maine wrote:
> > On Tuesday, May 3, 2016 at 6:36:29 PM UTC-7, Richard Maine wrote:


(I wrote)
> > > > Seems to me that Fortran does allow for BOZ constants use in a concise
> > > > fashion in DATA statements, just like it says above.
(snip)

> > > Yes, but if you check the OP's post, he specifically was asking about a
> > > named constant array. DATA statements only apply to variables - not
> > > constants. That's why I didn't give a reply mentioning DATA.

> > I suppose it is nice to have something that the compiler will flag if you
> > put it on the wrong side of an assignment, but most often I don't have
> > so much of a problem with 'variables' that don't vary.

> It's a lot more than just the left-hand side of an assignment statement.
> That one tends to be pretty obvious. But there are plenty of places
> where the safety of having a constant is handy. One I can well imagine
> for arrays is an actual argument for a dummy that isn't intent(in). Sure
> you can throw out the extra safety and still have working programs. You
> can throw out lots of safety features. To heck with making things
> private, declaring intent at all, or a bunch of other things. Yep, you
> can in principle do without them, but they are in the language for a
> reason. I personally think it is a good reason.

Yes, but many of these features also require you to be more verbose.

If you have a lot of arguments, and have to put INTENT(IN) in each one, that is
a lot of typing.

I also suspect that SELECTED_INT_KIND() is more verbose than some
might like, but we have that one.

Hmmm, I just notice that there is no SELECTED_LOGICAL_KIND(), but there are
KINDs for LOGICAL values.

Richard Maine

unread,
May 4, 2016, 11:12:02 AM5/4/16
to
<herrman...@gmail.com> wrote:

> On Tuesday, May 3, 2016 at 7:20:12 PM UTC-7, Richard Maine wrote:

> > You can throw out lots of safety features....

> Yes, but many of these features also require you to be more verbose.

Well, yes. If terse and dangerous is your preferred style, that's an
option. Fortran doesn't traditionally force you to use the safety
features; they are optional. The optionality adds a little danger in
that it is possible to forget to use the features even if you intended
to, but that's a tradeoff we have generally accepted (not to universal
agreement, but generally).

I'm slightly surprised you even bring up the subject. While true, it
seems more a whimsical reply than a serious one. But if we are in that
mode, I'll reply in the same whimsical vein, more for my own amusement
than substance.

> If you have a lot of arguments, and have to put INTENT(IN) in each one,
> that is a lot of typing.

INTENT declarations lowered the amount of typing in my code. That's
because by the time f90 came around, I had developed the habit in my f77
code of having a separate comment line for each argument to document
whether it was for input, output, or both. (And none of this nonstandard
use of "!" for comments in my f77, so it did mean a whole separate
line.) I was pleasantly surprised to find that f90 allowed me to
essentially turn my comments into compilable code.

I similarly used the construct name on END DO statements to get rid of
my former comments documenting what DO loops my CONTINUE statements were
terminating, at least for loops with bodies of more than a very few
lines.

> I also suspect that SELECTED_INT_KIND() is more verbose than some
> might like, but we have that one.

And it generally appears about once per kind per program in code that
uses it. Put it in a module, which you use. Some text examples show it
on individual declarations, but that's just horrid in most cases.

As long as you are going for terse, might as well get rid of named
constants at all. If something is 13, just type 13 instead of all this
newfangled verbose PARAMETER stuff.

And I'm shocked that you left out the biggest single case that I can
think of - type declarations. Hey, "implicit none" is 13 extra
characters (if I counted correctly), plus a newline. And all it does is
force you to do yet more typing. (In my formal comments on f90, I had
suggested making implicit none the default for free source form, since
that would not have invalidated any standard-conforming old code; my
suggestion didn't fly, obviously).

Don't forget about comments. Nothing but extra verbosity there.

I'll argue that being terse can increase typing in the long run. All the
debugging that ensues can involve a lot of typing. Not to speak of the
typing involved in correspondence with users who run into bugs that
slipped by you. :-)

herrman...@gmail.com

unread,
May 4, 2016, 1:57:21 PM5/4/16
to
On Wednesday, May 4, 2016 at 8:12:02 AM UTC-7, Richard Maine wrote:

(snip on safety features, then I wrote)

> > Yes, but many of these features also require you to be more verbose.

> Well, yes. If terse and dangerous is your preferred style, that's an
> option. Fortran doesn't traditionally force you to use the safety
> features; they are optional. The optionality adds a little danger in
> that it is possible to forget to use the features even if you intended
> to, but that's a tradeoff we have generally accepted (not to universal
> agreement, but generally).

> I'm slightly surprised you even bring up the subject. While true, it
> seems more a whimsical reply than a serious one. But if we are in that
> mode, I'll reply in the same whimsical vein, more for my own amusement
> than substance.


(snip on INTENT and comments)

> > I also suspect that SELECTED_INT_KIND() is more verbose than some
> > might like, but we have that one.

> And it generally appears about once per kind per program in code that
> uses it. Put it in a module, which you use. Some text examples show it
> on individual declarations, but that's just horrid in most cases.

Theoretically, one could figure out the optimal SELECTED_xxx_KIND for each
variable, and declare appropriately. That rarely happens in real programs.
But if it did, it could be one per variable declaration.

> As long as you are going for terse, might as well get rid of named
> constants at all. If something is 13, just type 13 instead of all this
> newfangled verbose PARAMETER stuff.

> And I'm shocked that you left out the biggest single case that I can
> think of - type declarations. Hey, "implicit none" is 13 extra
> characters (if I counted correctly), plus a newline. And all it does is
> force you to do yet more typing. (In my formal comments on f90, I had
> suggested making implicit none the default for free source form, since
> that would not have invalidated any standard-conforming old code; my
> suggestion didn't fly, obviously).

OK, but the question is scaling. You put one IMPLICIT NONE,
then one declaration for each variable, but the OP is asking for one that
is for each array element. I suspect for a large enough array, you could
exceed some statement length or continuation line limit due to the verbosity.

Last night, while half asleep, I thought of a possible way to change it.

In the suggested form, it is INT(Z'123',KIND(XXX)), assuming one is initializing
an array named XXX.

It occurred to me that the KIND argument is a scalar integer constant expression.

The thought is that one could allow: INT(Z'123',XXX) instead, in cases where XXX
was not a scalar integer constant, with an implied KIND(). In the case in question,
the OP is initializing an array, and so not scalar, but it could also work for:

REAL :: YYY=REAL(Z'41100000',YYY)

since YYY isn't INTEGER, and I suspect it can even work for the case:

INTEGER, PARAMETER :: P=INT(Z'123',P)

as P isn't a scalar integer constant expression until after that statement has
been processed. That is, there is no ambiguity in the value of P, though it might
be a little less readable than the REAL or array case.

herrman...@gmail.com

unread,
May 4, 2016, 10:04:56 PM5/4/16
to

(snip, previously I wrote)

> It occurred to me that the KIND argument is a scalar integer constant expression.

> The thought is that one could allow: INT(Z'123',XXX) instead, in cases where XXX
> was not a scalar integer constant, with an implied KIND(). In the case in question,
> the OP is initializing an array, and so not scalar, but it could also work for:

> REAL :: YYY=REAL(Z'41100000',YYY)

> since YYY isn't INTEGER, and I suspect it can even work for the case:

> INTEGER, PARAMETER :: P=INT(Z'123',P)

> as P isn't a scalar integer constant expression until after that statement has
> been processed. That is, there is no ambiguity in the value of P, though it might
> be a little less readable than the REAL or array case.

Thinking about this a little more, that isn't likely to happen. It gives one argument
two different meanings. But this is a fix.

Add a third argument to functions like INT and REAL, a MOLD argument like some
other functions have, indicating the type and kind you would like the result to have.
(The type probably has to agree, so only the KIND is getting MOLDed.) That would allow:

REAL :: YYY=REAL(Z'41100000',,YYY)

as noted previously, most cases are not ambiguous, and for those the second comma
could be omitted. Seems to me that often enough MOLD is more obvious than KIND,
not just in declarations but in assignment and other uses of such functions.


Richard Maine

unread,
May 5, 2016, 1:21:46 AM5/5/16
to
<herrman...@gmail.com> wrote:

> On Wednesday, May 4, 2016 at 8:12:02 AM UTC-7, Richard Maine wrote:

> OK, but the question is scaling. You put one IMPLICIT NONE,
> then one declaration for each variable, but the OP is asking for one that
> is for each array element. I suspect for a large enough array, you could
> exceed some statement length or continuation line limit due to the verbosity.

Your reading of the OP's request is different than mine. There is
already a way to do it for each array element, and I would agree that is
excessively verbose. I rather thought the OP was explicitly asking for
something *OTHER* than that. To quote from his original post,

>> Now, of course, one can use INT intrinsic function for each element
>> of the array as in

>> integer(kind=xx), parameter :: bar2(*) = [ int( z'0', kind=xx),
>> int( z'1', kind=xx) ]

>> which is acceptable to me but it does seem a tad verbose, especially
>> when the array size becomes. So I am wondering if I am overlooking
>> some other option for better syntax in the language.

See Steve's suggestion, which involves declaring the kind once for the
entire array using a syntax we already have for that. It just involves
using that declaration to apply to BOZ interpretation of the elements.

herrman...@gmail.com

unread,
May 5, 2016, 2:29:38 AM5/5/16
to
On Wednesday, May 4, 2016 at 10:21:46 PM UTC-7, Richard Maine wrote:
> (I wrote)

> > On Wednesday, May 4, 2016 at 8:12:02 AM UTC-7, Richard Maine wrote:

> > OK, but the question is scaling. You put one IMPLICIT NONE,
> > then one declaration for each variable, but the OP is asking for one that
> > is for each array element. I suspect for a large enough array, you could
> > exceed some statement length or continuation line limit due to the verbosity.

> Your reading of the OP's request is different than mine. There is
> already a way to do it for each array element, and I would agree that is
> excessively verbose. I rather thought the OP was explicitly asking for
> something *OTHER* than that. To quote from his original post,

Well, yes, but he was asking for the other because INT for each was verbose.

Partly because it isn't only the INT, which isn't so bad, but the ,KIND(bar).

Well, even more, the OP had INT(Z'0', KIND=KIND(bar))

> >> Now, of course, one can use INT intrinsic function for each element
> >> of the array as in

> >> integer(kind=xx), parameter :: bar2(*) = [ int( z'0', kind=xx),
> >> int( z'1', kind=xx) ]

> >> which is acceptable to me but it does seem a tad verbose, especially
> >> when the array size becomes. So I am wondering if I am overlooking
> >> some other option for better syntax in the language.

> See Steve's suggestion, which involves declaring the kind once for the
> entire array using a syntax we already have for that. It just involves
> using that declaration to apply to BOZ interpretation of the elements.

OK, but it is still a little verbose even for only one.

Clive Page

unread,
May 5, 2016, 5:13:41 AM5/5/16
to
On 03/05/2016 19:09, FortranFan wrote:
> Hi,
>
> I need to construct an integer array of a named constant using BOZ-literal-constants as in
>
> integer(kind=xx), parameter :: SOME_DATA(*) = [ z'..', z'..', .. ]
>
> but the current standard doesn't seem to allow this.

The DATA statement rules allow the simple syntax that you want, but it
only applies to variables not constants of course.

But I have a suggestion: do this in a module (maybe one set up for the
purpose) and declare your array of variables to have PROTECTED status,
then use a DATA statement in that module to initialise the elements.
If I understand it correctly, you can use the module to access the array
anywhere else but the array will be protected against changed, i.e.
effectively an array of constants. Would this be suitable? I just
tried it, and it seems to do the job:

module test_prot_module
implicit none
integer, protected :: array(3)
data array / z'123', z'456', z'789' /
end module test_prot_module

program test_prot
use test_prot_module
implicit none
write(*,*)'array=', array

!! array(1) = 3 ! Will not compile because array is protected

end program test_prot



--
Clive Page

FortranFan

unread,
May 5, 2016, 7:53:55 AM5/5/16
to
On Thursday, May 5, 2016 at 1:21:46 AM UTC-4, Richard Maine wrote:

> ..
>
> Your reading of the OP's request is different than mine. There is
> already a way to do it for each array element, and I would agree that is
> excessively verbose. I rather thought the OP was explicitly asking for
> something *OTHER* than that. To quote from his original post,
>
> ..

As always, Richard Maine's reading of an original post is right on the money. How he condenses it here is exactly what I was asking about.

>
> See Steve's suggestion, which involves declaring the kind once for the
> entire array using a syntax we already have for that. It just involves
> using that declaration to apply to BOZ interpretation of the elements.
>

But hmmm.. I am not sure about this statement. My read of Steve Lionel's response is two things:

a) he stresses Intel Fortran is correct in issuing the warning that it does because the standard, as written currently, clearly does not allow an instruction of the form:

integer(kind=xx), parameter :: bar(*) = int( [ z'0' ], kind=kind(bar) )

or for that matter,
..
use, intrinsic :: iso_fortran_env, only : xx => int32
..
integer(kind=xx), parameter :: bar(*) = int( [ z'0' ], kind=kind(xx) )

b) and he thinks it is reasonable the standard be modified to allow above instructions and that I should go ahead and propose this to the standards committee.

Thanks for your attention,

FortranFan

unread,
May 5, 2016, 7:56:02 AM5/5/16
to
On Thursday, May 5, 2016 at 5:13:41 AM UTC-4, Clive Page wrote:

> ..
>
> The DATA statement rules allow the simple syntax that you want, but it
> only applies to variables not constants of course.
>
> But I have a suggestion: do this in a module (maybe one set up for the
> purpose) and declare your array of variables to have PROTECTED status,
> then use a DATA statement in that module .. Would this be suitable? ..


Thanks much for your response, it will an acceptable solution too under other circumstances. But for now I will prefer the somewhat verbose option involving named constant, meaning PARAMETER attribute.

Steve Lionel

unread,
May 5, 2016, 9:29:24 AM5/5/16
to
On 5/5/2016 7:53 AM, FortranFan wrote:
> But hmmm.. I am not sure about this statement. My read of Steve Lionel's response is two things:
>
> a) he stresses Intel Fortran is correct in issuing the warning that it does because the standard, as written currently, clearly does not allow an instruction of the form:
>
> integer(kind=xx), parameter :: bar(*) = int( [ z'0' ], kind=kind(bar) )
>
> or for that matter,
> ..
> use, intrinsic :: iso_fortran_env, only : xx => int32
> ..
> integer(kind=xx), parameter :: bar(*) = int( [ z'0' ], kind=kind(xx) )
>
> b) and he thinks it is reasonable the standard be modified to allow above instructions and that I should go ahead and propose this to the standards committee.

Not quite. a) is correct - that syntax is nonstandard. As an extension,
Intel Fortran assigns a meaning to it but not necessarily the one you
want. For example, if bar (and the initial value expression) was real
instead of integer, you might get a surprise.

But for b, I am not suggesting the above syntax. Instead I suggest:

integer(kind=xx), parameter :: bar(*) = [integer(kind(xx))::z'0']

In other words, extending array constructors to allow BOZ literals if
and only if a type-spec is included that specifies a type of integer,
real or complex. The interpretation would then be that each BOZ literal
in the constructor is as if it had been the first argument to INT, REAL
or CMPLX with the KIND argument specified (if in the type-spec).

This proposal is cleaner than the above, which would need to have lots
of special words added for array constructor arguments with BOZ
literals. And what if the constructor had a mix of BOZ literals and
other things?

We already have the type-spec for array constructors - extending the
meaning for any BOZ literals in the constructor is straightforward and
allows use in other contexts.

Gary Scott

unread,
May 5, 2016, 10:11:29 AM5/5/16
to
IVF seems to me to already "do the right thing" with BOZ and 16#xx.
I've never been surprised...yet

Richard Maine

unread,
May 5, 2016, 10:46:28 AM5/5/16
to
Steve Lionel <steve....@intel.invalid> wrote:

> But for b, I am not suggesting the above syntax. Instead I suggest:
>
> integer(kind=xx), parameter :: bar(*) = [integer(kind(xx))::z'0']
>
> In other words, extending array constructors to allow BOZ literals if
> and only if a type-spec is included that specifies a type of integer,
> real or complex...

> This proposal is cleaner than the above, which would need to have lots
> of special words added for array constructor arguments with BOZ
> literals. And what if the constructor had a mix of BOZ literals and
> other things?
>
> We already have the type-spec for array constructors - extending the
> meaning for any BOZ literals in the constructor is straightforward and
> allows use in other contexts.

Yep. I picked that up from Steve's initial post. Admitedly, that initial
post was a bit brief, but the rest seemed to me to follow pretty
directly. Perhaps it is because I was already familliar with exactly
what is already there for array constructors as of f2003. The relevant
syntax was new to f2003 and I'm guessing it might not have come to some
poster's minds. I was very familliar with that syntax because it solved
a bit of awkwardness that had buged me for a long time, namely how to
write a constructor for an array of character string literals without
carefully padding each literal to the same length (shades of Pascal).

His initial post just said that

> one would then be required to add an explicit type-spec in the
> constructor.

Since we already have a syntax for exactly that, it seemed obvious to me
that one would just use that syntax rather than invent something
different. (And I was very confident that Steve knew about that syntax).
As he notes above, BOZ interpretation would fit pretty cleanly into the
description of what that syntax means. The other syntax ideas mentioned
here require that the interpretation of the array constructor be
influenced by things outside of the constructor. That is pretty
radically different from the way almost everything else in Fortran works
and would get "messy" to precisely describe. The words for how to
describe the syntax Steve shows practically write themselves as far as I
can see. And as he says, they naturally allow constuctors where some
elements are BOZ and others are not.

FortranFan

unread,
May 5, 2016, 11:53:36 AM5/5/16
to
On Thursday, May 5, 2016 at 9:29:24 AM UTC-4, Steve Lionel wrote:

> ..
>
> Not quite. ..
>
> In other words, extending array constructors to allow BOZ literals if
> and only if a type-spec is included that specifies a type of integer,
> real or complex. ..


Thanks, Steve, for the clarification. I totally missed out on the type-spec addition to the constructor, my bad - I should have noticed it.

The type-spec syntax makes perfect sense and if available, that would indeed be my preferred approach in code.

herrman...@gmail.com

unread,
May 5, 2016, 12:09:15 PM5/5/16
to
On Thursday, May 5, 2016 at 6:29:24 AM UTC-7, Steve Lionel wrote:
> On 5/5/2016 7:53 AM, FortranFan wrote:

(snip)

> Not quite. a) is correct - that syntax is nonstandard. As an extension,
> Intel Fortran assigns a meaning to it but not necessarily the one you
> want. For example, if bar (and the initial value expression) was real
> instead of integer, you might get a surprise.

> But for b, I am not suggesting the above syntax. Instead I suggest:

> integer(kind=xx), parameter :: bar(*) = [integer(kind(xx))::z'0']

Seems to me that this has, pretty much, the problem that I recently noted
in another thread. Well, maybe not yet, but if instead:

real(kind=xx), parameter :: bar(*) = [real(kind(xx))::z'0']

where xx is presumably integer, and kind(xx) is an integer kind.

(I think this isn't actually Steve's fault, but that he copied it and modified
it from a previous post. But it does show how easy it is to do.)

> In other words, extending array constructors to allow BOZ literals if
> and only if a type-spec is included that specifies a type of integer,
> real or complex. The interpretation would then be that each BOZ literal
> in the constructor is as if it had been the first argument to INT, REAL
> or CMPLX with the KIND argument specified (if in the type-spec).

(snip)

-- glen

Dick Hendrickson

unread,
May 5, 2016, 12:26:12 PM5/5/16
to
I don't think it's a foolproof solution. As I understand it, the
PROTECTED status doesn't follow actual arguments into a subroutine nor
does it work "as expected" with pointers.

Dick Hendrickson

Clive Page

unread,
May 5, 2016, 6:48:20 PM5/5/16
to
On 05/05/2016 17:26, Dick Hendrickson wrote:

> I don't think it's a foolproof solution. As I understand it, the
> PROTECTED status doesn't follow actual arguments into a subroutine nor
> does it work "as expected" with pointers.

You may well be right; but if it doesn't follow actual arguments, it
isn't very useful then. Never mind, the syntax of the DATA statement is
so attractive that this seemed worth proposing, as I've never thought of
using it like that before.



--
Clive Page

herrman...@gmail.com

unread,
May 5, 2016, 7:13:02 PM5/5/16
to
(snip, I wrote)

> Seems to me that this has, pretty much, the problem that I recently noted
> in another thread. Well, maybe not yet, but if instead:

> real(kind=xx), parameter :: bar(*) = [real(kind(xx))::z'0']

> where xx is presumably integer, and kind(xx) is an integer kind.

I see no-one else has commented on this one yet.

Note that kind(xx) might not be kind(bar).

William Clodius

unread,
May 6, 2016, 12:02:53 AM5/6/16
to
Steve Lionel <steve....@intel.invalid> wrote:

> On 5/3/2016 2:09 PM, FortranFan wrote:
> > 1. Am I correct in my understanding the standard does not allow
> >constructs such as integer, parameter :: bar(*) = int( [ z'0' ],
> >kind=kind(bar) ) ? Meaning prior to invoking the elemental INT intrinsic
> >function, the array will be constructed and BOZ constants are not valid
> >in an array-constructor, even when that array constructor is being passed
> >to an intrinsic procedure?
> >
> > 2. Any other standard-conforming way to how to construct an integer
> >array named constant using BOZ literals besides what I show above?
>
> The standard is quite explicit as to where BOZ constants are allowed:
>
> C4102 (R463) A boz-literal-constant shall appear only as a
> data-stmt-constant in a DATA statement, or where explicitly allowed in
> subclause 13.7 as an actual argument of an intrinsic procedure.
>
> This doesn't have the words "or in an array constructor". If use in an
> array constructor was allowed, there would then need to be words to say
> what data type the constructor had, since BOZ constants have no type. I
> suppose one would then be required to add an explicit type-spec in the
> constructor.
>
> What you're asking for seems quite reasonable, but the language doesn't
> currently allow for it in a concise fashion. Feel free to propose this for
> "Fortran 2020" (or whatever it will be called.)
A nominally straightforward and backwards compatible way of providing
the desired functionality is to add a BIT data type to the language, and
have a BOZ literal definedd as a literal for a bit data type of the same
bit size as the largest sized integer provided by the processor. Then an
array of BOZ literal constants is an array of that kind of BIT type, so
it satisfies Fortran's array element consistency rules, and it can then
be used as an argument to the appropriate Fortran elemental procedures.

Unfortunately, of course, BIT types are so useful, but are provided in
many languages with many minor variations of syntax and semantics, that
you are liable to run into the bike sheding problem that has plagued
previous proposals.

Thomas Koenig

unread,
May 6, 2016, 6:55:17 AM5/6/16
to
herrman...@gmail.com <herrman...@gmail.com> schrieb:

> Hmmm, I just notice that there is no SELECTED_LOGICAL_KIND(), but there are
> KINDs for LOGICAL values.

It could actually make a strange kind of sense, at least to get the
LOGICAL kind which consumes the least amount of storage.

Unless you want a LOGICAL which can only hold .TRUE. ... that
certainly would save you a lot of memory.

robin....@gmail.com

unread,
May 6, 2016, 9:05:22 AM5/6/16
to
On Friday, May 6, 2016 at 8:55:17 PM UTC+10, Thomas Koenig wrote:
> h.no...@gmail.com <h.no...@gmail.com> schrieb:
>
> > Hmmm, I just notice that there is no SELECTED_LOGICAL_KIND(), but there are
> > KINDs for LOGICAL values.
>
> It could actually make a strange kind of sense, at least to get the
> LOGICAL kind which consumes the least amount of storage.
>
> Unless you want a LOGICAL which can only hold .TRUE.

Not much help there, unless you also want to store .FALSE. too. ;^)

> ... that certainly would save you a lot of memory.

That would save a negligible amount of memory unless you have huge arrays
of LOGICAL.

Steve Lionel

unread,
May 6, 2016, 9:49:22 AM5/6/16
to
On 5/5/2016 12:09 PM, herrman...@gmail.com wrote:
> Seems to me that this has, pretty much, the problem that I recently noted
> in another thread. Well, maybe not yet, but if instead:
>
> real(kind=xx), parameter :: bar(*) = [real(kind(xx))::z'0']
>
> where xx is presumably integer, and kind(xx) is an integer kind.
>
> (I think this isn't actually Steve's fault, but that he copied it and modified
> it from a previous post. But it does show how easy it is to do.)

Right, What I meant to type was:

real(kind=xx), parameter :: bar(*) = [real(kind=xx)::z'0']

Steve Lionel

unread,
May 6, 2016, 9:57:55 AM5/6/16
to
On 5/4/2016 7:00 AM, herrman...@gmail.com wrote:
> Hmmm, I just notice that there is no SELECTED_LOGICAL_KIND(), but there are
> KINDs for LOGICAL values.

What would you want to select on? Note that ISO_FORTRAN_ENV provides
LOGICAL_KINDS, an array of the supported kind numbers for logicals. If
you always wanted the smallest one, just use the first element of that
array.

Ron Shepard

unread,
May 6, 2016, 12:23:41 PM5/6/16
to
On 5/6/16 8:57 AM, Steve Lionel wrote:
> On 5/4/2016 7:00 AM, herrman...@gmail.com wrote:
>> Hmmm, I just notice that there is no SELECTED_LOGICAL_KIND(), but
>> there are
>> KINDs for LOGICAL values.
>
> What would you want to select on? Note that ISO_FORTRAN_ENV provides
> LOGICAL_KINDS, an array of the supported kind numbers for logicals. If
> you always wanted the smallest one, just use the first element of that
> array.

I've wondered if logical KIND values could also be used to distinguish
different conventions for .true. and .false.. For example, one KIND
might correspond to using the least significant bit 0 and 1, while
another KIND could correspond to the C convention of 0 for false and
nonzero for true, and another KIND could correspond to the integers -1
for true and zero for false. This would facilitate interoperability with
C and among fortran compilers, it would help detect KIND mismatches
between actual and dummy arguments, and if mixed-kind operations were
allowed, it would offload any conversions required onto the compiler
rather than the programmer. The main use for logical KIND values would
probably be to match the conventions used in various external libraries,
both in the number of bits and in the expected bit patterns.

$.02 -Ron Shepard

Steve Lionel

unread,
May 6, 2016, 12:31:11 PM5/6/16
to
On 5/6/2016 12:23 PM, Ron Shepard wrote:
> I've wondered if logical KIND values could also be used to distinguish
> different conventions for .true. and .false.. For example, one KIND
> might correspond to using the least significant bit 0 and 1, while
> another KIND could correspond to the C convention of 0 for false and
> nonzero for true, and another KIND could correspond to the integers -1
> for true and zero for false. This would facilitate interoperability with
> C and among fortran compilers, it would help detect KIND mismatches
> between actual and dummy arguments, and if mixed-kind operations were
> allowed, it would offload any conversions required onto the compiler
> rather than the programmer.

An intriguing notion. I'll observe that the current standard
"recommends" the C convention for LOGICAL. I'll also note that there
isn't really any useful interoperability among different Fortran
compilers but this is an important issue with C interoperability.

Yes, absolutely KIND values could be used for this purpose if an
implementation chose to do so. But I wonder how much use such a feature
would get instead of telling the compiler to always use the C convention
(if its default is otherwise.)

herrman...@gmail.com

unread,
May 6, 2016, 3:15:34 PM5/6/16
to
On Friday, May 6, 2016 at 3:55:17 AM UTC-7, Thomas Koenig wrote:

(I wrote)
> > Hmmm, I just notice that there is no SELECTED_LOGICAL_KIND(), but there are
> > KINDs for LOGICAL values.

> It could actually make a strange kind of sense, at least to get the
> LOGICAL kind which consumes the least amount of storage.

As far as I know, it is still required that default INTEGER, default REAL,
and default LOGICAL be the same size. It does seem that one might
sometimes want a smaller one, though on many machines access to larger
objects is more efficient.

> Unless you want a LOGICAL which can only hold .TRUE. ... that
> certainly would save you a lot of memory.

There are the stories that grandfathers tell there grandkids, one that they
used to walk to and from school every day, uphill both ways. The other is
that you now have both zeros and ones, in my day we only had zeros.

But I forget where the story came from.



herrman...@gmail.com

unread,
May 6, 2016, 3:24:00 PM5/6/16
to
On Friday, May 6, 2016 at 6:49:22 AM UTC-7, Steve Lionel wrote:

(snip, I wrote)
> > Well, maybe not yet, but if instead:
> >
> > real(kind=xx), parameter :: bar(*) = [real(kind(xx))::z'0']

> > where xx is presumably integer, and kind(xx) is an integer kind.

> > (I think this isn't actually Steve's fault, but that he copied it and modified
> > it from a previous post. But it does show how easy it is to do.)

> Right, What I meant to type was:

> real(kind=xx), parameter :: bar(*) = [real(kind=xx)::z'0']

I suppose, but my choice would be:

real(kind=xx), parameter :: bar(*) = [real(kind=kind(bar))::z'0']

But also, it seems that there should be a convenient way to say that you
want an initializer of the same kind (even if you have to give the type) of
that being initialized.

There might be some cases where the initializer is a different kind or type,
knowing that the conversion will be done, but that should be rare.

I could see a table of square roots truncated to integers, for example.

Steve Lionel

unread,
May 6, 2016, 4:24:38 PM5/6/16
to
On 5/6/2016 3:23 PM, herrman...@gmail.com wrote:
> I suppose, but my choice would be:
>
> real(kind=xx), parameter :: bar(*) = [real(kind=kind(bar))::z'0']

Referencing kind(bar) in the initialization would be allowed by the
current rules on constant expressions. Adding in a "you know what I
mean" rule would get messy, since the initialization expression is not
required to be the same type and kind as the entity being declared. Your
best hope in getting this capability added to the language is to make it
a natural extension of an existing feature, without having to invent new
semantics.

herrman...@gmail.com

unread,
May 6, 2016, 5:21:39 PM5/6/16
to
On Friday, May 6, 2016 at 1:24:38 PM UTC-7, Steve Lionel wrote:

(I wrote)
> > I suppose, but my choice would be:

> > real(kind=xx), parameter :: bar(*) = [real(kind=kind(bar))::z'0']

> Referencing kind(bar) in the initialization would be allowed by the
> current rules on constant expressions. Adding in a "you know what I
> mean" rule would get messy, since the initialization expression is not
> required to be the same type and kind as the entity being declared. Your
> best hope in getting this capability added to the language is to make it
> a natural extension of an existing feature, without having to invent new
> semantics.

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.)

Maybe:

real(kind=xx), parameter :: bar(*) = [ ::z'0']

where the empty type and kind before the :: implies the type and kind of the variable being
initialized. That might be true even if it wasn't directly obvious:

real(kind=xx), parameter :: bar(*) = sqrt([ ::z'0'])

or with an even more complicated expression.

I am not sure now, is mixed mode allowed for initializers?
That is, the constants specified have a different type, to be converted, as
they would be for assignment?

integer :: xxx(*) = sqrt([ 1.5, 2.5, 3.5])

or instead does one need:

integer:: xxx(*) = integer(sqrt([ 1.5, 2.5, 3.5]))

-- glen

Richard Maine

unread,
May 6, 2016, 5:57:04 PM5/6/16
to
<herrman...@gmail.com> wrote:

> On Friday, May 6, 2016 at 1:24:38 PM UTC-7, Steve Lionel wrote:
>
> (I wrote)
> > > I suppose, but my choice would be:
>
> > > real(kind=xx), parameter :: bar(*) = [real(kind=kind(bar))::z'0']
>
> > Referencing kind(bar) in the initialization would be allowed by the
> > current rules on constant expressions. Adding in a "you know what I
> > mean" rule would get messy, since the initialization expression is not
> > required to be the same type and kind as the entity being declared. Your
> > best hope in getting this capability added to the language is to make it
> > a natural extension of an existing feature, without having to invent new
> > semantics.
>
> 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 other options]

And you are back into the interpretation of things inside of the array
constructor being influenced by context outside of the constructor.
Anything along those lines is a minefield of mess. Not even worth tying
to list the potential messes. Even mentioning concepts like "variable
being initialized" gets messy. I'll ignore the fact that a parameter
isn't a variable at all, but that actually gets into the fact that you
have to *PRECISELY* define exactly what is meant in all possible cases -
not just the most trivial one.

I'd say that asking for something like that would kill any chance of the
proposal going anywhere. Take a minor convenience feature and burden it
with a drastic departure from a fundamental principle of the language
(that interpretation of an expression does not depend on context), and
you just killed the feature.

Ian Harvey

unread,
May 6, 2016, 6:33:45 PM5/6/16
to
On 2016-05-07 7:21 AM, herrman...@gmail.com wrote:
> On Friday, May 6, 2016 at 1:24:38 PM UTC-7, Steve Lionel wrote:
>
> (I wrote)
>>> I suppose, but my choice would be:
>
>>> real(kind=xx), parameter :: bar(*) = [real(kind=kind(bar))::z'0']
>
>> Referencing kind(bar) in the initialization would be allowed by the
>> current rules on constant expressions. Adding in a "you know what I
>> mean" rule would get messy, since the initialization expression is not
>> required to be the same type and kind as the entity being declared. Your
>> best hope in getting this capability added to the language is to make it
>> a natural extension of an existing feature, without having to invent new
>> semantics.
>
> 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']

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.

(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

What is the size of array?)

herrman...@gmail.com

unread,
May 6, 2016, 6:38:28 PM5/6/16
to
On Friday, May 6, 2016 at 2:57:04 PM UTC-7, Richard Maine wrote:

(snip)

> > 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 other options]

> And you are back into the interpretation of things inside of the array
> constructor being influenced by context outside of the constructor.
> Anything along those lines is a minefield of mess. Not even worth tying
> to list the potential messes. Even mentioning concepts like "variable
> being initialized" gets messy. I'll ignore the fact that a parameter
> isn't a variable at all, but that actually gets into the fact that you

Well, I get tired of "that thingy on the left of the equal sign", but yes.

> have to *PRECISELY* define exactly what is meant in all possible cases -
> not just the most trivial one.

> I'd say that asking for something like that would kill any chance of the
> proposal going anywhere. Take a minor convenience feature and burden it
> with a drastic departure from a fundamental principle of the language
> (that interpretation of an expression does not depend on context), and
> you just killed the feature.

OK, but it isn't context in the way it is usually used.

You would say that a function, for example, shouldn't be evaluated
differently based on where it is in an expression. Consider, though:


real(kind=xx) :: bar(*) = sqrt(1d0+int(sqrt(1+ [real(kind=*)::10, 20, 30])))

In this case, the * is the type and kind of bar, not affected by the fact
that it is inside a sqrt, int, sqrt.

Where some might want context sensitivity for a case like:

real(kind(1d0)) xxx=sqrt(1)

(which fails already due to 1 being integer, but then that is part of the question)

Not sure what to call it, it is a leap frog instead of the usual meaning of context.

I do note that Fortran allows the (*) dimension for initialized arrays. Again, the
convenience of not needing to make two things agree when one could change.

To be sure, note the problem with:

real(kind=xx) :: bar(*) = sqrt(1d0+int(sqrt(1+ [real(kind=kind(bar))::10, 20, 30])))

when someone might come along later, rename the bar variable, and create a
new variable named bar:

integer :: bar(3) = 3
real(kind=xx) :: bar2(*) = sqrt(1d0+int(sqrt(1+ [real(kind=kind(bar))::10, 20, 30])))

in the common case where the person working on the program isn't the one
who wrote it in the first place, and doesn't look carefully enough.

herrman...@gmail.com

unread,
May 6, 2016, 6:54:39 PM5/6/16
to
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.

> 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))

Richard Maine

unread,
May 6, 2016, 7:33:01 PM5/6/16
to
<herrman...@gmail.com> wrote:

> On Friday, May 6, 2016 at 2:57:04 PM UTC-7, Richard Maine wrote:
>
> (snip)
>
> > > 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 other options]
>
> > And you are back into the interpretation of things inside of the array
> > constructor being influenced by context outside of the constructor.
> > Anything along those lines is a minefield of mess. Not even worth tying
> > to list the potential messes. Even mentioning concepts like "variable
> > being initialized" gets messy. I'll ignore the fact that a parameter
> > isn't a variable at all, but that actually gets into the fact that you
>
> Well, I get tired of "that thingy on the left of the equal sign", but yes.

And suppose the constructor in question is in a subexpression whose type
isn't supposed to be the same as that thing on the left of the equals
sign? As I noted before, you are assuming the trivial case. Or suppose
an equals sign isn't involved at all? Or were you planning on
arbitrarily limiting this to assignments and initialization? No use as
an actual argument, for example? Array constructors can go lots of
places. You are going to do a special syntax that applies to only a
subset of them. Mess, mess, mess.

> OK, but it isn't context in the way it is usually used.

Sure seems exactly like it to me. In fact, I can't imagine what other
meaning you might have in mind. The context is the stuff in the
surrounding code outside of the item in question. This is the same
principle that says, for example, that 3.1415926535897932384 is a single
precision real literal independent of what context it appears in. If you
don't want to call it context, fine. That isn't a term used in the
standard; it just seems like an English term that acurately describes
the concept. But call it what you will, it is exactly the same
principle.

> You would say that a function, for example, shouldn't be evaluated
> differently based on where it is in an expression.

And this is any different? This is about an aray cunstructor being
evaluated diferently depending on where it is in an expression. You do
recall that the thing on the right of the equals sign is an expression,
Right? And that it doesn't need to be a trivial one.

> Not sure what to call it, it is a leap frog instead of the usual meaning
> of context.

Then use whatever word you want. That's the word I've always seen used
to describe this concept, but if you want to use a different word, that
doesn't change the fact that this is a fundamental principle of Fortran.

You know, I mentioned in my prior post that it would kill the proposal
to burden a simple convenience feature with such a drastic departure
from the way the language works. If this were an actual floor discussion
at a committee meeting, I'd guess that by now it would just have been
voted down. There have been cases of things like that in the past, where
the committee was receptive to what seemed like a simple proposal, but
the proposer couldn't seem to keep it simple and so the whole thing got
rejected.

Ian Harvey

unread,
May 6, 2016, 7:42:00 PM5/6/16
to
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.)

herrman...@gmail.com

unread,
May 6, 2016, 8:51:41 PM5/6/16
to
On Friday, May 6, 2016 at 4:33:01 PM UTC-7, Richard Maine wrote:

(regarding PARAMETER not being variable, I wrote)
> > Well, I get tired of "that thingy on the left of the equal sign", but yes.

> And suppose the constructor in question is in a subexpression whose type
> isn't supposed to be the same as that thing on the left of the equals
> sign? As I noted before, you are assuming the trivial case. Or suppose
> an equals sign isn't involved at all? Or were you planning on
> arbitrarily limiting this to assignments and initialization? No use as
> an actual argument, for example? Array constructors can go lots of
> places. You are going to do a special syntax that applies to only a
> subset of them. Mess, mess, mess.

Yes the suggestion was for initialization only.

> > OK, but it isn't context in the way it is usually used.

> Sure seems exactly like it to me. In fact, I can't imagine what other
> meaning you might have in mind. The context is the stuff in the
> surrounding code outside of the item in question. This is the same
> principle that says, for example, that 3.1415926535897932384 is a single
> precision real literal independent of what context it appears in. If you
> don't want to call it context, fine. That isn't a term used in the
> standard; it just seems like an English term that acurately describes
> the concept. But call it what you will, it is exactly the same
> principle.

One definition from Google for context:

"the parts of something written or spoken that immediately precede and
follow a word or passage and clarify its meaning."

> > You would say that a function, for example, shouldn't be evaluated
> > differently based on where it is in an expression.

> And this is any different? This is about an aray cunstructor being
> evaluated diferently depending on where it is in an expression. You do
> recall that the thing on the right of the equals sign is an expression,
> Right? And that it doesn't need to be a trivial one.

It is not immediately preceding or following.

In the case I showed, the SQRT and INT are evaluated based on their arguments,
as usual.

> > Not sure what to call it, it is a leap frog instead of the usual meaning
> > of context.

Since a common case is that you want something to have the type and kind
of the variable (or constant) being initialized, it seemed convenient to have
a way to say that.

In the usual (that Fortran doesn't have) context, an operator or function would be
evaluated based on the immediate context of that operator or function. It could
then propagate back through functions.

Mathematica will, for example, do:

N[Sqrt[2],1000000]

where N specifies that you want a numeric value, instead of a symbolic value,
and with in this case 1000000 decimal digits. It then propagates back to the Sqrt,
forcing it to evaluate to the required precision. You can nest functions, and it
will propagate as needed. In each case, from a function to its immediate argument.

In the leap frog case, there are intermediate functions that don't see the
outside type and kind, and evaluate as usual. The array constructor gets
the type and kind from that being initialized, not from the function that it
is used in.

> Then use whatever word you want. That's the word I've always seen used
> to describe this concept, but if you want to use a different word, that
> doesn't change the fact that this is a fundamental principle of Fortran.

> You know, I mentioned in my prior post that it would kill the proposal
> to burden a simple convenience feature with such a drastic departure
> from the way the language works. If this were an actual floor discussion
> at a committee meeting, I'd guess that by now it would just have been
> voted down. There have been cases of things like that in the past, where
> the committee was receptive to what seemed like a simple proposal, but
> the proposer couldn't seem to keep it simple and so the whole thing got
> rejected.

I suppose, but you know that hasn't stopped me before from commenting
on how something could be done, even knowing that it is way too late to
do it that way.

But the one Ian suggested, of having the type and kind of the thing being
initialized depend on the initialization value, probably makes more sense in
the usual use.

Richard Maine

unread,
May 6, 2016, 9:16:25 PM5/6/16
to
<herrman...@gmail.com> wrote:

> On Friday, May 6, 2016 at 4:33:01 PM UTC-7, Richard Maine wrote:

> One definition from Google for context:
>
> "the parts of something written or spoken that immediately precede and
> follow a word or passage and clarify its meaning."

Seems to me like that fits the use here. This is using parts of the code
(something written) that precede or follow the "passage" to clarify (or
even specify in this case) its meaning. One might quibble about the
"immediately" bit, but I'd say that wasn't a very good part of the
definition anyway unless you use "immediately" in a fairly broad sense,
in which case that part fits as well.

Avoiding contextual dependence means having the meaning clear from the
"passage" itself instead of depending on the parts that precede or
follow it.

campbel...@gmail.com

unread,
May 6, 2016, 9:18:04 PM5/6/16
to
Interesting to contemplate how we could have different true's in the one program. This would be modern Fortran!

William Clodius

unread,
May 6, 2016, 9:22:47 PM5/6/16
to
<herrman...@gmail.com> wrote:

> <snip>
> Maybe:
>
> real(kind=xx), parameter :: bar(*) = [ ::z'0']
>
> where the empty type and kind before the :: implies the type and kind of
> the variable being initialized. That might be true even if it wasn't
> directly obvious:
>
> real(kind=xx), parameter :: bar(*) = sqrt([ ::z'0'])
>
> or with an even more complicated expression.
> <snip>

There are languages that constrain the context of legal programs enough
that the type of the result can be consitently inferred, Ada comes to
mind as designed to enforce this. Fortran has never been one of those
languages. There are too many contexts where this can't be determined,
and trying to call out the special cases where this could be done would
result in an even messier and confusing standard.

Richard Maine

unread,
May 6, 2016, 10:05:44 PM5/6/16
to
<campbel...@gmail.com> wrote:

> On Saturday, May 7, 2016 at 2:23:41 AM UTC+10, Ron Shepard wrote:

> > I've wondered if logical KIND values could also be used to distinguish
> > different conventions for .true. and .false.....

> Interesting to contemplate how we could have different true's in the one
> program. This would be modern Fortran!

There's truth, and then there is truthiness. :-)

herrman...@gmail.com

unread,
May 7, 2016, 1:48:16 AM5/7/16
to
On Friday, May 6, 2016 at 7:05:44 PM UTC-7, Richard Maine wrote:

(snip, campble.. wrote)
> > Interesting to contemplate how we could have different true's in the one
> > program. This would be modern Fortran!

> There's truth, and then there is truthiness. :-)


OK, .TRUE., .TRUER., .TRUEST.

James Van Buskirk

unread,
May 7, 2016, 3:25:52 AM5/7/16
to
wrote in message
news:b334933e-84a8-4f91...@googlegroups.com...

> Interesting to contemplate how we could have different true's in the
> one program. This would be modern Fortran!

You could always do that with ifort. Just compile different files with
/fpscomp:logicals or /fpscomp:nologicals

robert....@oracle.com

unread,
May 7, 2016, 9:23:38 AM5/7/16
to
On Friday, May 6, 2016 at 3:33:45 PM UTC-7, Ian Harvey wrote:
>
> (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).

It is in paragraph 4 of Subclause 5.2 of the 16-007 draft.

>
> integer, parameter :: array(*) = 4
>
> What is the size of array?

The first sentence of the Conformance clause of the standard prohibits that statement from appearing in a standard conforming program. The explicit prohibition in 16-007 is better than the implicit prohibition.

Bob Corbett

Ian Harvey

unread,
May 7, 2016, 5:37:04 PM5/7/16
to
On 2016-05-07 11:23 PM, robert....@oracle.com wrote:
> On Friday, May 6, 2016 at 3:33:45 PM UTC-7, Ian Harvey wrote:
>>
>> (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).
>
> It is in paragraph 4 of Subclause 5.2 of the 16-007 draft.

Thanks - missed that one.

Dick Hendrickson

unread,
May 8, 2016, 12:21:29 PM5/8/16
to
That would make Fortran uniquer than most languages, possibly one of the
uniquest!

Dick Hendrickson

Gordon Sande

unread,
May 8, 2016, 12:45:36 PM5/8/16
to
Actually a logic of NO, MAYBE or YES has considerable technical merit.
There are
some quetions in logic that are awkward with 2 states but trivial with
3. I like
the use of ON, OFF and AS_IS for setting style overrides in FrameMaker
as an example
where 3 states greatly simplifies things.

Gary Scott

unread,
May 8, 2016, 4:49:35 PM5/8/16
to
well, yeah, but its easy enough to create a string of bits with any
meaning you want.

Thomas Koenig

unread,
May 8, 2016, 5:59:23 PM5/8/16
to

Terence

unread,
May 9, 2016, 5:47:37 AM5/9/16
to


"Gordon Sande" wrote:-
>Actually a logic of NO, MAYBE or YES has considerable technical merit.
>There are some quetions in logic that are awkward with 2 states but trivial
>with 3. I like the use of ON, OFF and AS_IS for setting style overrides in
>FrameMaker as an example where 3 states greatly simplifies things.

I remember we used one-byte integers, with the values of -1,0 and 1,
and heavy use of the conditional IF
IF (MATX(I,J)) label1, label2,label3
When Fortran didn't have IAND, IOR, IXOR or NOT as part of the inline
fuctionality.

herrman...@gmail.com

unread,
May 9, 2016, 6:03:33 PM5/9/16
to
On Sunday, May 8, 2016 at 2:59:23 PM UTC-7, Thomas Koenig wrote:

(snip, I wrote)

> > There are the stories that grandfathers tell there grandkids, one that they
> > used to walk to and from school every day, uphill both ways. The other is
> > that you now have both zeros and ones, in my day we only had zeros.

> > But I forget where the story came from.

> That may be

> http://dilbert.com/strip/1992-09-08

Close enough for me.

Also, reminds me of when typewriters didn't have 1 or 0 as you could
use l or O instead. That is, ell and oh.

-- glen

herrman...@gmail.com

unread,
May 9, 2016, 6:07:49 PM5/9/16
to
On Monday, May 9, 2016 at 2:47:37 AM UTC-7, Terence wrote:

(snip)

> I remember we used one-byte integers, with the values of -1,0 and 1,
> and heavy use of the conditional IF
> IF (MATX(I,J)) label1, label2,label3
> When Fortran didn't have IAND, IOR, IXOR or NOT as part of the inline
> fuctionality.

You mean arithmetic IF.

Reminds me of some manual that suggests not using Computed GOTO with
three or fewer entries, when arithmetic IF could be used, and should be faster.
0 new messages