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

What are the possible hurdles to enhanced "enum" functionality in Fortran?

574 views
Skip to first unread message

FortranFan

unread,
Mar 23, 2016, 4:43:25 PM3/23/16
to
From a language and compiler development point-of-view, putting aside any time/resource constraints, are there any fundamental issues with including an improved "enum" functionality in Fortran?

That is, from the language aspects of Fortran syntax, semantics, and taxonomy, is there an intrinsic problem that might preclude any enhancements beyond the facility for enum introduced in Fortran starting with the 2003 revision toward standard interoperability with C?

I would greatly appreciate any knowledgeable feedback on above.

I'm greatly interested in better support for "enum" types in Fortran. I would like to adopt many of the so-called "good coding practices" involving enum that are used regularly by my peer group within industry in languages such as C++, Python, Java, and Microsoft .NET. Listed below are a couple of examples in C++ that capture most of what I would like to do.

1. Intrinsic support for an integral type of "enum" which provides facilities toward improved code readability and some form of type safety. You will see in C++, I can do the following for working with days in a week:

--- begin code ---
#include <iostream>
using namespace std;

enum Days { Sunday = 0, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };

// main example
int main(void)
{

Days Today;
Today = Days::Wednesday; // Ok, and code reads much better too
//Today = 2; // Error, cannot convert from int to Days

switch ( Today )
{
case Days::Wednesday:
cout << "It's a Wednesday" << endl;
break;
case Days::Saturday:
case Days::Sunday:
cout << "It's a Weekend!" << endl;
break;
default: cout << "It's some other day." << endl;
}

return 0;

}
--- end code ---

It will be nice if I can do in Fortran:
--- begin pseudo code ---
module m
implicit none
private
enum, public :: Days !.. Not supported at present
enumerator :: Sunday = 0
enumerator :: Monday
enumerator :: Tuesday
enumerator :: Wednesday
enumerator :: Thursday
enumerator :: Friday
enumerator :: Saturday
end enum
end module m
program p
use m, only : Days
type(Days) :: Today
Today = Days%Tuesday
!Today = 2 !! Should not be allowed, no direct integer assignment to enum type
select case ( Today )
case ( Days%Tuesday )
print *, "It's a Tuesday!"
case ( Days%Saturday, Days%Sunday )
print *, "It's a weekend!"
case default
print *, "It's some other day!"
end select
stop
end program p
--- end pseudo code ---

Can anyone with deeper knowledge of Fortran and development for it think facilities along the above lines simply do not go with the language? If so, why? Note I'm not wedded to my invented syntax in the above pseudo snippet; it was just for illustration purposes. My interest is really in being to program in "modern" Fortran the kind of coding idioms involving "enum" that my peers have accepted as more readable and type-safe.

2. Better support for use of "enum" with object-oriented (OO) design. I would like to build on the above point and extend it to components for derived types so it can help me further in OO concepts involving class design, data packaging, information hiding, and so forth. Consider an example in C++ again where one can write a class for day of a week as follows:

--- begin code snippet ---
#include <iostream>
using namespace std;

class Day
{
public:

enum Days { Sunday = 0, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, InvalidDay };

// Constructors
Day(void);
Day(Days d);

// Overloaded assignment operator
Day& operator = (Days d);

// Overloaded comparison operator
bool operator== (const Days d) const;

// Accessor function
Days getDay(void) const;

private:

// Data member
Days m_day;
};

Day::Days Day::getDay(void) const
{
return m_day;
}

// Constructors
Day::Day(void) : m_day(Sunday) {}

Day::Day(Days _d) : m_day(_d) {}

// Assignment operator
Day& Day::operator= (Days _d)
{
m_day = _d;
return *this;
}

// Comparison operator
bool Day::operator== (const Days _d) const
{
return (m_day == _d);
}

// main example
int main(void)
{

Day Today;

Today = Day::Tuesday; // Ok, and code reads much better too
//Today = 2; // Error, cannot convert from int to Days

switch ( Today.getDay() )
{
case Day::Tuesday:
cout << "It's a Tuesday" << endl;
break;
case Day::Saturday:
case Day::Sunday:
cout << "It's a Weekend!" << endl;
break;
default: cout << "It's some other day." << endl;
}

return 0;
}
--- end code snippet ---

So I would like to be able to do in Fortran,

--- begin pseudo code snippet ---
module m
implicit none
private
type, public :: Day
private
enum, public :: Days ! Note how enum is "bound" to the type!
enumerator :: Sunday = 0
enumerator :: Monday
enumerator :: Tuesday
enumerator :: Wednesday
enumerator :: Thursday
enumerator :: Friday
enumerator :: Saturday
end enum
type(Days) :: m_day
contains
private
procedure, pass(this) :: assign_day
procedure, pass(this), public :: getDay
generic, public :: assignment(=) => assign_day
end type

contains
subroutine assign_day( this, SomeDay )
!.. Argument list
class(Day), intent(inout) :: this
type(Days), intent(in) :: SomeDay

this%m_day = SomeDay

end function assign_day

function getDay( this ) result( ThisDay )
!.. Argument list
class(Day), intent(in) :: this
!.. Function result
type(Days) :: ThisDay

ThisDay = this%m_day

end function getDay

end module m

program p
use m, only : Day !.. Note the compact use statement
type(Day) :: Today
Today = Day%Tuesday
select case ( Today%getDay() )
case ( Day%Tuesday )
print *, "It's a Tuesday!"
case ( Day%Saturday, Day%Sunday )
print *, "It's a weekend!"
case default
print *, "It's some other day!"
end select
stop
end program p
--- end pseudo code snippet ---

Again, are there any basic language and compiler development constraints that would prevent a future Fortran standard revision (Fortran 20XY beyond the one in progress Fortran 2015) from adopting support along the above lines? Note I am not asking about the time and effort it takes in getting any such change discussed and accepted by the standards committee and then to get it all documented in standard-speak and for compiler writers to get the features implemented.

Also, note I am not here to debate in general any of the limitations with using enum types in programming (I understand the pros and cons). Nor do I want to know any of the "virtues" of writing so-called simple, concise code with FORTRAN; I've supported many such programs and I know what they entail.

Instead I have a general interest in understanding better the hurdles that might hinder further evolution of the Fortran language and presently I'm pondering over the enum functionality. Is it mainly time and resource constraints? Or is there more to it than meets the eye?

Fortran 2003 introduced "ENUM, BIND(C)" keyword to encapsulate enumerators for interoperability with C and Fortran 2008 brought the TYPE statement for intrinsic types. In my simple-minded thinking, I see these as seeds that can grow into better support for enum. Since an "enum" type is a particular packaging of an integral type and the elements to do such packaging appear to be present in Fortran, I wonder if Fortran language can be extended to provide more "syntactic sugar" for coders.

Thank you for your attention,

Richard Maine

unread,
Mar 23, 2016, 6:18:21 PM3/23/16
to
FortranFan <pare...@gmail.com> wrote:

> Since an "enum" type is a particular packaging of an integral type...

That is not a given. In fact, it is the crux of one of the fundamental
questions - whether an enum should just be syntactic sugar for declaring
integers or whether an enum should be an actual type (I started to say a
"real" type, but that term just confuses things, so I went with
"actual"). See, for example, Ada. (Ok, my Ada proficiency is horrid; I
used to know a little bit of it, but that was long ago and I know less
now:-( But I think enums are actual types in Ada; that would sure fit
with general Ada philosophy.)

The current BIND(C) enum was emasculated to apply only to C largely
because of unhappiness with what a poor job it was. I voted to delete
the enum feature completely because of how poor it was (and I wasn't
alone), but there was pressure to make something for the C case, so the
BIND(C) version got left in as a compromise.

As an illustration of how poor the BIND(C) enum is, realize that the
only thing it does that is in any way special is that it picks a kind
that would match what the companion C processor would pick for the same
enumeration. But even though that's the only "useful" thing it does,
there is no direct way to extract that result. You have to do it
indirectly by inquiring about the kind of one of the enumerators, which
tends to make it look as though the randomly choosen enumerator is
something special. Note that you can't declare a variable to be of an
enum "type" (because there isn't an enum type). You have to indirectly
figure out what the integer kind is and then declare the variable to be
of that kind. As in the example in Note 4.65 of f2003

enum, bind(c)
enumerator :: red=4, blue=9
enumerator yellow
end enum

integer(kind(red)) :: x

Why kind(red) instead of one of the other colors? No reason; you just
have to choose one at random because there is no name for the
enumeration itself - just fo rthe individual enumerators.

Restricting the feature to the BIND(C) case at least left the door open
to having a "native" version that was not just syntactic sugar for a
bunch of integer named constants, and poor syntactic sugar at that in my
opinion.

The big question then is exactly what one would want for a native enum
facility. No, that's not a trivial detail to be dismissed. That's a
fundamental part of the specification, and one can't go much further
without answering that question first. Well, I should elaborate that a
single person answering it won't do either, no matter how emphatic that
person might be that his or her answer is the obvious only one. You have
to get at least a majority consensus on the answer. Therein lies the
rub.

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

FortranFan

unread,
Mar 23, 2016, 6:43:26 PM3/23/16
to
On Wednesday, March 23, 2016 at 6:18:21 PM UTC-4, Richard Maine wrote:

> ..
>
> The current BIND(C) enum was emasculated to apply only to C largely
> because of unhappiness with what a poor job it was. ..
>
> Restricting the feature to the BIND(C) case at least left the door open
> to having a "native" version that was not just syntactic sugar for a
> bunch of integer named constants, ..
>
> The big question then is exactly what one would want for a native enum
> facility. No, that's not a trivial detail to be dismissed. ..


Thanks much for your response. I understand it may not be trivial and that's the reason for my post. Let the past, especially with transpired with Fortran 2003, be in the past. Looking to the future, is it possible technically for the language to evolve further and offer the kind of facilities I'm interested in?

Or is it so complicated that it makes it virtually impossible for the language to offer any such benefits to coders? If so, why? That's what I would like to learn on enums.

Richard Maine

unread,
Mar 23, 2016, 7:13:43 PM3/23/16
to
In my opinion, there are no huge technical barriers. Just a matter of
agreeing in exactly what is wanted. And, of course, getting high enough
priority compared to other things on the "nice to do" list. That last
might be the biggest hurdle. Going from "nice to do" to "high enough
priority to actually happen" is non-trivial.

Looking back over your original post more carefully, I note that you
mostly seem to be arguing for what I'd call the enum as an actual type
as opposed to enum as syntactic sugar for integers. I had formerly
focused one one sentence of your post, which seemed to me to be talking
about enums as integers (which the BIND(C) ones are). But your code
examples look much more like enums as distinct types. I might note that
I agree with you on that.

Though I do see an odd remnant or two of enums as integers in your
example code. Why identify an integer value at all, as in your

enumerator :: Sunday = 0

Let the compiler implementation worry about the internal representation.

I also note your

enum, public :: Days !.. Not supported at present

Yes. Definitely. Or at least something of the sort. The lack of a name
for the enumeration is one of my (several) bitches about the current
ones. That one at least is pretty easily solved. I forget why something
like that didn't get in the BIND(C) ones.

Ian Harvey

unread,
Mar 23, 2016, 10:56:29 PM3/23/16
to
(For some reason eternal september has not picked up this thread.)

On Thursday, 24 March 2016 07:43:25 UTC+11, FortranFan wrote:
> From a language and compiler development point-of-view, putting aside any time/resource constraints, are there any fundamental issues with including an improved "enum" functionality in Fortran?
>
> That is, from the language aspects of Fortran syntax, semantics, and taxonomy, is there an intrinsic problem that might preclude any enhancements beyond the facility for enum introduced in Fortran starting with the 2003 revision toward standard interoperability with C?
...
I can't think of any "fundamental" reasons for why you couldn't introduce strongly typed enumerations, but it depends on the details. The syntax above also suggests capability that goes beyond just enumerators.

One incongruity that presents is that BIND(C) enumerations are just INTEGER named constants. Practically I think strongly typed Fortran enumerators would have to be their own unspecified, non-extensible type - I have toyed with the idea of enumerations being implemented via special non-intrinsic INTEGER kinds (each enumeration construct introducing a new kind value), but I think that gets too messy (how do you ensure each kind is unique across a program?). Perhaps the differentiation is that unnamed constructs declare integer enumerators (with BIND(C) being a special case of this), while named constructs declare a unique type.

(If I have the same source token sequence for an enum construct in two different scopes, does it declare the same enumerator type? The behaviour could be analogous to non-SEQUENCE/non-BIND(C) types versus SEQUENCE and BIND(C) types.)

Where I think much more complexity might lie from your examples is in the use of type names as a namespace qualifier (for both the case above, and also for the latter example that I elided, where you have an enumerator declaration nested inside a derived type). That is going into territory that is completely foreign to the current language. A derived type definition is its own scope, but what you can declare in that scope is very limited (components and parameters), and outside of that scope the identifiers of the components and type parameters are only accessible through objects of the type, not the type name. All other packaging of identifiers (including accessibility considerations) for consumption in non-host associated scopes in the language is done using modules.

Perhaps it is a simplistic example of what I am referring to, but if you currently have syntax such as `abc%xyz`, without having to think about it you know that `abc` is a data object. Fortran processors know that too, and they use that sort of hint to help classify identifiers and provide meaningful error messages when identifiers are used in inconsistent ways. (It is perhaps only tangentially relevant here, but the heritage of the language also means that in some cases use of an identifier determines the nature of an identifier.)

That doesn't mean that adding more namespace related aspects to types is impossible, but I think it very much increases the difficulty and complexity of detailed specification and implementation.

Strongly typed enumerators? Easy enough, depending on details. Types as namespaces/nested declarations in types? There might be dragons, I'd be nervous.

FortranFan

unread,
Mar 23, 2016, 11:03:58 PM3/23/16
to
On Wednesday, March 23, 2016 at 7:13:43 PM UTC-4, Richard Maine wrote:

> ..
>
> In my opinion, there are no huge technical barriers.

That is very helpful to know, thank you.

> .. Just a matter of
> agreeing in exactly what is wanted. And, of course, getting high enough
> priority compared to other things on the "nice to do" list. That last
> might be the biggest hurdle. Going from "nice to do" to "high enough
> priority to actually happen" is non-trivial.
> ..

Totally agree on this. So if there were technical barriers, I can only imagine how difficult it will be.

> Looking back over your original post more carefully, I note that you
> mostly seem to be arguing for what I'd call the enum as an actual type
> as opposed to enum as syntactic sugar for integers. I had formerly
> focused one one sentence of your post, which seemed to me to be talking
> about enums as integers (which the BIND(C) ones are). But your code
> examples look much more like enums as distinct types. I might note that
> I agree with you on that.
>

Yes, I'm indeed interested in enums as distinct types. Sorry for any confusion in my write-up, I do not claim to have anything close to a fully formed concept on this topic, let alone a proposal in ISO standard-speak on the matter.

I do think it will help this discussion greatly if you were to agree with the idea of enums as distinct types.


> Though I do see an odd remnant or two of enums as integers in your
> example code. Why identify an integer value at all, as in your
>
> enumerator :: Sunday = 0
>
> Let the compiler implementation worry about the internal representation.
>

Since the existing "ENUM, BIND(C)" facility in the current standard states, "An enumerator is a named integer constant," and because all the other languages I've worked with have enumerators as an integral type (often with added option to specify the kind and provide static casting to an integer), I figured any further development with enums in Fortran would (and should) follow suit. But all I really care about is being able to cast an enumerator to an integer at little to no cost (vice versa will be nice too!) since I have some use cases along those lines.

> I also note your
>
> enum, public :: Days !.. Not supported at present
>
> Yes. Definitely. Or at least something of the sort. The lack of a name
> for the enumeration is one of my (several) bitches about the current
> ones. That one at least is pretty easily solved. I forget why something
> like that didn't get in the BIND(C) ones.
>

Indeed I've wondered about the lack of an enumeration name ever since I first read about "ENUM, BIND(C)" in "Fortran 2003 Handbook" by Adams et al. Especially because C has had the name since ANSI C (1989). But I'm very glad to read you agree on this and you do think it "is pretty easily solved."

Note I'm open to any further expansion on the enum distinct type such as it being extensible (as suggested in another discussion) and having additional ordering facilities for enumerators and so forth. It's just that the two cases I show in the original post cover most of my immediate uses for enums.

Ian Harvey

unread,
Mar 23, 2016, 11:41:14 PM3/23/16
to
On 2016-03-24 2:03 PM, FortranFan wrote:
...
> Note I'm open to any further expansion on the enum distinct type such
> as it being extensible (as suggested in another discussion)...

Why would you want it to be an extensible type (if that is what is
meant)? Extension (inheritance) implies an "is a" relationship between
the extension type and the parent, and given one of the whole points to
an enumeration is to define a limited set of values, I don't think that
it makes much sense to say that some other type (with the possibility of
an infinite number of values) "is a" particular enumeration. What is it
that you want to specifically be able to inherit?

I could see a point to making an enumeration an extension type of the
intrinsic integer type.

Or are you talking about permitting one enumeration to extend the
possible values of another enumeration?

FortranFan

unread,
Mar 23, 2016, 11:57:47 PM3/23/16
to
On Wednesday, March 23, 2016 at 10:56:29 PM UTC-4, Ian Harvey wrote:

> (For some reason eternal september has not picked up this thread.)
>

Oops, sorry. I was using employer-issued computer today and can't use anything other than Google groups, wonder if that has something to do with it.

> ..
> I can't think of any "fundamental" reasons for why you couldn't introduce strongly typed enumerations, but it depends on the details. The syntax above also suggests capability that goes beyond just enumerators.
> ..

That's reassuring. Yes, beyond just enumerators is what I'd like, as in enums as distinct types.

> .. Perhaps the differentiation is that unnamed constructs declare integer enumerators (with BIND(C) being a special case of this), while named constructs declare a unique type.
> ..

That sounds good to me.

> ..
>
> Where I think much more complexity might lie from your examples is in the use of type names as a namespace qualifier .. That is going into territory that is completely foreign to the current language. ..

Is it really that foreign? Fortran has no explicit namespace concept (even though modules kinds serve as one) and thus no qualifier for it. I was thinking of parameterized derived types (PDTs) and how with Fortran 2008, one can do:

..
type foo_t(k)
integer, kind :: k = 4
integer(kind=k) :: i
..
end type foo_t
..
type(foo_t(k=8)) :: foo
type(integer(kind=foo%k)) :: bar
print *, foo%k, foo%i
..

then perhaps type(type(foo%i)) will be feasible too and if so, why not have the qualification aspects of enum and enumerator members be handled similarly with % delimiter? It may require "magic" by compiler writers hopefully it is nothing compared to PDTs and perhaps it even builds on it? I was also reluctant to suggest extra qualification syntax, thinking the whole concept would lose support and traction among readers because of that.

> .. where you have an enumerator declaration nested inside a derived type)...
>
> Strongly typed enumerators? Easy enough, depending on details. Types as namespaces/nested declarations in types? There might be dragons, I'd be nervous.

I really hope Fortran can ultimately offer some way for an enum declaration to be bound to a derived type which will make packaging OO classes in Fortran really neat. In my example, what I'm after is the consumer of the "Day" class to only require "use m, only : Day" statement to consume said class. That makes it compact and clean.

But I don't really know a compiler would handle it, hence my post.

What I wonder about is the fact that all the languages which find use similar to Fortran in numeric, technical, scientific, engineering computing space - C++, Python, Microsoft .NET, Java, etc. - offer far greater support for enums, especially with OO. And the use of enums with OO is well established. So it will be really beneficial if Fortran can do so too.


FortranFan

unread,
Mar 24, 2016, 12:14:11 AM3/24/16
to
On Wednesday, March 23, 2016 at 11:41:14 PM UTC-4, Ian Harvey wrote:

> On 2016-03-24 2:03 PM, FortranFan wrote:
> ...
> > Note I'm open to any further expansion on the enum distinct type such
> > as it being extensible (as suggested in another discussion)...
>
> Why would you want it to be an extensible type (if that is what is
> meant)? ..


Note I'm not saying extension is a must, but some kind of extension facility such as additional enumerators may be valuable:

module m
..
enum, public :: COLORS !.. Original developer thougt 3 colors would suffice
enumerator :: BLACK
enumerator :: WHITE
enumerator :: GRAY
end enum COLORS
..
end module m
module n
use m, only : COLORS
..
enum, extends(COLORS) :: MORE_COLORS ! but now the application is multicolored!
enumerator :: RED
enumerator :: GREEN
enumerator :: BLUE
..
end enum MORE_COLORS
..
end module n


Note features such as above seem to make sense and appear useful while they do not seem to conflict with the facilities of interest to me. So I would like to be open-minded about this, especially if it can help a broader group of coders in Fortran.

Gary Scott

unread,
Mar 24, 2016, 7:37:49 AM3/24/16
to
enum is just not sufficiently useful to warrant the clutter. bit string
is much much more fundamentally useful (if done right).

Richard Maine

unread,
Mar 24, 2016, 10:27:26 AM3/24/16
to
When I wrote the above, I was thinking about mentioning bit strings as a
particular case where a major problem is getting agreement on what
"right" would be. But I decided not to digress into that. :-)

FortranFan

unread,
Mar 24, 2016, 10:30:29 AM3/24/16
to
On Thursday, March 24, 2016 at 7:37:49 AM UTC-4, Gary Scott wrote:

> ..
> >
> enum is just not sufficiently useful to warrant the clutter. bit string
> is much much more fundamentally useful (if done right).


It needn't be an either/or facility with Enums and "bitstrings" in Fortran.

But here's what I notice around me: C++, Microsoft .NET, etc. are routinely becoming the basis for *big* programs in my industry and these languages effectively offer both options: enums and bitsets (BitArray, etc.). Yet when I go over the design and code for these *big* programs, I come across enums far more than bitsets. And whatever I've seen bitsets, it is not as though code is any less cluttered.

Fortran has intrinsic types, intrinsic functions, and intrinsic modules, and some intrinsic derived types (C_PTR is ISO_C_BINDING). For a long time now, I've been saying Fortran should also start offering intrinsic derived types with type-bound procedures, operators, and sd forth. VARYING_STRING type (discussed recently on this forum) and a bit type (similar to bitset in C++ STL) can be part of these intrinsic derived types.

But none of that should take anything away from the basic need for enum distinct type discussed here. This need remains and it is a vital part of modern programming idiom.

Ian Harvey

unread,
Mar 24, 2016, 3:46:45 PM3/24/16
to
On 2016-03-24 3:14 PM, FortranFan wrote:
> On Wednesday, March 23, 2016 at 11:41:14 PM UTC-4, Ian Harvey wrote:
>
>> On 2016-03-24 2:03 PM, FortranFan wrote: ...
>>> Note I'm open to any further expansion on the enum distinct type
>>> such as it being extensible (as suggested in another
>>> discussion)...
>>
>> Why would you want it to be an extensible type (if that is what is
>> meant)? ..
>
>
> Note I'm not saying extension is a must, but some kind of extension
> facility such as additional enumerators may be valuable:
>
> module m
> ..
> enum, public :: COLORS !.. Original developer thought 3 colors would suffice
> enumerator :: BLACK
> enumerator :: WHITE
> enumerator :: GRAY
> end enum COLORS
> ..
> end module m
> module n
> use m, only : COLORS
> ..
> enum, extends(COLORS) :: MORE_COLORS ! but now the application is multicolored!
> enumerator :: RED
> enumerator :: GREEN
> enumerator :: BLUE
> ..
> end enum MORE_COLORS
> ..
> end module n
>
> Note features such as above seem to make sense and appear useful
> while they do not seem to conflict with the facilities of interest to
> me. So I would like to be open-minded about this, especially if it
> can help a broader group of coders in Fortran.

Ok, as a feature that is reasonable - but note that ability to extend
the value set of an existing enumeration to create a new enumeration -
as proposed above - is very different from the existing language concept
of "a *type* being extensible" (F2008 1.3.147.6). I don't think a
suggestion that an enumeration *type* ought to be extensible makes much
sense.

In terms of the rules around type compatibility, I think it is the
opposite of what an extensible type implies.

As a parallel example to what you have above.

TYPE :: Animal
END TYPE :: Animal

TYPE, EXTENDS(Animal) :: Mammal
END TYPE Mammal

A procedure with a dummy argument of CLASS(Animal) can be associated
with an actual argument of TYPE(Mammal) - a Mammal is an Animal.

But in the enumeration case things are the other way around - a dummy
argument of type COLORS must not be associated with an actual argument
of type MORE_COLORS, else the procedure may receive values for the
enumeration that it does not understand.

FortranFan

unread,
Mar 24, 2016, 4:46:31 PM3/24/16
to
On Thursday, March 24, 2016 at 3:46:45 PM UTC-4, Ian Harvey wrote:

> .. very different from the existing language concept
> of "a *type* being extensible" (F2008 1.3.147.6). I don't think a
> suggestion that an enumeration *type* ought to be extensible makes much
> sense.
>
> ..
>
> A procedure with a dummy argument of CLASS(Animal) can be associated
> with an actual argument of TYPE(Mammal) - a Mammal is an Animal.
>
> But in the enumeration case things are the other way around - a dummy
> argument of type COLORS must not be associated with an actual argument
> of type MORE_COLORS, else the procedure may receive values for the
> enumeration that it does not understand.

Hmmm... this particular sub-thread might soon reach the usual "agree to disagree" stage.

In the use case I presented above, with "extends(COLORS)" in MORE_COLORS, the idea is enumerators in COLORS are inherited by MORE_COLORS, thus MORE_COLORS%BLACK becomes a valid enumeration and it will be related in some fashion to COLORS%BLACK (meaning they might yield the same result upon type conversion to an integer). Given this, I don't see any problem if the language can provide support along the following lines:

--- begin snippet ---
..
use m, only : COLORS
..
subroutine foo( .., c, ..)
..
class(COLORS) :: c
..
if (c == COLORS%BLACK) then
..
end if
..
end subroutine foo
..

type(MORE_COLORS) :: mc
..
mc = MORE_COLORS%GREEN
..
call foo( .., mc, ..) !.. ok, so the "if" instruction in foo won't be executed since enumerator has a different value, but no type mismatch issues otherwise
..

--- end snippet ---

It's too early to start discussing type extension in depth, but again I see possibility for some form of support, as illustrated above.

Ian Harvey

unread,
Mar 24, 2016, 5:21:02 PM3/24/16
to
On 2016-03-24 2:57 PM, FortranFan wrote:
> On Wednesday, March 23, 2016 at 10:56:29 PM UTC-4, Ian Harvey wrote:
>
>> (For some reason eternal september has not picked up this thread.)
>>
>
> Oops, sorry. I was using employer-issued computer today and can't
> use anything other than Google groups, wonder if that has something
> to do with it.

It has come through now - I suspect eternal september had issues.

>> .. I can't think of any "fundamental" reasons for why you couldn't
>> introduce strongly typed enumerations, but it depends on the
>> details. The syntax above also suggests capability that goes
>> beyond just enumerators. ..
>
> That's reassuring. Yes, beyond just enumerators is what I'd like, as
> in enums as distinct types.
>
>> .. Perhaps the differentiation is that unnamed constructs declare
>> integer enumerators (with BIND(C) being a special case of this),
>> while named constructs declare a unique type. ..
>
> That sounds good to me.
>
>> ..
>>
>> Where I think much more complexity might lie from your examples is
>> in the use of type names as a namespace qualifier .. That is going
>> into territory that is completely foreign to the current language.
>> ..
>
> Is it really that foreign? Fortran has no explicit namespace concept
> (even though modules kinds serve as one) and thus no qualifier for
> it. I was thinking of parameterized derived types (PDTs) and how
> with Fortran 2008, one can do:
>
> type foo_t(k)
> integer, kind :: k = 4
> integer(kind=k) :: i
> ..
> end type foo_t
> ..
> type(foo_t(k=8)) :: foo
> type(integer(kind=foo%k)) :: bar
> print *, foo%k, foo%i
>
> then perhaps type(type(foo%i)) will be feasible too and if so, why
> not have the qualification aspects of enum and enumerator members be
> handled similarly with % delimiter? It may require "magic" by
> compiler writers hopefully it is nothing compared to PDTs and perhaps
> it even builds on it? I was also reluctant to suggest extra
> qualification syntax, thinking the whole concept would lose support
> and traction among readers because of that.

foo, the thing that appears to the left of the `%`, is a data object in
the above, and the value of the type parameter is a property of that
object. You cannot currently write `foo_t%k`, or anything resembling
it.

Putting anything other than an object to the left of `%` is very new.

>> .. where you have an enumerator declaration nested inside a derived
>> type)...
>>
>> Strongly typed enumerators? Easy enough, depending on details.
>> Types as namespaces/nested declarations in types? There might be
>> dragons, I'd be nervous.
>
> I really hope Fortran can ultimately offer some way for an enum
> declaration to be bound to a derived type which will make packaging
> OO classes in Fortran really neat. In my example, what I'm after is
> the consumer of the "Day" class to only require "use m, only : Day"
> statement to consume said class. That makes it compact and clean.

I think you are looking at an extraordinary amount of work on language
specification and implementation, just to allow those who always want
ONLY clauses to continue to type more.

I think the better conceptual position with the language is to consider
the module to be the unit of consumption, not individual types (or
variables or procedures) defined in the module.

> But I don't really know a compiler would handle it, hence my post.
>
> What I wonder about is the fact that all the languages which find use
> similar to Fortran in numeric, technical, scientific, engineering
> computing space - C++, Python, Microsoft .NET, Java, etc. - offer far
> greater support for enums, especially with OO. And the use of enums
> with OO is well established. So it will be really beneficial if
> Fortran can do so too.

enums - fair enough. But this aspect is more about namespace
management, and I am far from convinced there's a material problem that
needs fixing in this area.

(That doesn't mean it is impossible to add hierarchical namespace
aspects to the language - I just think the cost/benefit of it very
questionable.)

Ian Harvey

unread,
Mar 24, 2016, 8:00:40 PM3/24/16
to
I'd very much want a compiler error for that case. `foo` cannot do
anything useful with the out of range value.

One of the reasons that type safety is a good thing is that it prevents
you supplying inappropriate input to a procedure or similar - if you
associate an object of type `animal` with an dummy of type `color`, the
compiler will tell you that you have a problem and protect you from your
own silliness.

You can extend that to "value safety" - if it does not make sense to
provide that value to a procedure, then if possible you want the
compiler to diagnose that.

The source describes the constraints that apply to the programmer's
model of the data, the compiler then helps to maintain the consistency
of that model by enforcing those constraints.

Again, I see this as an inversion of the way the type compatibility
rules work for type extension. If you have an polymorphic object of the
parent type that you think is of a particular extension type, then you
can use the SELECT TYPE construct (where appropriate - I agree with the
view that indiscriminate use of SELECT TYPE can indicate a code design
problem) to safely access the object as that extension type.

CLASS(Animal) :: x
...
SELECT TYPE (x)
CLASS IS (Mammal)
! Work here with x as a mammal.
END SELECT

If x is not a mammal, then no code expecting it to be a mammal is executed.

I could see the equivalent for enumerations (though whether it would be
worth doing is up for debate). Enumerations are fundamentally about
sets of values, so you could perhaps overload the existing construct
that deals with selection on the basis of value:

TYPE(MORE_COLOR) :: y
...
SELECT CASE (y)
CASE (COLOR) ! Use of enumeration name
! nominates the entire collection.
! Work here with y as a COLOR.
CASE DEFAULT
END SELECT

If the value of y is not in the set of values of COLOR, then no code
expecting it to be in the set of values of COLOR is executed.

William Clodius

unread,
Mar 24, 2016, 11:29:08 PM3/24/16
to
Note the concept of an enumeration defines a set of unique related named
values with assignment of the values to varaibles of the appropriate
ENUM type, and tests for equality. Often that is sufficient. However
sometimes it is desirable to specify relations between the identifiers.
For example the cyclic set Sunday, Monday, Tuesday, Wednesday, Thursday,
Friday, Saturday, with something like NEXT(Sunday)==Monday, and
PRECEDES(Sunday)==Saturday. Othertimes it is desirable to have a finite
ordered set: e.g., Top, Middle, Bottom, With Top > Middlle > Bottom.
More problematic, of course, are partially ordered sets.

William Clodius

unread,
Mar 24, 2016, 11:29:10 PM3/24/16
to
Ian Harvey <ian_h...@bigpond.com> wrote:

> On 2016-03-24 2:03 PM, FortranFan wrote:
> ...
> > Note I'm open to any further expansion on the enum distinct type such
> > as it being extensible (as suggested in another discussion)...
>
> Why would you want it to be an extensible type (if that is what is
> meant)? Extension (inheritance) implies an "is a" relationship between
> the extension type and the parent, and given one of the whole points to
> an enumeration is to define a limited set of values, I don't think that
> it makes much sense to say that some other type (with the possibility of
> an infinite number of values) "is a" particular enumeration. What is it
> that you want to specifically be able to inherit?
>
> I could see a point to making an enumeration an extension type of the
> intrinsic integer type.

In many way the integers are extensions of enumerations (distinct values
with the operations of assignment and equality), as they are distint
values with the operations of assignment, equality, greater than, less
than, plus, minus, etc.

FortranFan

unread,
Mar 25, 2016, 11:31:38 AM3/25/16
to
On Thursday, March 24, 2016 at 5:21:02 PM UTC-4, Ian Harvey wrote:

> ..
>
> I think you are looking at an extraordinary amount of work on language
> specification and implementation, just to allow those who always want
> ONLY clauses to continue to type more...
>
> enums - fair enough. But this aspect is more about namespace
> management, and I am far from convinced there's a material problem that
> needs fixing in this area.
>
> (That doesn't mean it is impossible to add hierarchical namespace
> aspects to the language - I just think the cost/benefit of it very
> questionable.)


Unless several different compiler developers can chime in and provide cogent explanations as to how enum%enumerator syntax can cause major implementation issues, I'm unable to buy any of the above arguments.

Regardless, as I made clear in my original post, I'm not attached to any of particular syntax indicated in my pseudo code snippets.

* if constructs such as Days%Tuesday shown in the snippet should really be a major hurdle, how about language support along the lines of Days(Tuesday)?

* since an enum is about a set of values and one can imagine it as being a 1-d array, my next position will be that an array index form of syntax is the next best thing a coder can relate to. So perhaps the language will adopt something along these lines then.

With this change, my first snippet will look like this:

--- begin pseudo code ---

module m
implicit none
private
enum, public :: Days !.. Not supported at present
enumerator :: Sunday = 0
enumerator :: Monday
enumerator :: Tuesday
enumerator :: Wednesday
enumerator :: Thursday
enumerator :: Friday
enumerator :: Saturday
end enum
end module m
program p
use m, only : Days
type(Days) :: Today

Today = Days(Tuesday) !.. Instead of Days%Tuesday

!Today = 2 !! Should not be allowed, no direct integer assignment to enum type
select case ( Today )
case ( Days(Tuesday) )
print *, "It's a Tuesday!"
case ( Days(Saturday:Sunday) ) !.. and/or Days(Saturday), Days(Sunday)
print *, "It's a weekend!"
case default
print *, "It's some other day!"
end select
stop
end program p

--- end pseudo code ---

As a coder, I seek some convenient facilities in Fortran as illustrated in this thread. In terms of syntax and semantics, I hope those more knowledgeable can help out in advancing the concept further in a manner that is consistent with rest of the language.

Whatever is adopted ultimately will hopefully be intuitive, at least to some extent, for coders. I feel C++ falls short in this aspect, I hope Fortran doesn't. But any such fear should not lead to paralysis and stop Fortran from gaining new facilities.

herrman...@gmail.com

unread,
Mar 25, 2016, 10:10:45 PM3/25/16
to

A little about how enum works in C, and maybe how BIND(C) enum works.

In C, the compiler chooses an integer type appropriate for the enum, most likely compilers always choose int, but the standard doesn't require that.

However, enum constants are always int, even if the corresponding enum variable isn't.

(Character constants, such as 'x', are also int, not char as you might expect.)
(Note that is different from C++.)

The C call by value, and expression promotion rules help here.
In a C expression, integer types smaller than int are promoted to int.

Seems that this could cause problems in Fortran subroutine arguments.

Richard Maine

unread,
Mar 25, 2016, 10:44:48 PM3/25/16
to
<herrman...@gmail.com> wrote:

> A little about how enum works in C, and maybe how BIND(C) enum works.
...
> However, enum constants are always int, even if the corresponding enum
> variable isn't.

Well, no that's not how BIND(C) enum works in Fortran. I realize (now
that you remind me, anyway) that C enums are like that, but BIND(C)
doesn't emulate that. In Fortran, as noted upthread, there is actually
no such thing as an enum variable, or for that matter an enum constant.
They are all integers - plain old ordinary integers with nothing
particularly special about them. And they act just like any other
integer.

And the enumerators (what one might call enum constants) are the
appropriate kind for the enum - not necessarily integer(C_INT). They are
most likely integer(C_INT) in practice, but the standard doesn't say
that. In fact, as mentioned before, the only way to find the kind is to
inquire about the kind of one of the constants.

This all for the BIND(C) enums currently in the language - not
necessariy for some hypothesized future eother sort of enums in Fortran.

herrman...@gmail.com

unread,
Mar 28, 2016, 9:45:39 PM3/28/16
to
On Friday, March 25, 2016 at 7:44:48 PM UTC-7, Richard Maine wrote:


(snip, I wrote)

> > A little about how enum works in C, and maybe how BIND(C) enum works.

> > However, enum constants are always int, even if the corresponding enum
> > variable isn't.

> Well, no that's not how BIND(C) enum works in Fortran. I realize (now
> that you remind me, anyway) that C enums are like that, but BIND(C)
> doesn't emulate that. In Fortran, as noted upthread, there is actually
> no such thing as an enum variable, or for that matter an enum constant.
> They are all integers - plain old ordinary integers with nothing
> particularly special about them. And they act just like any other
> integer.

Seems to me that could cause problems calling from C to Fortran or
Fortran to C.

Well, they are integers in C, too, which could be char or short or int.

But the compilers I know of use int for enum variables, so most often
the problem doesn't come up.

> And the enumerators (what one might call enum constants) are the
> appropriate kind for the enum - not necessarily integer(C_INT). They are
> most likely integer(C_INT) in practice, but the standard doesn't say
> that. In fact, as mentioned before, the only way to find the kind is to
> inquire about the kind of one of the constants.

One reason it isn't a problem in C, is that you can't pass a
pointer to a constant to a called function. Passed by value, they will
all be int (before any other conversions that are done).

I presume you can use an enum constant (you can call it something
else) to a called subroutine, or BIND(C) function.

> This all for the BIND(C) enums currently in the language - not
> necessariy for some hypothesized future eother sort of enums in Fortran.

Yes.



Richard Maine

unread,
Mar 28, 2016, 9:58:25 PM3/28/16
to
<herrman...@gmail.com> wrote:

> On Friday, March 25, 2016 at 7:44:48 PM UTC-7, Richard Maine wrote:
>
>
> (snip, I wrote)
>
> > > A little about how enum works in C, and maybe how BIND(C) enum works.
>
> > > However, enum constants are always int, even if the corresponding enum
> > > variable isn't.
>
> > Well, no that's not how BIND(C) enum works in Fortran. I realize (now
> > that you remind me, anyway) that C enums are like that, but BIND(C)
> > doesn't emulate that. In Fortran, as noted upthread, there is actually
> > no such thing as an enum variable, or for that matter an enum constant.
> > They are all integers - plain old ordinary integers with nothing
> > particularly special about them. And they act just like any other
> > integer.
>
> Seems to me that could cause problems calling from C to Fortran or
> Fortran to C.

Lots of things can be problems.

Regardless, that is the way it is. I was more interested in correcting
the facts than in discussing the reasons (assumimg I recalled the
reasons well enough to discuss them, which isn't a given on this one.)

Wolfgang Kilian

unread,
Mar 29, 2016, 4:08:45 AM3/29/16
to
On 23.03.2016 21:43, FortranFan wrote:
> From a language and compiler development point-of-view, putting aside any time/resource constraints, are there any fundamental issues with including an improved "enum" functionality in Fortran?
>
> That is, from the language aspects of Fortran syntax, semantics, and taxonomy, is there an intrinsic problem that might preclude any enhancements beyond the facility for enum introduced in Fortran starting with the 2003 revision toward standard interoperability with C?
>
> I would greatly appreciate any knowledgeable feedback on above.
>
> I'm greatly interested in better support for "enum" types in Fortran. I would like to adopt many of the so-called "good coding practices" involving enum that are used regularly by my peer group within industry in languages such as C++, Python, Java, and Microsoft .NET. Listed below are a couple of examples in C++ that capture most of what I would like to do.
>
> 1. Intrinsic support for an integral type of "enum" which provides facilities toward improved code readability and some form of type safety. You will see in C++, I can do the following for working with days in a week:

I often find myself using INTEGER parameters as enumerators (as
discussed in a recent thread). Type safety for such objects would be a
welcome enhancement to the language. The existing BIND(C) enumerators
don't provide that, their use case is almost non-existing.

I don't see a strong point in a component (ENUM_TYPE%ENUM_VAL) syntax.
I'd rather avoid that. The enumerator values are the possible
*instances* of the enumerator type, they are not components. I'd go
just with the individual names of the enum values, i.e.,

enum, public :: my_enum_t
enumerator :: my_enum_val1
...
end enum

subroutine do_something (mode)
type(my_enum_t), intent(in) :: mode
select case (mode)
case (my_enum_val1)
...
case default
...
end select
end subroutine

One would like to have the enum value names unique within scope, anyway.
No need for new concepts of namespace, etc.

> [...]


> 2. Better support for use of "enum" with object-oriented (OO) design. I would like to build on the above point and extend it to components for derived types so it can help me further in OO concepts involving class design, data packaging, information hiding, and so forth. Consider an example in C++ again where one can write a class for day of a week as follows:

I don't think that is necessary. Enumerators (i.e., their values) are
meant to be used within SELECT CASE (but not SELECT TYPE). It would be
natural to allow the operations that make sense in that context, namely:

* assignment and argument association, but only between enumerator
values of the same type.
* test for equality and inequality
* test for ordered values (< > <= >=). One might allow this only with
an ORDERED attribute in the enum declaration.
* as a potential benefit, a compiler test whether the SELECT CASE is
exhaustive. That is not available for integers or characters.

I don't see any need for user-defined operations. I don't see a strong
case for extensions of an enumerator type, either. Maybe, EXTENDS
could extend the range of allowed values ... but nothing else.

There must be I/O support. In formatted I/O, enumerators would most
likely be written/read as integers - - one could restrict that to
default integer kind to keep it simple. It's probably impossible to
keep type or value safety in I/O.

Otherwise, I would prohibit *any* relation between enumerators and
integers. No integer values in the declaration, no assignment or
argument association. Such a relation should be exclusive to BIND(C)
enumerators. If interoperability with integers is really desired
(debugging, etc.), there is always TRANSFER.

>
> Again, are there any basic language and compiler development constraints that would prevent a future Fortran standard revision (Fortran 20XY beyond the one in progress Fortran 2015) from adopting support along the above lines? Note I am not asking about the time and effort it takes in getting any such change discussed and accepted by the standards committee and then to get it all documented in standard-speak and for compiler writers to get the features implemented.
>
> Also, note I am not here to debate in general any of the limitations with using enum types in programming (I understand the pros and cons). Nor do I want to know any of the "virtues" of writing so-called simple, concise code with FORTRAN; I've supported many such programs and I know what they entail.
>
> Instead I have a general interest in understanding better the hurdles that might hinder further evolution of the Fortran language and presently I'm pondering over the enum functionality. Is it mainly time and resource constraints? Or is there more to it than meets the eye?
>
> Fortran 2003 introduced "ENUM, BIND(C)" keyword to encapsulate enumerators for interoperability with C and Fortran 2008 brought the TYPE statement for intrinsic types. In my simple-minded thinking, I see these as seeds that can grow into better support for enum. Since an "enum" type is a particular packaging of an integral type and the elements to do such packaging appear to be present in Fortran, I wonder if Fortran language can be extended to provide more "syntactic sugar" for coders.
>
> Thank you for your attention,

I recall that there have been proposals of that kind, which were voted
down because they did introduce too many additional concepts.

A lean ENUM facility, different from BIND(C), would be most useful with
little danger of syntax/semantic ambiguities.

-- Wolfgang

--
E-mail: firstnameini...@domain.de
Domain: yahoo

Ian Harvey

unread,
Mar 29, 2016, 5:14:01 PM3/29/16
to
On 2016-03-29 7:08 PM, Wolfgang Kilian wrote:
...
> I don't see any need for user-defined operations. I don't see a strong
> case for extensions of an enumerator type, either. Maybe, EXTENDS
> could extend the range of allowed values ... but nothing else.
>
> There must be I/O support. In formatted I/O, enumerators would most
> likely be written/read as integers - - one could restrict that to
> default integer kind to keep it simple. It's probably impossible to
> keep type or value safety in I/O.

What about defined input/output for enumeration types? I can see a use
case for mapping from an enumerator value to and from a certain
character string.

If the type (versus the value range) was not extensible - using the
current language terminology for extensible here, then that could be
provided by stand-alone Fortran 95 style generic interfaces. But there
is the nuisance factor that their accessibility doesn't follow the
identifier for the type.

Wolfgang Kilian

unread,
Mar 30, 2016, 5:39:08 AM3/30/16
to
On 29.03.2016 23:13, Ian Harvey wrote:
> On 2016-03-29 7:08 PM, Wolfgang Kilian wrote:
> ...
>> I don't see any need for user-defined operations. I don't see a strong
>> case for extensions of an enumerator type, either. Maybe, EXTENDS
>> could extend the range of allowed values ... but nothing else.
>>
>> There must be I/O support. In formatted I/O, enumerators would most
>> likely be written/read as integers - - one could restrict that to
>> default integer kind to keep it simple. It's probably impossible to
>> keep type or value safety in I/O.
>
> What about defined input/output for enumeration types? I can see a use
> case for mapping from an enumerator value to and from a certain
> character string.

That's what logicals map from/to ... and I remember strange bugs due to
a string that accidentally had a 'T' as first letter being read as
.true. (the I/O list was wrong, of course). I have the feeling that
there is no really good solution. In any case, a simple thing such as
an enumerator should have built-in provisions for all common use cases
including I/O, and I'd be fine if there were no user-serviceable parts
inside. But it would be a possible application of the UDDTIO facility,
which might be underrated (also by myself).

>
> If the type (versus the value range) was not extensible - using the
> current language terminology for extensible here, then that could be
> provided by stand-alone Fortran 95 style generic interfaces. But there
> is the nuisance factor that their accessibility doesn't follow the
> identifier for the type.

Yes. Often, the enum object is uniquely stored inside a derived type
(or one could introduce a wrapper type anyway), for which the usual
rules apply.

FortranFan

unread,
Mar 30, 2016, 9:45:46 AM3/30/16
to
On Tuesday, March 29, 2016 at 4:08:45 AM UTC-4, Wolfgang Kilian wrote:

> ..
>
> I don't see a strong point in a component (ENUM_TYPE%ENUM_VAL) syntax.
> I'd rather avoid that. The enumerator values are the possible
> *instances* of the enumerator type, they are not components. I'd go
> just with the individual names of the enum values, ..
>
> One would like to have the enum value names unique within scope, anyway.
> No need for new concepts of namespace, etc.
>
> ..

If I am understanding the statements such as above correctly, they seem to override the very needs I have expressed and if so, I find it rather worrisome for they betray a lack of understanding and concern for the needs of fellow Fortran coders. Is this how the Fortran community wants to go about evolving the language?

I ask what issues or problems might ensue if a more inclusive capability of the kind I seek is included in the language; as I said, let us not be concerned by non-technical matters at this stage; any time and resource constraints of vendors. No one has raised any technical, language-related concerns thus far. So from a strict language facility point-of-view, what exactly is to be gained by a 'lean' feature if that were to leave coders like me in the lurch?

I feel I have explained repeatedly my reason for a syntax like ENUM_TYPE%ENUM_VAL or ENUM_TYPE(ENUM_VAL) which is to be able to resolve ambiguities with non-unique enum values and to make the code clearer to read. Standard bearers of other languages have long understood this and provided solutions - see link below for Ada, I only mention it because I have heard some on the committee look kindly to features in Ada, but that pointing out anything in C++ (scoped enums, etc.) won't go down too well for whatever reason: http://www.radford.edu/~nokie/classes/320/typesnotes/enum6.adb.html

In the absence of a built-in facility in the language to deal with non-unique enum values, the coder is forced to do so by modifying the enum value (e.g., add a particular prefix to the name) which is totally unnecessary in this day and age.

Some of my code works at the interface between engineering, science, and math and some terms such as ELEMENT, FACTOR, NODE, NORMAL, UNIT have different meanings in different contexts, they will be enum values, and I will indeed have non-unique enum values in the same scope. As I indicated earlier, Ada to C++, C# to Java, Python to Visual Basic easily provide facilities to coders to handle such situations. I think it's high time Fortran did too.

So is the Fortran committee going to view the matter similarly as this other post should they consider this aspect again, that they will only imagine ghosts and dragons lurking around every corner, and seek to include a 'lean', perhaps a watered down version compared to those in other competing languages (even Ada 95) which will be a marginal improvement over the utterly useless facility in the current standard and which will be of little service to coders like me? That would hardly be 'modern'.

Ian Harvey

unread,
Mar 30, 2016, 8:43:20 PM3/30/16
to
On 2016-03-31 12:45 AM, FortranFan wrote:
> On Tuesday, March 29, 2016 at 4:08:45 AM UTC-4, Wolfgang Kilian
> wrote:
>
>> ..
>>
>> I don't see a strong point in a component (ENUM_TYPE%ENUM_VAL)
>> syntax. I'd rather avoid that. The enumerator values are the
>> possible *instances* of the enumerator type, they are not
>> components. I'd go just with the individual names of the enum
>> values, ..
>>
>> One would like to have the enum value names unique within scope,
>> anyway. No need for new concepts of namespace, etc.
>>
>> ..
>
> If I am understanding the statements such as above correctly, they
> seem to override the very needs I have expressed and if so, I find it
> rather worrisome for they betray a lack of understanding and concern
> for the needs of fellow Fortran coders. Is this how the Fortran
> community wants to go about evolving the language?

On the other hand, if someone wants a strongly typed enumeration with
the enumerator identifiers at module scope, consistent with how all
other identifiers work in the language, then your proposal overrides
their "needs".

> I ask what issues or problems might ensue if a more inclusive
> capability of the kind I seek is included in the language; as I said,
> let us not be concerned by non-technical matters at this stage; any
> time and resource constraints of vendors. No one has raised any
> technical, language-related concerns thus far. So from a strict
> language facility point-of-view, what exactly is to be gained by a
> 'lean' feature if that were to leave coders like me in the lurch?
>
> I feel I have explained repeatedly my reason for a syntax like
> ENUM_TYPE%ENUM_VAL or ENUM_TYPE(ENUM_VAL) which is to be able to
> resolve ambiguities with non-unique enum values and to make the code
> clearer to read. Standard bearers of other languages have long
> understood this and provided solutions - see link below for Ada, I
> only mention it because I have heard some on the committee look
> kindly to features in Ada, but that pointing out anything in C++
> (scoped enums, etc.) won't go down too well for whatever reason:
> http://www.radford.edu/~nokie/classes/320/typesnotes/enum6.adb.html

I think `(` and `)` are already excessively overloaded in the language
(basic statement syntax, function references, implied-do's, array
subscripting, substring subscripting...), to the point that it
compromises source readability, error diagnostics and the ability to
further extend the language. Adding another overload will make that
situation worse.

The confusion that results from overloading of syntax for markedly
different operations is the primary reason that I am not in favour of
using a single `%` token for some sort of namespace resolution
operation. Learn from other mistakes made in the language, and pick
something else!

A habit I picked up from C++ (and source documentation tools with a C++
heritage) was to use `::` to separate module name from module identifier
in documentation. I have moved away from this in the last year or two
(i.e. I do not recommend this token either) because, similarly, `::`
itself already has several uses in the language, most of which have
something to do with "declaring" things, which hasn't got much to do
with namespace resolution.

As long as the syntax isn't a confusing overload of something existing I
really don't care what you choose, but simply as an example of unique
alternatives my current pick for documentation is a new token of `%%`.

You seek technical reasons above - I know my own personal Fortran
semantic analysis code would need substantial revision to deal with
overloading `( )` for namespace resolution, or (to a lesser extent)
overloading `%`. Compared with an alternative of some other unique
token, the overload options represent all cost and no benefit to me.

> In the absence of a built-in facility in the language to deal with
> non-unique enum values, the coder is forced to do so by modifying the
> enum value (e.g., add a particular prefix to the name) which is
> totally unnecessary in this day and age.

Only if the identifiers for the enumerator are initially declared in the
same scope (and declaring conflicting enumerator identifiers in the same
scope seems like a silly thing to want to do). If the conflict occurs
where one of the identifiers introduced through use association, then
the existing built-in facility of renaming in the use statement can be used.

> Some of my code works at the interface between engineering, science,
> and math and some terms such as ELEMENT, FACTOR, NODE, NORMAL, UNIT
> have different meanings in different contexts, they will be enum
> values, and I will indeed have non-unique enum values in the same
> scope. As I indicated earlier, Ada to C++, C# to Java, Python to
> Visual Basic easily provide facilities to coders to handle such
> situations. I think it's high time Fortran did too.

That situation is not limited to the identifiers for enumerators though.
This is another reason why I do not think a proposal for additional
support for enumerations should be bundled so tightly with this new
namespace concept. They are fundamentally two different animals.

Solely to contrast, because I think the merits of additional namespace
facilities in Fortran may be marginal, if you want additional namespace
facilities, then why not explicitly bring them in. Perhaps something like:

MODULE my_module
IMPLICIT NONE
INTEGER, PARAMETER :: another_constant = 2
NAMESPACE my_namespace
! Public entities of some_other_module accessible through
! this namespace.
USE some_other_module

! Host association of another_constant into this scope.
INTEGER, PARAMETER :: some_constant = another_constant

! perhaps here a declaration for some_enumeration,
! whatever form that might take.

TYPE :: some_type
...
END TYPE some_type

INTERFACE some_generic
PROCEDURE some_procedure
END INTERFACE some_generic

NAMESPACE child_namespace
! Go forth and nest...
END NAMESPACE child_namespace
END NAMESPACE my_namespace

! Qualification required out of the namespace construct.
TYPE(my_namespace%%my_type) :: some_variable
CONTAINS
! For specific procedures, perhaps we have to qualify the
! name, or perhaps the NAMESPACE construct has a CONTAINS
! statement and a subprogram part, or whatever...
SUBROUTINE my_namespace%%some_procedure
END SUBROUTINE my_namespace%%some_procedure
END MODULE

! Namespace entities brought in along with all other
! module entities, but the namespace entities require
!
USE my_module
PRINT *, my_namespace%%some_constant

! Bring in entities in the namespace only, with
! qualification still required.
USE my_module, ONLY: my_namespace
PRINT *, my_namespace%%some_constant

! Bring in entities in the namespace, renaming
! the namespace
USE my_module, local_name => my_namespace
PRINT *, local_name%%some_constant

! Bring in entities from the given namespace only,
! qualification no longer required. (perhaps this
! is abuse of a USE statement, and some separate
! source construct should be devised to achieve
! this - also you may want to eliminate the need for
! qualification in situations where you are not
! acquiring the namespace through USE).
USE my_module%%my_namespace
PRINT *, some_constant

Because you have unique syntax for namespace qualification, I think it
may be possible to put namespace names in their own class in 16.3.1,
permitting a namespace name to be the same as another local identifier
for something other than a namespace in the same scope. But that is the
sort of thing that would require careful consideration, as would the
impact of being able to eliminate the need for qualification in other
scopes.

> So is the Fortran committee going to view the matter similarly as
> this other post should they consider this aspect again, that they
> will only imagine ghosts and dragons lurking around every corner, and
> seek to include a 'lean', perhaps a watered down version compared to
> those in other competing languages (even Ada 95) which will be a
> marginal improvement over the utterly useless facility in the current
> standard and which will be of little service to coders like me? That
> would hardly be 'modern'.

One aspect to note is that it is difficult to eliminate the possibility
of ghosts and dragons until you have a more detailed proposal.

Recent language history also shows that sometimes when people try and
actually implement new language features in Fortran processors, dragons
do emerge.

FortranFan

unread,
Mar 31, 2016, 2:01:12 AM3/31/16
to
On Wednesday, March 30, 2016 at 8:43:20 PM UTC-4, Ian Harvey wrote:

> On 2016-03-31 12:45 AM, FortranFan wrote:
> .. I find it
> > rather worrisome for they betray a lack of understanding and concern
> > for the needs of fellow Fortran coders. Is this how the Fortran
> > community wants to go about evolving the language?
>
> On the other hand, if someone wants a strongly typed enumeration with
> the enumerator identifiers at module scope, consistent with how all
> other identifiers work in the language, then your proposal overrides
> their "needs".
>

Sheer nonsense: I'm constantly trying to convey a 'wider tent' philosophy and I suggest and support the inclusion of a broader set of capabilities in each aspect of the language evolution so they can help a larger number of Fortran coders with their needs.

I brought up the Ada example specifically keeping in mind that 'someone' who wants module scope because, in my simple-minded thinking and limited understanding, Ada seems to show how a language might support both, that when there is no ambiguity, a direct reference to enum value (e.g., Blue) is Ok but otherwise it asks to qualify by enum type e.g., Color'(Blue). I've made it clear I only seek the flexibility to do the latter, never did I mean to suggest the language should not support the former. It's up to standard bearers to decide how the feature should be put together with due consideration to syntax and semantic foundations of the language.


> ..
>
> I think `(` and `)` are already excessively overloaded ..
> As long as the syntax isn't a confusing overload of something existing I
> really don't care what you choose, but simply as an example of unique
> alternatives my current pick for documentation is a new token of `%%`.
>

Looks ok, I too indicated in the very beginning I'm flexible with the syntax.

> You seek technical reasons above - I know my own personal Fortran
> semantic analysis code would need substantial revision to deal with
> overloading `( )` for namespace resolution, or (to a lesser extent)
> overloading `%`. Compared with an alternative of some other unique
> token, the overload options represent all cost and no benefit to me.
> ..

See above, I'm open to any and all suggestions - ENUM_TYPE.ENUM_VAL, ENUM_TYPE%%ENUM_VAL, etc. I just hope Fortran helps me get past the name conflicts I'm going to have with enumerators, something the standard bearers of other languages easily foresaw and who provided easy means to get around them.

> ..
>
> That situation is not limited to the identifiers for enumerators though.
> This is another reason why I do not think a proposal for additional
> support for enumerations should be bundled so tightly with this new
> namespace concept. ..
>
> Because you have unique syntax for namespace qualification, I think it
> may be possible to put namespace names in their own class in 16.3.1,
> ..

The important need here is to be able to address the aspect of non-unique names of enumerators in a scope, perhaps it is best to leave it at that in this thread.

> ..
>
> One aspect to note is that it is difficult to eliminate the possibility
> of ghosts and dragons until you have a more detailed proposal.

Makes little sense in the context of enums; I can appreciate the concerns if one were discussing some feature introduction regarding PGAS programming involving coarrays, etc. which may still be advancing from a computer science point-of-view..

>
> Recent language history also shows that sometimes when people try and
> actually implement new language features in Fortran processors, dragons
> do emerge.

Hope those involved with the advancement of Fortran have learned from recent history and can to do better and more and faster now.


Wolfgang Kilian

unread,
Mar 31, 2016, 5:21:16 AM3/31/16
to
I'm not a member of the committee, and everything I say is just my
personal opinion.

Fortran already has several distinct namespace-like concepts, among them
procedures, modules, blocks ... there may be more. The F2003 standard
contains a design decision that derived types (aka classes in other OO
languages) do not act as namespaces in the sense that PUBLIC, PROTECTED
and PRIVATE attribute refer to module scope, not to type/class scope.
One may like this decision or not, but I would prefer not to add
additional namespace-like concepts.

A namespace resolution operator (say %%) could be useful, but I would
tie this to importing identifiers from USEd modules. Such a facility
might help for code clarity in general.

Identical names for distinct objects within a single scope (even in
different scopes!) should be avoided by the programmer, even if the
language allows this. The Ada example that you quote is a simple
illustration; imagine that the code context might be some 1000s of
lines. If conflicts arise via USE, there is already a renaming option.

So, what about enumerators? From my understanding of C, this is a very
low-level concept. I think of enumerator values as the possible
(singleton) instances of an abstract enumerator class. The idea is that
the allowed instances are enumerated completely at the point of
declaration, such that, ideally, a programmer can rely on the
completeness of this set. The facility was obviously inherited by C++,
where it allows the programmer to interoperate with C code, and to
bypass classes and hierarchies when there is no inherent functionality
associated with the class.

In the context of Fortran, this concept makes also sense. It would add
to the basic building blocks. It would not compete with higher-level
constructs such as derived types or modules.

As I said, other programmers with a different background might come to
different conclusions.

Wolfgang Kilian

unread,
Mar 31, 2016, 5:55:56 AM3/31/16
to
Regarding this particular problem, I see two solutions
(1) rename if conflicting names are imported via USE (possible today)
(2) introduce a qualifier syntax like module_name%%module_entity in
Fortran (nice to have).

I would keep this tied to modules and allow the qualifier syntax for all
entities where it makes sense. Enumerator value names should be treated
as ordinary names.

Bálint Aradi

unread,
Apr 6, 2016, 3:08:07 AM4/6/16
to
> (2) introduce a qualifier syntax like module_name%%module_entity in
> Fortran (nice to have).
>
> I would keep this tied to modules and allow the qualifier syntax for all
> entities where it makes sense. Enumerator value names should be treated
> as ordinary names.

+1 for this. Having something like

module colors
implicit none

integer, parameter :: green = 1

end module colors


program test_colors
use, namespace(colors) :: colors

if (mycolor == colors%green) then
...
end if

end program test

would be very useful IMO.

michael siehl

unread,
Apr 8, 2016, 7:48:07 AM4/8/16
to
|+1 for this. Having something like
|
|module colors
| implicit none
|
| integer, parameter :: green = 1
|
|end module colors
|
|
|program test_colors
| use, namespace(colors) :: colors
|
| if (mycolor == colors%green) then
| ...
| end if
|
|end program test
|
|would be very useful IMO.


We can emulate such a enumeration-like coding since Fortran 9x already, like this:

MODULE Enumerations
!*** Colors Enumeration:
TYPE, PUBLIC :: DontUse1
INTEGER :: Blue ! = 1
INTEGER :: Red ! = 2
INTEGER :: Green ! = 3
END TYPE DontUse1
!
TYPE (DontUse1), PUBLIC, PARAMETER :: EnumColors = DontUse1 (1,2,3)
!***
END MODULE Enumerations

PROGRAM Main
USE Enumerations
!
INTEGER :: MyColor = EnumColors%Green
!
IF (MyColor == EnumColors%Green) THEN
WRITE(*,*) 'MyColor is Green'
END IF
!
END PROGRAM Main

Best Regards

michael siehl

unread,
Apr 8, 2016, 10:19:44 AM4/8/16
to
...and, to make that 'enumeration' more safe to use, you could choose somewhat more unique integer values for it, like that:

TYPE (DontUse1), PUBLIC, PARAMETER :: EnumColors = DontUse1 (157839,230972,387150)

FortranFan

unread,
Apr 8, 2016, 4:07:37 PM4/8/16
to
On Friday, April 8, 2016 at 10:19:44 AM UTC-4, michael siehl wrote:

> ...and, to make that 'enumeration' more safe to use, you could choose somewhat more unique integer values for it, like that:
>
> TYPE (DontUse1), PUBLIC, PARAMETER :: EnumColors = DontUse1 (157839,230972,387150) ..


@michael siehl,

Is your intent simply to illustrate to some of the readers, who may not be aware of Fortran 90 and its features, a way to use named constants that make code a bit easier to read?

Or are you pretty much trying to negate the whole discussion of this thread? That is, are you trying to suggest based on how you go about emulating this with a Fortran 90 type of feature that no further improvement in the Fortran language is necessary and that the kind of facilities I seek, as explained in the original post, are not needed?


michael siehl

unread,
Apr 8, 2016, 8:09:52 PM4/8/16
to
|@michael siehl,
|
|Is your intent simply to illustrate to some of the readers, who may not be |aware of Fortran 90 and its features, a way to use named constants that make |code a bit easier to read?

Hi,
indeed, that was my intention. Nothing else.

BTW, the examples DontUse1 Type should be PRIVATE with today compilers, but I believe to remember that Fortran 95 compilers (back in the 1990s) did require this to be PUBLIC. Thus, I still leave this PUBLIC.

Best Regards

Bálint Aradi

unread,
Apr 11, 2016, 3:29:17 AM4/11/16
to
Am Freitag, 8. April 2016 13:48:07 UTC+2 schrieb michael siehl:
> |+1 for this. Having something like
> |
> We can emulate such a enumeration-like coding since Fortran 9x already, like this:
>
> MODULE Enumerations
> !*** Colors Enumeration:
> TYPE, PUBLIC :: DontUse1
> INTEGER :: Blue ! = 1
> INTEGER :: Red ! = 2
> INTEGER :: Green ! = 3
> END TYPE DontUse1
> !

I agree, that is indeed possible, thanks for the example. My excitement was actually more on the idea of having general namespaces in Fortran, especially, if one could assign the namespace when importing a module. But, that discussion would belong into a different thread, I guess.

Bálint
0 new messages