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

What I would like to see in Fortran 201x - I: Standardized Module Format

755 views
Skip to first unread message

Richard Weed

unread,
Jun 18, 2016, 11:02:54 PM6/18/16
to

I would like to start a dialog on what people like me (a long time
Fortran user developing codes for computational fluid and structural
dynamics applications) would like to see in the next iteration of
Fortran. In particular, I want to discuss what I think is missing
from Fortran that would make my programming life a lot easier if
implemented from a user standpoint (as opposed to a compiler
developer and/or member of the standards committee). Some of the
topics I intend to cover in separate posts are:

1. The need for a standard module and submodule format to allow
interoperability between modules compiled with different
compilers

2. The need for an intrinsic ADT facility that supports lists, queues,
trees etc. (I know this has been discussed before at some length
but I would like to put forward my ideas on how I would like to
see them implemented)

3. The need for an intrinsic linear algebra facility that defines
standard intrinsic types for matricies (dense and sparse) and standard
interfaces with meaningful procedure names and not the abbreviated
mess that is LAPACK (the implementation is still left to the compiler
developers, I just want interfaces that will work with any linear
algebra package in a standard way) to the most common linear algebra
tasks (LU factorization, solving systems of equations, finding
eigenvalues and eigenvectors condition numbers, matvecs, etc.)

4. Some things that I think should have been in the previous standards but
for some reason were left out or rejected by the standards committee.


I'll start with the need for a standard format for modules and submodules. I ran into this problem yesterday when I tried to use a version of PLplot I installed via software manager on my Linux Mint system with some code I compiled with the Intel compiler. I was trying to use the Fortran 90 interfaces so of course when I tried to USE plplot I got errors. Obviously, I could download PLplot and build an Intel specific version but my point is, why should I have to. I tried first to use an old version of PLplot I had compiled with Intel but after several OS upgrades etc. some of the shared object files needed were no longer found. If there was a standard format (it could be in addition to the existing compiler specific format but selected by a compiler flag say -fiso-module-format) I wouldn't have to waste time building PLplot. I could just use whats available and not worry about which compiler was used to build the third-party library (as long as the .o files are compatible - which is the case with Intel and gcc on Linux).

So my questions to the user community (and compiler developers and standards committee folks) are.

1. Do others see the need for a standard module format that is interoperable
between compilers (at least on Linux/Unix/BSD)
2. Has this been proposed in the past to the standards committees and if so
why was it rejected
3. I realize this probably doesn't have a snowballs chance of being implemented
but if it was I would like to hear from others on possible issues that
would prevent it from being implemented

I'll post my ideas on subjects 2-4 in separate posts

RW

herrman...@gmail.com

unread,
Jun 18, 2016, 11:47:53 PM6/18/16
to
On Saturday, June 18, 2016 at 8:02:54 PM UTC-7, Richard Weed wrote:
> I would like to start a dialog on what people like me (a long time
> Fortran user developing codes for computational fluid and structural
> dynamics applications) would like to see in the next iteration of
> Fortran.

(snip)

> 1. The need for a standard module and submodule format to allow
> interoperability between modules compiled with different
> compilers

Most often, you can't mix object files from different compilers, so there
isn't much reason for this.

If you only do I/O from one, it has a chance to work.

For C, it usually works. C has a simpler calling sequence, and simpler I/O routines,
which are called directly. One C library can be called, usually, but the output of
different compilers.

But there is no standard on the calls a Fortran object program makes to its library to
do I/O, and it isn't likely that there ever will be one.

The calling sequence used for traditional external routines might be similar between
compilers, but the calling sequence for module routines, even if the .MOD format was
compatible, is likely different.

Beliavsky

unread,
Jun 18, 2016, 11:59:19 PM6/18/16
to
On Saturday, June 18, 2016 at 11:02:54 PM UTC-4, Richard Weed wrote:
> I would like to start a dialog on what people like me (a long time
> Fortran user developing codes for computational fluid and structural
> dynamics applications) would like to see in the next iteration of
> Fortran.

<SNIP>

> 3. The need for an intrinsic linear algebra facility that defines
> standard intrinsic types for matricies (dense and sparse) and standard
> interfaces with meaningful procedure names and not the abbreviated
> mess that is LAPACK (the implementation is still left to the compiler
> developers, I just want interfaces that will work with any linear
> algebra package in a standard way) to the most common linear algebra
> tasks (LU factorization, solving systems of equations, finding
> eigenvalues and eigenvectors condition numbers, matvecs, etc.)

Matran http://www.cs.umd.edu/~stewart/matran/Matran.html does some of this.

campbel...@gmail.com

unread,
Jun 19, 2016, 1:59:37 AM6/19/16
to
As a user, my pet like would be that the INTERFACE structure be more developed.

In the present design, the interface definition and the routine are a duplicate of the routines interface. This duplication of code is wrong and I would like to see the INTERFACE defined in a module, which can be USEd in the routine, as the definition of the interface. In this way we could have a "USE all_interfaces" that could provide routine checking throughout the code, without all the mess that is there at present.

I consider a failing of the present INTERFACE design is that the INTERFACE is a duplication of the routine than can not be checked by the compiler.

In the early 90's, I actually tried this approach by duplicating the interface code in a module, only to find this approach was illegal. At the least it should have been allowed and checked for inconsistencies. It also acts as a useful documentation file, which can be checked when compiled with new code introduced into a developing project.

It does not have to be a necessary coding approach, but unlike as it is at present, it should be an allowed coding approach.

campbel...@gmail.com

unread,
Jun 19, 2016, 2:04:53 AM6/19/16
to
On Sunday, June 19, 2016 at 3:59:37 PM UTC+10, campbel...@gmail.com wrote:
>
> It does not have to be a necessary coding approach, but unlike as it is at present, it should be an allowed coding approach.

I should have stated that "unlike as I UNDERSTAND it is at present", as I have never since tried to assemble the interface definition file. There could always be some new clause I have not yet noticed!

Ian Harvey

unread,
Jun 19, 2016, 4:02:21 AM6/19/16
to
On 2016-06-19 1:02 PM, Richard Weed wrote:
>
> I would like to start a dialog on what people like me (a long time
> Fortran user developing codes for computational fluid and structural
> dynamics applications) would like to see in the next iteration of
> Fortran. In particular, I want to discuss what I think is missing
> from Fortran that would make my programming life a lot easier if
> implemented from a user standpoint (as opposed to a compiler
> developer and/or member of the standards committee). Some of the
> topics I intend to cover in separate posts are:
>
> 1. The need for a standard module and submodule format to allow
> interoperability between modules compiled with different compilers

As Glen notes, you need to worry about object file compatibility too,
other processor dependencies such as kind values, plus the
continuing evolution of the language.

A highly interoperable and extensible format between compilers already
exists - it is the source code.

> 2. The need for an intrinsic ADT facility that supports lists,
> queues, trees etc. (I know this has been discussed before at some
> length but I would like to put forward my ideas on how I would like
> to see them implemented)

Why do these need to be intrinsic facilities?

> 3. The need for an intrinsic linear algebra facility that defines
> standard intrinsic types for matricies (dense and sparse) and
> standard interfaces with meaningful procedure names and not the
> abbreviated mess that is LAPACK (the implementation is still left to
> the compiler developers, I just want interfaces that will work with
> any linear algebra package in a standard way) to the most common
> linear algebra tasks (LU factorization, solving systems of equations,
> finding eigenvalues and eigenvectors condition numbers, matvecs,
> etc.)

As above, why does it need to be an intrinsic facility?

Intrinsic stuff pretty much means that support has to be in the compiler
itself. Changing compilers is relatively difficult, expensive and slow.

The list of wants above reads to me as if you just want a different
library or different interface to existing libraries. Anyone can write
Fortran libraries - it would seem to be easier, cheaper and faster to
write such a library, either in isolation or in collaboration with others.

(There is a big difference between "the language should provide better
support for libraries", versus "the language should provide these
specific libraries".)

> 4. Some things that I think should have been in the previous
> standards but for some reason were left out or rejected by the
> standards committee.
>
>
> I'll start with the need for a standard format for modules and
> submodules. I ran into this problem yesterday when I tried to use a
> version of PLplot I installed via software manager on my Linux Mint
> system with some code I compiled with the Intel compiler. I was
> trying to use the Fortran 90 interfaces so of course when I tried to
> USE plplot I got errors. Obviously, I could download PLplot and build
> an Intel specific version but my point is, why should I have to. I
> tried first to use an old version of PLplot I had compiled with Intel
> but after several OS upgrades etc. some of the shared object files
> needed were no longer found. If there was a standard format (it could
> be in addition to the existing compiler specific format but selected
> by a compiler flag say -fiso-module-format) I wouldn't have to waste
> time building PLplot. I could just use whats available and not worry
> about which compiler was used to build the third-party library (as
> long as the .o files are compatible - which is the case with Intel
> and gcc on Linux).

Intel and gfortran have very different Fortran runtime libraries -
linking together their object files isn't going to work in the general case.

In selecting a distribution you are effectively selecting a system
compiler. If you want to use a different compiler to that system
compiler, then you are going beyond what a distribution supports.

To highlight - imagine if you decided to use a different C compiler, one
that had chosen different bit sizes for int, long, etc to your system
compiler. You are effectively creating a new distribution at that point.

Within a compiler family you don't have compatible module file formats,
or, in quite a few cases, object file formats.

Stefano Zaghi

unread,
Jun 19, 2016, 5:36:00 AM6/19/16
to
Dear Ian, I disagree with you on ADT.

>> 2. The need for an intrinsic ADT facility that supports lists,
>> queues, trees etc. (I know this has been discussed before at some
>> length but I would like to put forward my ideas on how I would like
>> to see them implemented)

>Why do these need to be intrinsic facilities?

There are many cases where ADT is helpful, to cite just one I could say that re-invent the wheel is a bad programming approach. List/tree of abstract, etherogeneous data is very very helpful (in my peculiar work for adaptive mesh refinement): having a builtin intrinsic list or tree is convenient as having arrays. Do you think that arrays facilities can be cinvenient trimmed out from built-ins and left to external libraries?

>Intrinsic stuff pretty much means that support has to be in the compiler
itself. Changing compilers is relatively difficult, expensive and slow.

Well, if this is a valid reasonFortran sould be never evolved and we should program wjrth F66. Yes, writing a compiler is a difficult task this is the reason why I am not able to do... fortunately the world is plenty of programmers smarter than me :-)

>The list of wants above reads to me as if you just want a different
library or different interface to existing libraries. Anyone can write
Fortran libraries - it would seem to be easier, cheaper and faster to
write such a library, either in isolation or in collaboration with others.

Writing a library for an ADT list is possible (we done), but is not easier, nor cheaper, neiter faster than having an instrinsic list as we have intrinsic array, e.g. python offer builtin ADT list, it is easy, cheap and fast. As the standard as introduced new types in decades, there is not relevant problems why the standard cannot define a list, I guess that "class(*)" should have been a similar big problem at that time.

>(There is a big difference between "the language should provide better
support for libraries", versus "the language should provide these
specific libraries".)

Why list should be considered "type B" container (that must be left outside builtins) with respect array that being "type A" container has the "grant" to be builtin?


Surely I think that array is the most important container: doing calculations, I use arrays 90% of time, so why the rest 10% of coding (where data structures are not simple arrays) should take my 90% of work for re-inventing the wheel?

My best regards.

Ian Harvey

unread,
Jun 19, 2016, 7:31:52 AM6/19/16
to
On 2016-06-19 7:35 PM, Stefano Zaghi wrote:
> Dear Ian, I disagree with you on ADT.
>
>>> 2. The need for an intrinsic ADT facility that supports lists,
>>> queues, trees etc. (I know this has been discussed before at some
>>> length but I would like to put forward my ideas on how I would
>>> like to see them implemented)
>
>> Why do these need to be intrinsic facilities?
>
> There are many cases where ADT is helpful, to cite just one I could
> say that re-invent the wheel is a bad programming approach. List/tree
> of abstract, etherogeneous data is very very helpful (in my peculiar
> work for adaptive mesh refinement): having a builtin intrinsic list
> or tree is convenient as having arrays. Do you think that arrays
> facilities can be cinvenient trimmed out from built-ins and left to
> external libraries?

I'm not questioning their usefulness, I'm questioning why they have to
be intrinsic.

What would an intrinsic list offer over a library solution?

What are the special requirements on the compiler that you need for this
list support? Are you after list specific syntax? Is "I am a list" a
fundamental attribute of an object - permitting it to be a
characteristic used for procedure resolution and the like? (If yes to
either of those two - what specific sort of list are you talking about?
Are you differentiating a singly linked list from doubly linked? Does
the list store values or by reference? Is the implementation optimised
for navigation or for mutation?)

Those aspects are part of the inclusion of arrays as a pretty
fundamental built-in feature of the language.

>> Intrinsic stuff pretty much means that support has to be in the
>> compiler
> itself. Changing compilers is relatively difficult, expensive and
> slow.
>
> Well, if this is a valid reason Fortran sould be never evolved and we
> should program wjrth F66. Yes, writing a compiler is a difficult task
> this is the reason why I am not able to do... fortunately the world
> is plenty of programmers smarter than me :-)

Something that is difficult, expensive and slow may still be worth doing
if the benefit from doing that thing exceeds the cost of doing it.

When you have multiple plausible methods of achieving an outcome, you
don't just look at the cost versus benefit of a single method in
isolation, you also look at the relativities between methods, so that
you reasonably expect to deliver the most (or the required) benefit for
the least cost.

>> The list of wants above reads to me as if you just want a different
>>
> library or different interface to existing libraries. Anyone can
> write Fortran libraries - it would seem to be easier, cheaper and
> faster to write such a library, either in isolation or in
> collaboration with others.
>
> Writing a library for an ADT list is possible (we done), but is not
> easier, nor cheaper, neiter faster than having an instrinsic list as
> we have intrinsic array, e.g. python offer builtin ADT list, it is
> easy, cheap and fast. As the standard as introduced new types in
> decades, there is not relevant problems why the standard cannot
> define a list, I guess that "class(*)" should have been a similar big
> problem at that time.

CLASS(*) addressed a distinct capability gap in the language - before it
was introduced there were things that you simply could not do in
standard Fortran (store or reference runtime arbitrary type objects).
There would undoubtedly have been a very material cost associated with
adding that feature to the language, but all alternatives addressing
that capability gap would have required language changes. Your options
start to look more like "do or do not" at that stage.

That situation doesn't apply to writing and using a list (or other data
structure) in Fortran today, because you *can*, without anything
approaching an impractical amount of effort, write and use lists in
modern Fortran right now.

(In terms of "using" today, I am putting aside issues around compiler
support for the current standard. There is obviously no point adding
more stuff to the language in an attempt to deal with incomplete or
buggy implementations of what has already been put into the language.)

If you already have standard source code for a generic list, the cost of
using that existing code is going to be pretty nominal for yourself and
anyone that you share the code with. The cost of agreeing on and
specifying such a list in a standard, followed by actually building it
into multiple compilers would be enormous (being holistic about cost
here - including time considerations - a solution that I can rely on
today is better than one I might be able to use in a decade).

That's not to say that there isn't substantial room for improvement in
how the language supports things like generic data structures, I could
rant for days about that, but that is not the same thing as actually
building specific data structures into the base language.

I recall some proverb from school that went something like "Give a
programmer a new intrinsic type and you keep them happy for a day, teach
their language how to support generic libraries and keep them happy for
a lifetime", but I might have that wrong - too busy fishing to pay
attention.

> Why list should be considered "type B" container (that must be left
> outside builtins) with respect array that being "type A" container
> has the "grant" to be builtin?
>
> Surely I think that array is the most important container: doing
> calculations, I use arrays 90% of time, so why the rest 10% of coding
> (where data structures are not simple arrays) should take my 90% of
> work for re-inventing the wheel?

But you (or some other third party) only write your generic list thing
once, right? And then you just re-use it.

(Code re-use (whether it is my code I am re-using, or someone else's
code - doesn't matter) is critical to programmer productivity, but I
think ease of code re-use is one of Fortran's biggest weaknesses.)

You have to draw the line somewhere. Python's design criteria are quite
different from those of the standard Fortran language, so its author
will have made different trade-offs in selecting which capabilities are
intrinsic, which facilities are provided by standard libraries, and what
things will be left to external libraries.

I'd be sympathetic to some sort of effort towards "here is a standard
for a Fortran library that supports various generic data structures" (a
bit like ISO_VARYING_STRING was), but not for making the stuff inside
that library intrinsic.

Anton Shterenlikht

unread,
Jun 19, 2016, 9:15:00 AM6/19/16
to
Richard Weed <rwee...@gmail.com> writes:


> I would like to start a dialog on what people like me (a long time
>Fortran user developing codes for computational fluid and structural
>dynamics applications) would like to see in the next iteration of
>Fortran. In particular, I want to discuss what I think is missing
>from Fortran that would make my programming life a lot easier if=20
>implemented from a user standpoint (as opposed to a compiler
>developer and/or member of the standards committee). Some of the

I will not comment on the techincal issues raised, but only on
engaging with the Fortran standardisation committee.

I'm a member of WG5, the ISO Fortran standardisation committee.
I just participated (6-10-JUN-2016) in my first J3/WG5
joint meeting (WG5 delegates all actual standard writing work to J3,
the USA fortran standardisation committee). The committee are
actively seeking participation of people like you - Fortran
users looking ahead. There are many ways you can engage with
the committee - through the official mailing lists
(check j3-fortran.org or http://www.nag.co.uk/sc22wg5 ),
through
https://www.jiscmail.ac.uk/cgi-bin/webadmin?A0=comp-fortran-90
which is read my many people on the committee, and via
participation in the J3 meetings (3 times a year) or annual WG5
meetings.
If you are in the UK, you can also partcipate in the annual
BCS Fortran group meetings (http://www.fortran.bcs.org), which
are attended by WG5 members. There are probably other ways too.

As far as I know, the committee members (and perhaps others too),
can submit formal papers with suggestions, corrections, etc,
which will have to be discussed at the committee. If there is
broad support for a new feature in principle, there will be
an action on some sub-committee (e.g. HPC, DATA) to prepare
an edit to the standard implementing the feature. If the feature
is very large it will likely be implemented as a TS (technical
specification), which will be edited separately, and will be
merged into the standard later.

More experienced WG5/J3 members will correct me, if I made
mistakes describing the procedure.

Anton

Stefano Zaghi

unread,
Jun 19, 2016, 9:15:50 AM6/19/16
to
Dear Ian,

>I'm not questioning their usefulness, I'm questioning why they have to
be intrinsic.

Yes, I would like to have the possibility to use list like I ude array, I want list as intrinsic container.

>What would an intrinsic list offer over a library solution?

Much like having an intrinsic array over having a library array: dedicated syntax, methods, operators... hopefully more robust and efficient than a library.

>What are the special requirements on the compiler that you need for this
list support? Are you after list specific syntax? Is "I am a list" a
fundamental attribute of an object - permitting it to be a
characteristic used for procedure resolution and the like? (If yes to
either of those two - what specific sort of list are you talking about?
Are you differentiating a singly linked list from doubly linked? Does
the list store values or by reference? Is the implementation optimised
for navigation or for mutation?)

Yes, I hope to have dedicated syntax, iterators, functions, all bultins. When I use a list on python I do not bother with the internal implemenfation, why I have to bother in Fortran? Yes I am aware of the different "flavors" of lists (I implemented some of them), but this is not a valid reason to avoid to having a builtin list. Do you bother with compilers implementation of arrays? Their different optimization? Why list opyimization comes into the reason to avoid it builtin? Strange, I am used to think that the standard often avoid to enter in the merits of "how to implement" a feature, rather it specifies the characteristics of features.

>Those aspects are part of the inclusion of arrays as a pretty
fundamental built-in feature of the language.

Well, in this case, if one select a priori an implementation (and not only define its characterics) of a list it is still viable, why do not permit the standard to define an ADT list? I suspect that the standard to not specify in so much details "how to implement" arrays just because I observed a not negligible difference between one compiler with respect others...

>Something that is difficult, expensive and slow may still be worth doing
if the benefit from doing that thing exceeds the cost of doing it.

Yes, this my view, but not your standing at your previous post.

>When you have multiple plausible methods of achieving an outcome, you
don't just look at the cost versus benefit of a single method in
isolation, you also look at the relativities between methods, so that
you reasonably expect to deliver the most (or the required) benefit for
the least cost.

I agree.

>CLASS(*) addressed a distinct capability gap in the language - before it
was introduced there were things that you simply could not do in
standard Fortran (store or reference runtime arbitrary type objects).
There would undoubtedly have been a very material cost associated with
adding that feature to the language, but all alternatives addressing
that capability gap would have required language changes. Your options
start to look more like "do or do not" at that stage.

>That situation doesn't apply to writing and using a list (or other data
structure) in Fortran today, because you *can*, without anything
approaching an impractical amount of effort, write and use lists in
modern Fortran right now.

Very weak reasons: you can use characters before "character" type was introduced, some here with a very long experience said to have done (before f66?), but I think it is better with intrinsic type, or not? Yes we can use list, but having an intrinsic ADT list is much better.


>If you already have standard source code for a generic list, the cost of
using that existing code is going to be pretty nominal for yourself and
anyone that you share the code with.

I have ADT lists based on unlimited polyrmphic data and other exploiting "tranfer", but I am not satisfied: there is not really true-abstraction, methods, functions. I feel that we are poor with respect Pythoners for example.4

>The cost of agreeing on and
specifying such a list in a standard, followed by actually building it
into multiple compilers would be enormous (being holistic about cost
here - including time considerations - a solution that I can rely on
today is better than one I might be able to use in a decade).

If it will be never considered, it will never become builtin... yes it has a cost, but I (and many others) think that the cost worth to be spent for having a abstract builtin containers.

>I recall some proverb from school that went something like "Give a
programmer a new intrinsic type and you keep them happy for a day, teach
their language how to support generic libraries and keep them happy for
a lifetime", but I might have that wrong - too busy fishing to pay
attention.

I do not want a new type, I want a new container...

>But you (or some other third party) only write your generic list thing
once, right? And then you just re-use it.

Yes, but this is incomplete: the level of abstraction we achieved is not satisfaftory, the list/tree must be often "adjusted". A builtin ADT list is much more versatile.

>(Code re-use (whether it is my code I am re-using, or someone else's
code - doesn't matter) is critical to programmer productivity, but I
think ease of code re-use is one of Fortran's biggest weaknesses.)

I agree.

>You have to draw the line somewhere. Python's design criteria are quite
different from those of the standard Fortran language, so its author
will have made different trade-offs in selecting which capabilities are
intrinsic, which facilities are provided by standard libraries, and what
things will be left to external libraries.

I am aware of this and I agree.

>I'd be sympathetic to some sort of effort towards "here is a standard
for a Fortran library that supports various generic data structures" (a
bit like ISO_VARYING_STRING was), but not for making the stuff inside
that library intrinsic.

It could be a starting point.

My best regards.

herrman...@gmail.com

unread,
Jun 19, 2016, 9:25:26 AM6/19/16
to
On Sunday, June 19, 2016 at 4:31:52 AM UTC-7, Ian Harvey wrote:
> On 2016-06-19 7:35 PM, Stefano Zaghi wrote:

(snip)
> > There are many cases where ADT is helpful, to cite just one I could
> > say that re-invent the wheel is a bad programming approach. List/tree
> > of abstract, etherogeneous data is very very helpful (in my peculiar
> > work for adaptive mesh refinement): having a builtin intrinsic list
> > or tree is convenient as having arrays. Do you think that arrays
> > facilities can be cinvenient trimmed out from built-ins and left to
> > external libraries?

> I'm not questioning their usefulness, I'm questioning why they have to
> be intrinsic.

Yes. Considering the usual use for Fortran, a numerical integration or
differential equation solver would seem useful, but we don't have either
as intrinsic. It isn't because they aren't useful, but because there are too
many different ways to do it, and the programmer has to determine the
one appropriate for the situation.

> What would an intrinsic list offer over a library solution?

> What are the special requirements on the compiler that you need for this
> list support? Are you after list specific syntax? Is "I am a list" a
> fundamental attribute of an object - permitting it to be a
> characteristic used for procedure resolution and the like? (If yes to
> either of those two - what specific sort of list are you talking about?
> Are you differentiating a singly linked list from doubly linked? Does
> the list store values or by reference? Is the implementation optimised
> for navigation or for mutation?)

The Java List interface defines appropriate properties if a list, without
giving a specific implementation. There is then LinkedList and ArrayList
that give them specific properties. Also, the Java interfaces give specific
methods general over a range of classes, such as size() to find the number
of elements of a list or tree, or isEmpty() to test for having no elements.

But this is also in the usual class libraries, not part of the language itself.

> Those aspects are part of the inclusion of arrays as a pretty
> fundamental built-in feature of the language.

Well, a little it is from the common use of Fortran for numerical science
and engineering, but also because arrays are fundamental for other
data structures. Arrays are a fundamental part of Java, not one of
the common class libraries included with the system.

(snip)

> When you have multiple plausible methods of achieving an outcome, you
> don't just look at the cost versus benefit of a single method in
> isolation, you also look at the relativities between methods, so that
> you reasonably expect to deliver the most (or the required) benefit for
> the least cost.

Note that Fortran finally has a matrix multiply intrinsic, though even for
that case there might be better ways for some users. No intrinsic matrix
inversion, though. (Unless added since I looked last.)

(snip)

> CLASS(*) addressed a distinct capability gap in the language - before it
> was introduced there were things that you simply could not do in
> standard Fortran (store or reference runtime arbitrary type objects).
> There would undoubtedly have been a very material cost associated with
> adding that feature to the language, but all alternatives addressing
> that capability gap would have required language changes. Your options
> start to look more like "do or do not" at that stage.

C has (unsigned char *) and sizeof that allow one to operate on objects
(usually struct) without knowing what is inside. That allows for a generic
qsort() sort routine in the C library.

Java Object and the Comparable interface allow for generic sorting for
classes that implement Comparable.

> That situation doesn't apply to writing and using a list (or other data
> structure) in Fortran today, because you *can*, without anything
> approaching an impractical amount of effort, write and use lists in
> modern Fortran right now.

I don't know Fortran OO well enough yet. Is there anything like the
Java interface?

> (In terms of "using" today, I am putting aside issues around compiler
> support for the current standard. There is obviously no point adding
> more stuff to the language in an attempt to deal with incomplete or
> buggy implementations of what has already been put into the language.)

> If you already have standard source code for a generic list, the cost of
> using that existing code is going to be pretty nominal for yourself and
> anyone that you share the code with. The cost of agreeing on and
> specifying such a list in a standard, followed by actually building it
> into multiple compilers would be enormous (being holistic about cost
> here - including time considerations - a solution that I can rely on
> today is better than one I might be able to use in a decade).

Yes. Standardizing the method calls without standardizing the implementation
allows for improvements later without needing to start over again.

> That's not to say that there isn't substantial room for improvement in
> how the language supports things like generic data structures, I could
> rant for days about that, but that is not the same thing as actually
> building specific data structures into the base language.

> I recall some proverb from school that went something like "Give a
> programmer a new intrinsic type and you keep them happy for a day, teach
> their language how to support generic libraries and keep them happy for
> a lifetime", but I might have that wrong - too busy fishing to pay
> attention.

(snip)

-- glen

herrman...@gmail.com

unread,
Jun 19, 2016, 9:39:08 AM6/19/16
to
On Sunday, June 19, 2016 at 6:15:50 AM UTC-7, Stefano Zaghi wrote:

(snip)

> If it will be never considered, it will never become builtin... yes it has a cost,
> but I (and many others) think that the cost worth to be spent for having a
> abstract builtin containers.

Note that List is not built-in to Java, but an interface (Java term) commonly
included with the Java class libraries.

Even then, List doesn't have a specific implementation, but only standardizes
the methods that are used to operate on a List.

If someone wrote some List routines, possibly following the Java names for
the methods, they could get distributed to those who needed them.

Without being part of the standard, just as they are not part of the Java
language, people would get used to them and use them.

Richard Maine

unread,
Jun 19, 2016, 11:41:22 AM6/19/16
to
Stefano Zaghi <stefan...@gmail.com> wrote:

> Writing a library for an ADT list is possible (we done), but is not
> easier, nor cheaper, neiter faster than having an instrinsic list as we
> have intrinsic array, e.g. python offer builtin ADT list, it is easy,
> cheap and fast.

I'd say you are focussing only on your own work and failing to look at
the larger picture. Sure it is easy and cheap to have someone else do
things for you. But adding things to the standard is not at all easy,
cheap, or fast. It just happens to be work done by oher people than you.

The Fortran standards committee is tiny. There were times when it had 40
or 50 people, but last time I was on it there were only a handful of
people. All of them are volunteering their time, plus a fair amout of
money for dues and travel to meetings. And there is a lot of work for
them to do. There are far more resonable proposals than there are
resources to do them. In my personal opinion, the commitee takes on too
much work as it is, which inevitably makes the quality suffer.

And then if something is in the standard, every single compiler vendor
has to implement it. Among other things, this creates a high entry
barrier for new compilers.

Finally, the standards process is slow. *VERY* slow. From when an idea
is proposed to when it actually gets into a published standard and then
into a compiler is typically on the order of a decade. It can take
longer than that.

I consider it better to have the standard mostly restricted to things
that need to be in the language for technical reasons. A position that
things need to be in the standard because that means it just magically
happens instead of someone having to do work is not a winning argument.

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

Dick Hendrickson

unread,
Jun 19, 2016, 11:50:00 AM6/19/16
to
Have you looked at sub-modules?

Dick Hendrickson

Richard Weed

unread,
Jun 19, 2016, 12:40:40 PM6/19/16
to
Thanks to everyone that has responded so far both pro and con. This is the kind of discussion/debate I was hoping for. In light of the resposes so far, I'll
make the following clarifications and additions to my original post.

1. In the case of a standardized module format, I'm aware that the differences
in internal object formats would make this difficult. All I'm asking for is
some facility that I can use the .MOD files built by say gfortran with other compilers in a standardized way so I don't have to waste time building third
party software just because noboby can agree on what the internal formats
(namespace rules etc) should be and nobody in the standards world wants to step
up and provide some adult supervision. In my previous job, one of my major
assigments was installing and maintaining a variety of very large Computational
Fluid Dynamics and Computational Structural Mechanics (CFD and CSM) packages that made heavy use of third party libraries. Most of the issues I had were not with the base code itself but the libraries. Some wanted to use shared objects only and
were tied to a particular version (even down to libc), others would only work with a particular compiler or a specific version of a compiler. If you insist
on tying your software to third party libraries, be prepared to spend a larger amount of your time dealing with them than with your own code. And thats if, you are allowed to actually build and install these libraries yourself on a given system. On some large scale systems (like inside Gov't labs and some
universities) you might not have priveledges or be allowed to install them youself.

Also, code transportability (both between compilers and different systems and
architectures) is a major issue in the real world. Anything done at the compiler level to increase that will decrease the total life cycle cost of deploying a particular piece of software

2. My call for intrinsic facilities for ADTs and Linear Algebra routines is based on my recent experiences in writing a large scale application where I needed to support lists as well as provide a basic set of routines for solving linear systems of equations to do unit testing on routines that will eventually
have to use larger packages (MKL etc.) probably in parallel. I went throught the exersice of writing a set of Object based routines using unlimited polymorphism to handle linked lists, queues, red-black trees etc. After several thousand lines of code I have something that works for both instrinsic data types and a user derived type. My point is again why should I have to waste my time doing this for something that (in the case of a list) is almost essential
in modern CFD and CSM methods that use unstructured grids were data is
not stored in a convenient contiguous array and accessed in loops with unit stride. Since in my experience, the majority of Fortran cpu cycles on current large HPC systems inside Gov't labs etc. are done by CFD and CFM codes I just think having an intrinsic facility for lists built into the langauge is in this day and age as important as arrays were back when Fortran first started.

As to the need for intrinsic interfaces for linear algebra, my call for this is prompted by a recent experience were I was trying to use LAPACK routines from both the netlib and MKL. I found that for some of the routines there were differences in the netlib LAPACK90 and MKL interfaces. So I had to kludge up my code with fpp macros and modify my build scripts to account for the differences if I was on a system that didn't support MKL and the Intel compiler. Having a common set of interfaces that wrap the calls to any underlying routine that
may or not have the same interface reduces my workload and makes my code base
cleaner and easier to maintian. As to knowing what method to use etc., after 50 plus years of doing numerical linear algebra we know what works and what works best. As long as the interface is consistent, I'll leave it to the math library folks to implement the methods that provide the best performance with a given
compiler on a given architecture.

I guess in general I'm asking for more capability in Fortran that allows me to
as outlined in Damien Rouson's book use the design pattern folks idea that you program to an interface and not an implementation. I also think that in the case of things like lists having an intrinsic capability reduces the need to
clutter up Fortran with something like templates.

Finally, while I'll use other folks libraries etc. if thats my only option, so much code these days (even if its suppose to be free) is encumbered by some license that might make it impossible to use in my project because my legal folks or my customer's legal folks don't want to deal with possible issues of misuse or potential ITAR violations.

I'll post my ideas about topics 2-4 in my original post over the next couple of weeks as time permits.

Again, thanks to all for your comments. Hopefully, we are providing the standards folks with ideas for the next Fortran





herrman...@gmail.com

unread,
Jun 19, 2016, 3:00:37 PM6/19/16
to
On Sunday, June 19, 2016 at 9:40:40 AM UTC-7, Richard Weed wrote:
> Thanks to everyone that has responded so far both pro and con.
> This is the kind of discussion/debate I was hoping for. In light of the
> resposes so far, I'll
> make the following clarifications and additions to my original post.

> 1. In the case of a standardized module format, I'm aware that the differences
> in internal object formats would make this difficult. All I'm asking for is
> some facility that I can use the .MOD files built by say gfortran with other
> compilers in a standardized way so I don't have to waste time building third
> party software just because noboby can agree on what the internal formats
> (namespace rules etc) should be and nobody in the standards world wants to step
> up and provide some adult supervision.

Actually, I probably believe that the .MOD file should be standardized, but the
advantage is pretty small. You pretty much have to compiler for each system,
for each compiler version, and each memory model (32 bit and 64 bit, currently).

Much of what needs to go into a .MOD file should be the same for different
systems. It does occur to me that KIND values likely go in, and could be different
for different systems. They might even change with compiler options on the
same system. So, even in the best case, they aren't all that portable.

> In my previous job, one of my major
> assigments was installing and maintaining a variety of very large Computational
> Fluid Dynamics and Computational Structural Mechanics (CFD and CSM) packages
> that made heavy use of third party libraries. Most of the issues I had were not
> with the base code itself but the libraries. Some wanted to use shared objects only
> and were tied to a particular version (even down to libc), others would only
> work with a particular compiler or a specific version of a compiler.

Yes. As noted, this is true independent of .MOD file format, and for a variety of reasons.

> If you insist on tying your software to third party libraries, be prepared to
> spend a larger amount of your time dealing with them than with your own code.
> And thats if, you are allowed to actually build and install these libraries yourself
> on a given system. On some large scale systems (like inside Gov't labs and some
> universities) you might not have priveledges or be allowed to install them youself.

The advantage of open source is that you can compile for the specific system.

With commercial, closed source, you have to find the right version for your specific
compiler.

It might be possible to standardize the calling sequence, even for the more
complicated Fortran cases like assumed shape and allocatable. (I believe that
there is discussion to allow calling to/from C for some of those.)

But I/O will likely stay system specific. Only if the library doesn't do any I/O is there
any hope of porting object code between systems.

> Also, code transportability (both between compilers and different systems and
> architectures) is a major issue in the real world. Anything done at the compiler level
> to increase that will decrease the total life cycle cost of deploying a particular
> piece of software

Standardize on one system and architecture. Sounds easy!

> 2. My call for intrinsic facilities for ADTs and Linear Algebra routines is based on
> my recent experiences in writing a large scale application where I needed to support
> lists as well as provide a basic set of routines for solving linear systems of equations
> to do unit testing on routines that will eventually have to use larger packages
> (MKL etc.) probably in parallel. I went throught the exersice of writing a set of
> Object based routines using unlimited polymorphism to handle linked lists,
> queues, red-black trees etc. After several thousand lines of code I have something
> that works for both instrinsic data types and a user derived type.

There has been discussion of that, but as far as I know, you are the first to do it.

As far as I know, it is pretty recently that unlimited polymorphism was ready to be
able to do such.

> My point is again why should I have to waste my time doing this for something
> that (in the case of a list) is almost essential in modern CFD and CSM methods
> that use unstructured grids were data is not stored in a convenient contiguous
> array and accessed in loops with unit stride.

Since people have been doing that at least back to Fortran 66 days, is isn't
required that it work for unlimited polymorphism, but yes the previous ones would
be specific for the case at hand.

> Since in my experience, the majority of Fortran cpu cycles on current large HPC
> systems inside Gov't labs etc. are done by CFD and CFM codes

seems possible

> I just think having an intrinsic facility for lists built into the langauge is in this
> day and age as important as arrays were back when Fortran first started.

I suspect most don't go as far as unlimited polymorphism. They just implement
the specific case, and usually fairly simple at that. The specific case is likely
more efficient, though the fraction of time spent doing list processing should be
fairly small for most CFD and CFM problems.

> As to the need for intrinsic interfaces for linear algebra, my call for this is
> prompted by a recent experience were I was trying to use LAPACK routines
> from both the netlib and MKL. I found that for some of the routines there were
> differences in the netlib LAPACK90 and MKL interfaces. So I had to kludge up
> my code with fpp macros and modify my build scripts to account for the differences
> if I was on a system that didn't support MKL and the Intel compiler.
> Having a common set of interfaces that wrap the calls to any underlying
> routine that may or not have the same interface reduces my workload and
> makes my code base cleaner and easier to maintian. As to knowing what
> method to use etc., after 50 plus years of doing numerical linear algebra we
> know what works and what works best. As long as the interface is consistent,
> I'll leave it to the math library folks to implement the methods that provide the
> best performance with a given compiler on a given architecture.

OK, but this doesn't require it to be part of the standard, only that implementors
of different packages agree.

(snip)

-- glen

Stefano Zaghi

unread,
Jun 19, 2016, 5:03:33 PM6/19/16
to
Dear Richard,

>I'd say you are focussing only on your own work and failing to look at
the larger picture. Sure it is easy and cheap to have someone else do
things for you. But adding things to the standard is not at all easy,
cheap, or fast. It just happens to be work done by oher people than you.

Probably you are right, my limited experience shows me a picture smaller than yours, but you are surely failing to understand me: I never said that adding anything (even a comma...) to the standard is easy, cheap or fast, these are words of Ian about developing libraries... I am conscious of the hard work of F-men. As regarding the concept of "stole the work of others" I am not the rigth man to object this, 90% of me codes are FOOS, you can only object to the quality of my work...

>The Fortran standards committee is tiny. There were times when it had 40
or 50 people, but last time I was on it there were only a handful of
people. All of them are volunteering their time, plus a fair amout of
money for dues and travel to meetings. And there is a lot of work for
them to do. There are far more resonable proposals than there are
resources to do them. In my personal opinion, the commitee takes on too
much work as it is, which inevitably makes the quality suffer.

I totally agree, I will never stop to thanks them (you among others) for their wonderful work.

>And then if something is in the standard, every single compiler vendor
has to implement it. Among other things, this creates a high entry
barrier for new compilers.

This concept seems to have not block the definition of parametrized derived type in the standard... another weak reason to not discuss at all about generic containers. Let the standard define them, then we kindly wait some decades to have compilers support as we will do for parametrized derived type.

>Finally, the standards process is slow. *VERY* slow. From when an idea
is proposed to when it actually gets into a published standard and then
into a compiler is typically on the order of a decade. It can take
longer than that.

I am a Fortraner, I am patient.

>I consider it better to have the standard mostly restricted to things
that need to be in the language for technical reasons. A position that
things need to be in the standard because that means it just magically
happens instead of someone having to do work is not a winning argument.

What is surely not winning is using so weak reasons to not discuss at all about generic containers: a lot of possible Fortraners go away for this "so small picture" of reality. Again, you argument that I would like to stole the work of the committee instead of doing it by my hands... as I said before this argument is very silly. Why you are contrary to define a list as you have defined the concept of array? I suspect that you think this is just a nerd-stuff...

The need of generic containers is not limited to my work, we are many, the limited picture is your. If you like so tiny language, maybe C is better than Fortran for you, all happens to be in "std libraries". I like Fortran because it has so wonderful bultins, I hope to see an ADT list before I will retire.

My best regards.

Wolfgang Kilian

unread,
Jun 19, 2016, 5:10:26 PM6/19/16
to
As I understand the OP's post, he also refers to a distinct capability
gap in the language, namely the inability to provide generic containers
which are strongly typed, in the same sense as arrays are strongly
typed. Class(*) doesn't solve this problem in any satisfactory way.

(Ab)using class(*) for generic containers, the library writer
effectively abandons Fortran's type management system, at the cost of
writing a replacement system. It appears as if the OP already has done
substantial work in this direction, but still that's more like a
workaround than a solution.

>
> That situation doesn't apply to writing and using a list (or other data
> structure) in Fortran today, because you *can*, without anything
> approaching an impractical amount of effort, write and use lists in
> modern Fortran right now.
>
> (In terms of "using" today, I am putting aside issues around compiler
> support for the current standard. There is obviously no point adding
> more stuff to the language in an attempt to deal with incomplete or
> buggy implementations of what has already been put into the language.)
>
> If you already have standard source code for a generic list, the cost of
> using that existing code is going to be pretty nominal for yourself and
> anyone that you share the code with. The cost of agreeing on and
> specifying such a list in a standard, followed by actually building it
> into multiple compilers would be enormous (being holistic about cost
> here - including time considerations - a solution that I can rely on
> today is better than one I might be able to use in a decade).
>
> That's not to say that there isn't substantial room for improvement in
> how the language supports things like generic data structures, I could
> rant for days about that, but that is not the same thing as actually
> building specific data structures into the base language.
>
> I recall some proverb from school that went something like "Give a
> programmer a new intrinsic type and you keep them happy for a day, teach
> their language how to support generic libraries and keep them happy for
> a lifetime", but I might have that wrong - too busy fishing to pay
> attention.

Yes, and I insist that class(*) still doesn't provide the necessary
capabilities, even if it technically allows writing a generic-list library.

With Fortran 77, you could handle any generic data structure. Just use
a large work array and equivalence it to any type. So why go further?
Fortran 90 had pointer arrays. Now we can replace those by allocatable
arrays, which were also not really required - but they dispense the user
from doing memory management. You can do list and tree structures via
reallocating arrays, right? Typed generic data structures are a logical
next step towards versatility of the language. They would dispense the
user (or library writer) from doing explicit type management.

>> Why list should be considered "type B" container (that must be left
>> outside builtins) with respect array that being "type A" container
>> has the "grant" to be builtin?
>>
>> Surely I think that array is the most important container: doing
>> calculations, I use arrays 90% of time, so why the rest 10% of coding
>> (where data structures are not simple arrays) should take my 90% of
>> work for re-inventing the wheel?
>
> But you (or some other third party) only write your generic list thing
> once, right? And then you just re-use it.
>
> (Code re-use (whether it is my code I am re-using, or someone else's
> code - doesn't matter) is critical to programmer productivity, but I
> think ease of code re-use is one of Fortran's biggest weaknesses.)
>
> You have to draw the line somewhere. Python's design criteria are quite
> different from those of the standard Fortran language, so its author
> will have made different trade-offs in selecting which capabilities are
> intrinsic, which facilities are provided by standard libraries, and what
> things will be left to external libraries.
>
> I'd be sympathetic to some sort of effort towards "here is a standard
> for a Fortran library that supports various generic data structures" (a
> bit like ISO_VARYING_STRING was), but not for making the stuff inside
> that library intrinsic.

I don't get your point here - didn't the OP just ask for an intrinsic
facility that *allows for* writing generic container code? He was not
asking for the container types themselves to become intrinsics.

The ability to write strongly typed generic code can only come as an
extension of the language itself. Specific incarnations (list, queue,
etc.) might be provided via intrinsic modules as a convenience (see
STL), but that's secondary.

-- Wolfgang

Ron Shepard

unread,
Jun 19, 2016, 5:37:13 PM6/19/16
to
On 6/19/16 2:00 PM, herrman...@gmail.com wrote:

[regarding *.mod and *.obj files...]

> The advantage of open source is that you can compile for the specific system.

Yes for open source, but also some commercial vendors will give you the
source if you buy the license but you do not have the legal right to
modify it (or redistribute, etc.).

> With commercial, closed source, you have to find the right version for your specific
> compiler.

It seems like these days this is not so much of an issue as it might
have been 20 or 30 years ago. Now, the vendor can just place compiled
*.obj and *.mod files online for all versions of their supported
compilers, and the customer can download the appropriate one for his
compiler and his choice of options.

$.02 -Ron Shepard

Wolfgang Kilian

unread,
Jun 19, 2016, 5:52:53 PM6/19/16
to
On 06/19/2016 05:02 AM, Richard Weed wrote:
>
> I would like to start a dialog on what people like me (a long time
> Fortran user developing codes for computational fluid and structural
> dynamics applications) would like to see in the next iteration of
> Fortran. In particular, I want to discuss what I think is missing
> from Fortran that would make my programming life a lot easier if
> implemented from a user standpoint (as opposed to a compiler
> developer and/or member of the standards committee). Some of the
> topics I intend to cover in separate posts are:
>
> 1. The need for a standard module and submodule format to allow
> interoperability between modules compiled with different
> compilers

As much as I agree with you from a user's perspective (I have bitten by
this problem more than once), I suppose that this is impossible in
general. If an uniform module format is to make any sense, you would
have to fix at least calling conventions for module procedures and
storage internals of derived types. Such aspects are not specified by
the Fortran standard, and I assume that this is on purpose.

Think of a BIND attribute, say BIND(Fortran), which might apply to
entities within modules that you would like to make binary-interoperable
across compilers. IIRC, BIND(C) guarantees not more that
interoperability for a single companion processor, although the C
standard specifies a lot more about storage and calling conventions.
For Fortran with its freedom on implementation, this is rather hopeless.

> 2. The need for an intrinsic ADT facility that supports lists, queues,
> trees etc. (I know this has been discussed before at some length
> but I would like to put forward my ideas on how I would like to
> see them implemented)

I am with you on that item. If the support in the language is generic,
specific incarnations (list, queue, etc.) could be left to a library or
(intrinsic) module.

>
> 3. The need for an intrinsic linear algebra facility that defines
> standard intrinsic types for matricies (dense and sparse) and standard
> interfaces with meaningful procedure names and not the abbreviated
> mess that is LAPACK (the implementation is still left to the compiler
> developers, I just want interfaces that will work with any linear
> algebra package in a standard way) to the most common linear algebra
> tasks (LU factorization, solving systems of equations, finding
> eigenvalues and eigenvectors condition numbers, matvecs, etc.)

Dense matrices are two-dimensional arrays, so they are already in the
language. For sparse matrices, I guess that this depends too much on
the actual problem where they arise.

In any case, I would not think in terms of intrinsic functions but of
intrinsic modules. Doesn't this sound more like the Lapack interface
should be updated to the present standard of Fortran conventions?

>
> 4. Some things that I think should have been in the previous standards but
> for some reason were left out or rejected by the standards committee.
>
>
> I'll start with the need for a standard format for modules and submodules. I ran into this problem yesterday when I tried to use a version of PLplot I installed via software manager on my Linux Mint system with some code I compiled with the Intel compiler. I was trying to use the Fortran 90 interfaces so of course when I tried to USE plplot I got errors. Obviously, I could download PLplot and build an Intel specific version but my point is, why should I have to. I tried first to use an old version of PLplot I had compiled with Intel but after several OS upgrades etc. some of the shared object files needed were no longer found. If there was a standard format (it could be in addition to the existing compiler specific format but selected by a compiler flag say -fiso-module-format) I wouldn't have to waste time building PLplot. I could just use whats available and not worry about which compiler was used to build the third-party library (as long as the .o files are compatible - which i
s the case with Intel and gcc on Linux).
>
> So my questions to the user community (and compiler developers and standards committee folks) are.
>
> 1. Do others see the need for a standard module format that is interoperable
> between compilers (at least on Linux/Unix/BSD)

Answer: I see the need but this won't (can't) happen, I fear.

> 2. Has this been proposed in the past to the standards committees and if so
> why was it rejected

I remember some ideas from the gfortran side that the source code (maybe
dropping irrelevant detail) could serve as a common format, at least for
gfortran itself.

With submodules, this even makes sense for closed-source projects - the
information in modules could be reduced to types and interfaces,
equivalent to C header files. The implementation is in submodules.
Note that there is no need for unifying submodule formats, as they do
not contain any information that is externally accessible.

But even this doesn't work across compilers, because they may (are in
principle allowed to) have different conventions for storage within
types, etc.

> 3. I realize this probably doesn't have a snowballs chance of being implemented
> but if it was I would like to hear from others on possible issues that
> would prevent it from being implemented
>
> I'll post my ideas on subjects 2-4 in separate posts
>
> RW
>

-- Wolfgang

Ian Harvey

unread,
Jun 19, 2016, 8:02:54 PM6/19/16
to
I'm not really talking about the internal implementation, the latter bit
was more highlighting that there are materially different options for
the "flavour" of a list. If you build *a* list into the compiler, there
is a reasonable chance that list won't suit (or it would be overkill) in
some cases.

Things that get built into compilers usually need to be lowest common
denominator sort of stuff.

>> Those aspects are part of the inclusion of arrays as a pretty
> fundamental built-in feature of the language.
>
> Well, in this case, if one select a priori an implementation (and not
> only define its characterics) of a list it is still viable, why do
> not permit the standard to define an ADT list? I suspect that the
> standard to not specify in so much details "how to implement" arrays
> just because I observed a not negligible difference between one
> compiler with respect others...

(There's a difference between some sort of specification of what the
interface of a list might be, and then requiring that interface be built
into a compiler in some way. If you are not changing the compiler, then
your specified interface is limited to the capabilities of the language
of the day.)

>> Something that is difficult, expensive and slow may still be worth
>> doing
> if the benefit from doing that thing exceeds the cost of doing it.
>
> Yes, this my view, but not your standing at your previous post.

I was contrasting the effort required for changes to the language (and
therefore all compilers implementing the language) with the effort
required to write a source code library.

I am very much not saying the language should never be changed, quite
the contrary. But when considering whether to "build something in" or
leave it to libraries to implement, there is a very big difference in
the relative effort involved.
It well pre-dates my time, but doing character manipulation in a
robustly portable manner prior to the introduction of the character type
strikes me as practically impossible. People wrote code for specific
processors, and it worked, but if you looked at the details of what was
being assumed, it wasn't portable.

I am not arguing that if you can already do something in the language
that you should never consider improving that way or adding better
alternatives. But in terms of benefit, there is a big difference
between "I cannot do this at all" - a language feature that enables
broad function, versus "this is a better way for doing something that I
already can do".

>> If you already have standard source code for a generic list, the
>> cost of
> using that existing code is going to be pretty nominal for yourself
> and anyone that you share the code with.
>
> I have ADT lists based on unlimited polyrmphic data and other
> exploiting "tranfer", but I am not satisfied: there is not really
> true-abstraction, methods, functions. I feel that we are poor with
> respect Pythoners for example.4

This is a different topic, but I think unlimited polymorphic CLASS(*)
has a very limited role to play in generic programming. It has a role
to play in code where the code has absolutely no idea when executing
about the characteristics of the thing that it needs to store or
reference, but that is not the usual case in generic programming. For
example, for a generic list, the typical case is that all items in the
list are of the same type, this is not a concept that can be described
by using an unlimited polymorphic scalar for each list element.

TRANSFER definitely does not have a role to play in generic programming!
It will work for Fortran 95 level objects, but as soon as you start
throwing Fortran 2003 features into your objects (e.g allocatable
components) it is practically just broken. From the overall perspective
of the language, this is a good thing - I think requiring TRANSFER to
work reliably on F2003+ objects would have heinous implications for
implementation and optimisation of Fortran programs.

(If you are sticking relatively closely to the confines of the standard
language, then INCLUDE is pretty much how you have to do generic
containers today, and it is certainly not without its issues. Sad but
true. Going beyond standard source code as input - there are
preprocessor style options too.)

>> The cost of agreeing on and
> specifying such a list in a standard, followed by actually building
> it into multiple compilers would be enormous (being holistic about
> cost here - including time considerations - a solution that I can
> rely on today is better than one I might be able to use in a decade).
>
>
> If it will be never considered, it will never become builtin... yes
> it has a cost, but I (and many others) think that the cost worth to
> be spent for having a abstract builtin containers.
>
>> I recall some proverb from school that went something like "Give a
>>
> programmer a new intrinsic type and you keep them happy for a day,
> teach their language how to support generic libraries and keep them
> happy for a lifetime", but I might have that wrong - too busy fishing
> to pay attention.
>
> I do not want a new type, I want a new container...

I don't want a new container, I want language features that let me (or
third parties) write portable source code that specifies the
characteristics and requirements of specific containers, and then lets
me easily use those containers.

I don't want *a* container, I want practical access to *any* container.

If a compiler vendor chooses to conveniently package libraries with
their compiler that provide a set of containers ready for me to use
(like compiler vendors commonly package numeric libraries), that's
great, it will be one of the things that sways my decision about which
vendor to use. If there is some common agreement about the interface of
those libraries to further promote code portability, perhaps even going
as far as another part of the standard like ISO_VARYING_STRING, that's
fantastic. But I don't see the need to hardwire the specific containers
into the language as intrinsic types or whatever.

Ian Harvey

unread,
Jun 19, 2016, 8:07:42 PM6/19/16
to
...
>> CLASS(*) addressed a distinct capability gap in the language - before it
>> was introduced there were things that you simply could not do in
>> standard Fortran (store or reference runtime arbitrary type objects).
>> There would undoubtedly have been a very material cost associated with
>> adding that feature to the language, but all alternatives addressing
>> that capability gap would have required language changes. Your options
>> start to look more like "do or do not" at that stage.
>
> As I understand the OP's post, he also refers to a distinct capability
> gap in the language, namely the inability to provide generic containers
> which are strongly typed, in the same sense as arrays are strongly
> typed. Class(*) doesn't solve this problem in any satisfactory way.
>
> (Ab)using class(*) for generic containers, the library writer
> effectively abandons Fortran's type management system, at the cost of
> writing a replacement system. It appears as if the OP already has done
> substantial work in this direction, but still that's more like a
> workaround than a solution.

I agree - see my response to Stefano.

>> That situation doesn't apply to writing and using a list (or other data
>> structure) in Fortran today, because you *can*, without anything
>> approaching an impractical amount of effort, write and use lists in
>> modern Fortran right now.
>>
>> (In terms of "using" today, I am putting aside issues around compiler
>> support for the current standard. There is obviously no point adding
>> more stuff to the language in an attempt to deal with incomplete or
>> buggy implementations of what has already been put into the language.)
>>
>> If you already have standard source code for a generic list, the cost of
>> using that existing code is going to be pretty nominal for yourself and
>> anyone that you share the code with. The cost of agreeing on and
>> specifying such a list in a standard, followed by actually building it
>> into multiple compilers would be enormous (being holistic about cost
>> here - including time considerations - a solution that I can rely on
>> today is better than one I might be able to use in a decade).

Let me highlight:

>> That's not to say that there isn't substantial room for improvement in
>> how the language supports things like generic data structures, I could
>> rant for days about that, but that is not the same thing as actually
>> building specific data structures into the base language.
>>
>> I recall some proverb from school that went something like "Give a
>> programmer a new intrinsic type and you keep them happy for a day, teach
>> their language how to support generic libraries and keep them happy for
>> a lifetime", but I might have that wrong - too busy fishing to pay
>> attention.



> Yes, and I insist that class(*) still doesn't provide the necessary
> capabilities, even if it technically allows writing a generic-list library.

I insist that I agree!

> With Fortran 77, you could handle any generic data structure. Just use
> a large work array and equivalence it to any type. So why go further?
> Fortran 90 had pointer arrays. Now we can replace those by allocatable
> arrays, which were also not really required - but they dispense the user
> from doing memory management. You can do list and tree structures via
> reallocating arrays, right? Typed generic data structures are a logical
> next step towards versatility of the language. They would dispense the
> user (or library writer) from doing explicit type management.

Support for generic data structures would be great. Bring it on...
where do I sign?

(Just don't do it using macros or other dumb text preprocessing please.)

But my view is the data structures themselves don't have to be intrinsic.

>>> Why list should be considered "type B" container (that must be left
>>> outside builtins) with respect array that being "type A" container
>>> has the "grant" to be builtin?
>>>
>>> Surely I think that array is the most important container: doing
>>> calculations, I use arrays 90% of time, so why the rest 10% of coding
>>> (where data structures are not simple arrays) should take my 90% of
>>> work for re-inventing the wheel?
>>
>> But you (or some other third party) only write your generic list thing
>> once, right? And then you just re-use it.
>>
>> (Code re-use (whether it is my code I am re-using, or someone else's
>> code - doesn't matter) is critical to programmer productivity, but I
>> think ease of code re-use is one of Fortran's biggest weaknesses.)
>>
>> You have to draw the line somewhere. Python's design criteria are quite
>> different from those of the standard Fortran language, so its author
>> will have made different trade-offs in selecting which capabilities are
>> intrinsic, which facilities are provided by standard libraries, and what
>> things will be left to external libraries.
>>
>> I'd be sympathetic to some sort of effort towards "here is a standard
>> for a Fortran library that supports various generic data structures" (a
>> bit like ISO_VARYING_STRING was), but not for making the stuff inside
>> that library intrinsic.
>
> I don't get your point here - didn't the OP just ask for an intrinsic
> facility that *allows for* writing generic container code? He was not
> asking for the container types themselves to become intrinsics.

The various posters can clarify their intent, but I read the original
post as "I want an intrinsic list (and other intrinsic things)",
certainly that's how Stefano's post came across. That's not the same
thing as "I want better support in the language for writing and using
generic containers", which might not require any intrinsic procedures,
types or modules. For example, it could conceivably just be an
extension of capability along the lines of the existing integer kind
parameterisation of types - permit type parameterisation of types as well.

I don't really see why anything about generic containers needs to be
intrinsic (as per its meaning in the context of the language - F2008
2.5.5, maybe the definition of that is confusing things).

> The ability to write strongly typed generic code can only come as an
> extension of the language itself. Specific incarnations (list, queue,
> etc.) might be provided via intrinsic modules as a convenience (see
> STL), but that's secondary.

I think "ability" in the above should be relative in the current
language - you *can* write strongly typed generic code today, but it
isn't as easy to write or to use as it could (and should) be - you have
to use INCLUDE tricks and that sort of nonsense.

It is the ability to easily write and use strongly typed generic code
that is the problem that is best addressed, not the absence of some
fairly specific set of containers from the list of intrinsic things.

Put general capabilities in the base language, leave more specific
solutions to libraries or end user code.

Richard Maine

unread,
Jun 19, 2016, 9:22:52 PM6/19/16
to
Ian Harvey <ian_h...@bigpond.com> wrote:

> On 2016-06-20 7:10 AM, Wolfgang Kilian wrote:
> > On 06/19/2016 01:31 PM, Ian Harvey wrote:

> >> That's not to say that there isn't substantial room for improvement in
> >> how the language supports things like generic data structures, I could
> >> rant for days about that, but that is not the same thing as actually
> >> building specific data structures into the base language.
> >>
> >> I recall some proverb from school that went something like "Give a
> >> programmer a new intrinsic type and you keep them happy for a day, teach
> >> their language how to support generic libraries and keep them happy for
> >> a lifetime", but I might have that wrong - too busy fishing to pay
> >> attention.
...
> Support for generic data structures would be great. Bring it on...
> where do I sign?
...
> But my view is the data structures themselves don't have to be intrinsic.

I 100% agree with all that. As I mentioned in my post, "have the
standard restricted to things that need to be in the language for
technical reasons." I was really saying exactly the same thing as you
are above, just using slightly different words.

> > I don't get your point here - didn't the OP just ask for an intrinsic
> > facility that *allows for* writing generic container code? He was not
> > asking for the container types themselves to become intrinsics.
>
> The various posters can clarify their intent, but I read the original
> post as "I want an intrinsic list (and other intrinsic things)",
> certainly that's how Stefano's post came across. That's not the same
> thing as "I want better support in the language for writing and using
> generic containers",...

Yes, I read at least Stefano as asking for specific containers like
lists. That's why I reacted negatively to his post. Perhaps there might
be some language difficulty (as in Italian vs English) in my
interpreting what he said.

I had about decided to stop replying to this thread based on that. I
don't think a standardized list facility is desirable, and I don't think
it is going to happen either, so I figure that debating it is just a
waste of time and quickly turns personal.

Now if someone has good ideas on how the base language can better
facilitate users doing such structures, that's a completely different
matter.

I rather wonder if there might be some arguing at cross-purposes going
on because different people have different readings as to what is even
being discussed.

Stefano Zaghi

unread,
Jun 20, 2016, 12:27:39 AM6/20/16
to
Dear Ian,

>I'm not really talking about the internal implementation, the latter bit
was more highlighting that there are materially different options for
the "flavour" of a list. If you build *a* list into the compiler, there
is a reasonable chance that list won't suit (or it would be overkill) in
some cases.

You have mentioned optimization, you did seem to refer to implementation, again you said that if in the future we will we have "a lust" this will be nit what we want, that sound like "wrong" implementation or wrong flavor. Why this does not happen for Python? I use Python lists extensively without wondering to which "flavor" they belong. Overkilled list or poor one is surely a step over having no generic containers.

>Things that get built into compilers usually need to be lowest common
denominator sort of stuff.

I am not an expert of the standard, but I guess thare are many "things" that special with only one common denominator... themself. Generic vontainer could be very difficult to define, a real challenge for the committee, but surely they are of wide interest, not so self-contained to be considered a special case.


>(There's a difference between some sort of specification of what the
interface of a list might be, and then requiring that interface be built
into a compiler in some way. If you are not changing the compiler, then
your specified interface is limited to the capabilities of the language
of the day.)

I am conscious of that.

>I was contrasting the effort required for changes to the language (and
therefore all compilers implementing the language) with the effort
required to write a source code library.

This was clear to me, less for Richard.

>I am very much not saying the language should never be changed, quite
the contrary. But when considering whether to "build something in" or
leave it to libraries to implement, there is a very big difference in
the relative effort involved.

I agree. Generic containers worth to defined for me, for you ebidently not. I am constrasting the your reasons to avoid their definition.


>It well pre-dates my time, but doing character manipulation in a
robustly portable manner prior to the introduction of the character type
strikes me as practically impossible. People wrote code for specific
processors, and it worked, but if you looked at the details of what was
being assumed, it wasn't portable.

For whom asking for generic containers the situation is similar: we need to write list/tree for specific needs, genericity is still far to be really supported as well you were blocked to use portable strings, but I do not argued to you "there are workarounds to do that, write your own library", I was happy character type was added to the standard.

>I am not arguing that if you can already do something in the language
that you should never consider improving that way or adding better
alternatives. But in terms of benefit, there is a big difference
between "I cannot do this at all" - a language feature that enables
broad function, versus "this is a better way for doing something that I
already can do".

>This is a different topic, but I think unlimited polymorphic CLASS(*)
has a very limited role to play in generic programming. It has a role
to play in code where the code has absolutely no idea when executing
about the characteristics of the thing that it needs to store or
reference, but that is not the usual case in generic programming. For
example, for a generic list, the typical case is that all items in the
list are of the same type, this is not a concept that can be described
by using an unlimited polymorphic scalar for each list element.

>TRANSFER definitely does not have a role to play in generic programming!
It will work for Fortran 95 level objects, but as soon as you start
throwing Fortran 2003 features into your objects (e.g allocatable
components) it is practically just broken. From the overall perspective
of the language, this is a good thing - I think requiring TRANSFER to
work reliably on F2003+ objects would have heinous implications for
implementation and optimisation of Fortran programs.

Weel, these are our workarounds to achieve a minimum genericity... give us generic conainers and "we stop to encode charcters into other types" :-)

>(If you are sticking relatively closely to the confines of the standard
language, then INCLUDE is pretty much how you have to do generic
containers today, and it is certainly not without its issues. Sad but
true. Going beyond standard source code as input - there are
preprocessor style options too.)

I wrote my own pre-processor (that is foss obviously) just for this reason: we are talking about improving the language or about workarounds?

>I don't want a new container, I want language features that let me (or
third parties) write portable source code that specifies the
characteristics and requirements of specific containers, and then lets
me easily use those containers.

>I don't want *a* container, I want practical access to *any* container.

Wonderful, where I have to sign? I agree, the access to any container is my dream, currently we still have not access to a generic list.

>If a compiler vendor chooses to conveniently package libraries with
their compiler that provide a set of containers ready for me to use
(like compiler vendors commonly package numeric libraries), that's
great, it will be one of the things that sways my decision about which
vendor to use.

I disagree. I select the standard and then the best (for me) compiler that supports this standard. I dislike vendors' extensions.

>If there is some common agreement about the interface of
those libraries to further promote code portability, perhaps even going
as far as another part of the standard like ISO_VARYING_STRING, that's
fantastic. But I don't see the need to hardwire the specific containers
into the language as intrinsic types or whatever.

You do not see the need, but I (and many other) see it

My best regards.

Richard Maine

unread,
Jun 20, 2016, 1:03:47 AM6/20/16
to
Stefano Zaghi <stefan...@gmail.com> wrote:

> >I was contrasting the effort required for changes to the language (and
> >therefore all compilers implementing the language) with the effort
> >required to write a source code library.
>
> This was clear to me, less for Richard.

I prefer to speak for myself about what I understand. I am *VERY*
certain I understood what Ian was saying. I also agreed with it.

Stefano Zaghi

unread,
Jun 20, 2016, 3:51:03 AM6/20/16
to
Dear Richard, my apologize for my bad words.

Il giorno lunedì 20 giugno 2016 03:22:52 UTC+2, Richard Maine ha scritto:
> Yes, I read at least Stefano as asking for specific containers like
> lists. That's why I reacted negatively to his post. Perhaps there might
> be some language difficulty (as in Italian vs English) in my
> interpreting what he said.

I am very sorry for my bad English, I will try to improve it as soon as possible, as far as I will able to arrive.

> I had about decided to stop replying to this thread based on that. I
> don't think a standardized list facility is desirable, and I don't think
> it is going to happen either, so I figure that debating it is just a
> waste of time and quickly turns personal.

It is very difficult to be not personal when we talking about our desiderata. You are the first that introduced "personal comments" saying that "I surely do not see the big picture". It happens often that if someone post comments contrary to your view you quickly stop "to wast your time replaying". I take in great consideration your thought, I am very sorry to read that you do not want debate on opinions different from yours. I am not Robin, I am not a troll. I always to try to be kind, in the limits of my poor English.

> Now if someone has good ideas on how the base language can better
> facilitate users doing such structures, that's a completely different
> matter.

I think that generic container greatly improve the language, you do not. I tried to replicate to your reasons, you simply said that you do not wast your time...

> I rather wonder if there might be some arguing at cross-purposes going
> on because different people have different readings as to what is even
> being discussed.

I surely do not completely understand your words: please, take the time to expose them differently so that also a poor man like me can follow your light. I am very open-minded, if you can clarify why having generic containers is a wrong dream I will happy to learn new things.

>I prefer to speak for myself about what I understand. I am *VERY*
certain I understood what Ian was saying. I also agreed with it.

My sincere apologizes, it far from to speak for you. Simply, you when replaying to me have attribuited to me words like "easy, cheap and fast", that was originally of Ian... surely you are more plenty of "certainties" than me.

I hope to read your explanations why generic containers are bad.

My best regards.

P.S. note that I always replay with kindness, apologizing for my errors, but I never read one of your replay doing the same. Evidently, my time can be wasted more likely than your.

Marco

unread,
Jun 20, 2016, 4:34:34 AM6/20/16
to
I agree on this and my impression is that what I need here are
essentially two specific things:

1) the ability of saying that two polymorphic objects have the same
dynamic type, like

subroutine multiply( res , a , b )
class(t_vector) :: a
type( the_same_dynamic_time_as_a ) :: b, res

2) something like Haskell type classes or Java interfaces, which let a
user specify that his type t_my_type implements the same interface
as the library required t_vector class, without having t_my_type
extending t_vector, which would be a problem if there are many
independent libraries (multiple inheritance) or if the user does not
completely control the base type.

I think Fortran already has a small bit of both: parametrized derived
types and abstract interfaces. However, types can be parametrized only
with respect to integers and abstract interfaces are for procedures,
not for classes.

Marco

Wolfgang Kilian

unread,
Jun 20, 2016, 10:13:03 AM6/20/16
to
Let me add that I would use any list facility in Fortran if it was
standardized and convenient to use. But I wouldn't feel so comfortable
doing this because an isolated solution for lists (etc.) appears like a
wasted opportunity.

In the past, fundamental improvements in Fortran did last, while some of
the isolated solutions have not been so successful.

-- Wolfgang


Wolfgang Kilian

unread,
Jun 20, 2016, 10:36:27 AM6/20/16
to
Thanks for this detailed explanation.

Regarding the topic of this thread, some of the posters might be
interested in past (or recent?) concrete proposals about introducing
(strongly typed) generic programming/data containers in Fortran. The
problem has been repeatedly discussed in this group, but let's be
concrete: there are parameterized derived types, which address only part
of the issue. I remember that there has been a proposal about
parameterized modules which did not make it into the standard. Anything
else?

I assume that this has not been a topic in recent meetings, and I don't
expect any such fundamental change to be injected into F2017 anyway.
But if anybody is planning to prepare some more concrete concept about
such a feature (Ian?) for future updates, it might be useful to have a
summary about any previous proposals and their fate.

-- Wolfgang


Damian Rouson

unread,
Jun 20, 2016, 10:37:17 AM6/20/16
to
There are members of the committee who are supportive of the idea of adding some form generic containers to the language when the appropriate time comes. The committee voted last year that no new features will be considered before 2017. The first J3 meeting of each year typically happens in February so that is the earliest possible date for entertaining new features. Sometime before the February 2017 date, I'd like to circulate a user survey to provide input to the committee. If I ventured a guess about the response, I would guess that most users who are familiar with generic programming would like to see expanded support for generic programming in Fortran.

My personal desire for more generic programming comes primarily from the experience of writing a library in which I have to either restrict users's choices of types or handle the combinatorial explosion of all possible types. At least the latter approach can be handled with a conditional compilation tool, which makes it especially frustrating that conditional compilation support was removed from the standard.

I also know that there are members of the committee who would support an enhancement of interfaces. Again speaking for myself, I would like to have something similar to java's capability in which multiple inheritance is disallowed, but implementing multiple interfaces is allowed. Possibly those interfaces could be inherited from abstract derived types, but I'll admit to not having thought through the details yet, partly because the time for considering new features has not yet come.

I will also echo Stefano's sentiments regarding the strident tone of posts here. As I have commented before, this forum is frequently harsh to the point that I sometimes avoid contributing specifically for that reason and I know others who won't contribute here at all here for similar reasons. To those interested in more civil venues, I'd recommend the Fortran Programmers LinkedIn group. Traffic has been low on that list lately, but every discussion I can recall there has remained civil and helpful.

Anton Shterenlikht

unread,
Jun 20, 2016, 10:51:26 AM6/20/16
to
Damian Rouson <dam...@rouson.net> writes:

>I will also echo Stefano's sentiments regarding the strident tone of posts =
>here. As I have commented before, this forum is frequently harsh to the po=
>int that I sometimes avoid contributing specifically for that reason and I =
>know others who won't contribute here at all here for similar reasons. To t=
>hose interested in more civil venues, I'd recommend the Fortran Programmers=
> LinkedIn group. Traffic has been low on that list lately, but every discu=
>ssion I can recall there has remained civil and helpful.

I don't recognise "harsh" in comp.lang.fortran,
but I can only speak for myself, of course.

I'd like to add that, for various reasons,
comp-fortran-90 mailing list
(https://www.jiscmail.ac.uk/cgi-bin/webadmin?A0=comp-fortran-90)
seems to be better represented by current long
serving committee members. (Perhaps there is an
impression that comp.lang.fortran is more for
discussing the usage of existing features and
for helping new users, whereas comp-fortran-90
is more for expert users thinking about the
future. I'm just speculating. I have no direct evidence.)
So if somebody wanted to get in touch with
many committee members directly,
specifically to start a discussion of a desired feature,
I'd suggest that comp-fortran-90 might be more fruitful.

However, even the most expertly researched and
prepared proposals can be rejected by the commitee.
Just think of the very old proposal to add physical
units to the standard.

I guess if you really want to push your agenda forward,
you might eventually find yourself on the committee,
putting your argument in the committee mailing lists
and at the meetings.

Anton

Stefano Zaghi

unread,
Jun 20, 2016, 10:56:57 AM6/20/16
to
Dear Damian and all other,

I think that most part of the reasons of the "not so kind tone" here is due to my fault, I can only apologize myself for my bad "expressing". I was driven on the wrong way by the theory that "I just want to take advantage of the work of committee for avoid to develop libraries by my hands"...

Aside the tone used, I still feel that the reasons to avoid to discuss about generic containers are "weak". I would like to discus about them, not about my bad personality.

If the reason to avoid discussion about generic containers is "it is better to improve other facilities to obtain real genericity" I agree. On the contrary, I disagree the statements like "libraries can already do this (even better)", as much as "the old era of dealing with string without character" is not better than the era when "character" was introduced.

My best regards.

Richard Weed

unread,
Jun 20, 2016, 11:13:49 AM6/20/16
to
It appears that the main objections to my original posts
are due to the word "intrinsic". I would be perfectly
happy with a separate facility like ISO_VARYING_STRING
defined in a Technical Specification if I had some faith
that the compiler vendors would actually implement them.
As far as I know, the standard does not compel compiler
developers to implement anything that is not in the
standard document. Even then the standard is just a
suggestion as to what functionality and programming
interfaces should be provided to the user. Other than
being able to say "we conform to the standard" there
is nothing that requires the developers to implement
anything in the standard.

As to the need for a native (if you prefer that word to
intrinsic) facility for handling ADTs, one of the primary
reasons that most of the new development in the Finite Element
community moved to C++ was the availability (through the STL
and other libraries) of a consistent transportable way of
creating things like lists etc. that would work (most of the time)
with any C++ compiler. I really don't understand the resistance
to implementing a similar capability in Fortran. Richard Maine
commented on the dwindling number of people on the committee.
I suspect that has probably reduced the input from people
who see the language from an end user perspective and not
and not from a compiler developer one. It seems that a common
excuse as to why something can't be implemented is that it is
to hard or the language is already too bloated and complicated.
I just don't see those as valid excuses for excluding things that
would make the users life easier. If the attitude I sense from
some on this group had persisted in my profession (Aerospace Engineer)
we would have never gone to the moon, built the Space Shuttle
and Mach 3 plus aircraft, or sent robotic probes to explore the
solar system and beyond. Just because something is hard doesn't
mean it shouldn't be done.

I agree with Richard that it would have been better to put some
things on a slower track. I also think that would have happened if
the developer community had allowed the users to define what they
thought was important and not what a few members on the standards
committee thought was needed to make the language competitive with
C++ or other languages. While I applaud the committee for adding
things like coarrays and object-oriented programming, I don't think
the user community would have placed as high a priority on their
implementation a did the standards committee.

Again all I'm really asking for is native support in the language
for common programming tasks that doesn't require me to
rely on third party libraries or reinventing the wheel.

Wolfgang Kilian

unread,
Jun 20, 2016, 11:17:05 AM6/20/16
to
On 06/20/2016 04:51 PM, Anton Shterenlikht wrote:
> Damian Rouson <dam...@rouson.net> writes:
>
>> I will also echo Stefano's sentiments regarding the strident tone of posts =
>> here. As I have commented before, this forum is frequently harsh to the po=
>> int that I sometimes avoid contributing specifically for that reason and I =
>> know others who won't contribute here at all here for similar reasons. To t=
>> hose interested in more civil venues, I'd recommend the Fortran Programmers=
>> LinkedIn group. Traffic has been low on that list lately, but every discu=
>> ssion I can recall there has remained civil and helpful.

Not everybody likes social-media channels ... (yes, a newsgroup like
this one is reminiscent of stone-age internet)

>
> I don't recognise "harsh" in comp.lang.fortran,
> but I can only speak for myself, of course.

Harshness on c.l.f. is not even noticeable compared to the typical open
Internet forum of 2016.

>
> I'd like to add that, for various reasons,
> comp-fortran-90 mailing list
> (https://www.jiscmail.ac.uk/cgi-bin/webadmin?A0=comp-fortran-90)
> seems to be better represented by current long
> serving committee members. (Perhaps there is an
> impression that comp.lang.fortran is more for
> discussing the usage of existing features and
> for helping new users, whereas comp-fortran-90
> is more for expert users thinking about the
> future. I'm just speculating. I have no direct evidence.)
> So if somebody wanted to get in touch with
> many committee members directly,
> specifically to start a discussion of a desired feature,
> I'd suggest that comp-fortran-90 might be more fruitful.

Oh, thanks for pointing this out. I didn't know that that group is
alive - Fortran 90 is distant past, isn't it? :-)

>
> However, even the most expertly researched and
> prepared proposals can be rejected by the commitee.
> Just think of the very old proposal to add physical
> units to the standard.
>
> I guess if you really want to push your agenda forward,
> you might eventually find yourself on the committee,
> putting your argument in the committee mailing lists
> and at the meetings.
>
> Anton

Does require some extra travel money, though.

-- Wolfgang

Wolfgang Kilian

unread,
Jun 20, 2016, 12:03:28 PM6/20/16
to
On 06/20/2016 05:13 PM, Richard Weed wrote:
> It appears that the main objections to my original posts
> are due to the word "intrinsic". I would be perfectly
> happy with a separate facility like ISO_VARYING_STRING
> defined in a Technical Specification if I had some faith
> that the compiler vendors would actually implement them.

I do use ISO_VARYING_STRING all the time, but that might be an
exception. I don't know of a vendor who implements the module natively.

> As far as I know, the standard does not compel compiler
> developers to implement anything that is not in the
> standard document. Even then the standard is just a
> suggestion as to what functionality and programming
> interfaces should be provided to the user. Other than
> being able to say "we conform to the standard" there
> is nothing that requires the developers to implement
> anything in the standard.

I think that all vendors are heading towards complete F2008 now, but
their resources are limited. Fortran is important (to me, at least) but
it is a niche product, even if the absolute number of users is not small.

>
> As to the need for a native (if you prefer that word to
> intrinsic) facility for handling ADTs, one of the primary
> reasons that most of the new development in the Finite Element
> community moved to C++ was the availability (through the STL
> and other libraries) of a consistent transportable way of
> creating things like lists etc. that would work (most of the time)
> with any C++ compiler. I really don't understand the resistance
> to implementing a similar capability in Fortran. Richard Maine
> commented on the dwindling number of people on the committee.
> I suspect that has probably reduced the input from people
> who see the language from an end user perspective and not
> and not from a compiler developer one. It seems that a common
> excuse as to why something can't be implemented is that it is
> to hard or the language is already too bloated and complicated.
> I just don't see those as valid excuses for excluding things that
> would make the users life easier. If the attitude I sense from
> some on this group had persisted in my profession (Aerospace Engineer)
> we would have never gone to the moon, built the Space Shuttle
> and Mach 3 plus aircraft, or sent robotic probes to explore the
> solar system and beyond. Just because something is hard doesn't
> mean it shouldn't be done.

I'm writing C++ code only occasionally, but the STL (the containers, in
particular) is so convenient that it's appearing everywhere, even in my
code.

Fortran is definitely in need of a facility that parallels the STL. I
think the reluctance is not due to Fortran being bloated, but because
the STL/templates also carries a bad reputation as a feature that is not
well designed. Templates are somewhat in-between of a macro facility
and a language intrinsic, and some people may argue that it exhibits the
flaws of both. A language designer might fear the effort to do this
right the next time, not opening a can of worms.

> I agree with Richard that it would have been better to put some
> things on a slower track. I also think that would have happened if
> the developer community had allowed the users to define what they
> thought was important and not what a few members on the standards
> committee thought was needed to make the language competitive with
> C++ or other languages. While I applaud the committee for adding
> things like coarrays and object-oriented programming, I don't think
> the user community would have placed as high a priority on their
> implementation a did the standards committee.

The Fortran OO facility, at least, is lightweight and suprisingly well
done. For instance, unlike C struct / C++ class, it works on the level
of Fortran 90 derived types and classic Fortran procedures. The
classical design patterns can be implemented flawlessly, and it is very
robust against typical coding errors. You can translate OO patterns of
other languages literally (or even better), if you like. Design by
committee does succeed, occasionally.

> Again all I'm really asking for is native support in the language
> for common programming tasks that doesn't require me to
> rely on third party libraries or reinventing the wheel.

Yes.

-- Wolfgang

Wolfgang Kilian

unread,
Jun 20, 2016, 12:22:29 PM6/20/16
to
On 06/20/2016 04:37 PM, Damian Rouson wrote:
> There are members of the committee who are supportive of the idea of adding some form generic containers to the language when the appropriate time comes. The committee voted last year that no new features will be considered before 2017. The first J3 meeting of each year typically happens in February so that is the earliest possible date for entertaining new features. Sometime before the February 2017 date, I'd like to circulate a user survey to provide input to the committee. If I ventured a guess about the response, I would guess that most users who are familiar with generic programming would like to see expanded support for generic programming in Fortran.
>
> My personal desire for more generic programming comes primarily from the experience of writing a library in which I have to either restrict users's choices of types or handle the combinatorial explosion of all possible types. At least the latter approach can be handled with a conditional compilation tool, which makes it especially frustrating that conditional compilation support was removed from the standard.
>
> I also know that there are members of the committee who would support an enhancement of interfaces. Again speaking for myself, I would like to have something similar to java's capability in which multiple inheritance is disallowed, but implementing multiple interfaces is allowed. Possibly those interfaces could be inherited from abstract derived types, but I'll admit to not having thought through the details yet, partly because the time for considering new features has not yet come.

My impression is that an 'interface' is the sort of construct that you
need for specifying the constraints on the actual type that corresponds
to an abstract type in generic code. It should be discussed in the same
context.

(I'm not sure if the term 'interface' is a good choice here, it has
quite a few disconnected uses in Fortran already. OK, there is no
interface block with a type enclosed.)

-- Wolfgang

FortranFan

unread,
Jun 20, 2016, 12:50:21 PM6/20/16
to
On Monday, June 20, 2016 at 11:13:49 AM UTC-4, Richard Weed wrote:

> It appears that the main objections to my original posts
> are due to the word "intrinsic". I would be perfectly
> happy with a separate facility like ISO_VARYING_STRING
> defined in a Technical Specification if I had some faith
> that the compiler vendors would actually implement them.
> ..
>
> Again all I'm really asking for is native support in the language
> for common programming tasks that doesn't require me to
> rely on third party libraries or reinventing the wheel.

@Richard Weed,

It's almost as if you're speaking my mind on this issue, quite eerie since I'm completely certain we've never met! See this link for a thread I had initiated on generic types last September:

https://groups.google.com/forum/#!searchin/comp.lang.fortran/generic$20types$20anyone/comp.lang.fortran/R_zBfQKmcHE/5a_KthCMBgAJ

Also, see my comments on Stefano Zaghi's wonderful work on a string library here:
https://groups.google.com/forum/#!searchin/comp.lang.fortran/zaghi$20string$20foss/comp.lang.fortran/qONziG36nFs/VY01aldiBQAJ

You'll see my comments on containers as well as string facilities in the form of "INTRINSIC derived types" (that will preferably have type-bound procedures) in the above two threads match closely with what you're stating in this thread.

Generally I'm in agreement with everything you are suggesting for the next revision of the Fortran standard. Fyi, nearly 2-3 years ago I suggested on this forum a standardized format for MOD file, perhaps based on XML markup (say text-based, possibly compressed even): I will try to look up the thread and if I find it, I'll post the link to it on this thread.

Good luck with all your effort and hopefully, coming from you, it will gain traction along with support from brilliant, eager, open-minded, forward-thinking scientists such as Stefano Zaghi. May be you will even join the committee and steer the effort in the right direction. I've entirely failed in influencing anyone anywhere, particularly on this forum, got a distinct feeling of generally being shot down and getting only brickbats for any thoughts and suggestions, the "usual" responses are as if "no new idea shall go unpunished" as can be noticed in the discussion on the above link with the thread I had started on "Generic Types, anyone!"; it is as if there is a heavy undercurrent of sufferance by NIH syndrome in the comments (https://en.wikipedia.org/wiki/Not_invented_here). But I have concluded the true problem is indeed me and my limited understanding and I better to do the one thing I've complete control over which is to remove my hand which seems to "spoil the broth. So I'm currently striving hard to withdraw myself from the Fortran world, my nom de plume notwithstanding. I sincerely hope and wish for you to achieve the total opposite of me, i.e., complete success in your vision for Fortran.

Kind regards,

Richard Weed

unread,
Jun 20, 2016, 1:12:55 PM6/20/16
to
Wolfgang

A few more points regarding native support support for an STL like
facility in Fortran. First I'm not advocating anything that looks
like templates in C++. I want some of the functionality they provide
but think there are better ways to provide it than a preprocessor/macro
like approach. Actually, (again in the specific case of lists etc.) a
well thought out Fortran specific solution that fits the language
would greatly reduce the requirement for anything that looks like
templates since I would be willing to bet that the ADT support in
the STL library is one of the most heavily used facilities.

Damien Rouson and others have pointed out the need for greater support
for generic programming. I agree that is needed. Another reason
that the Finite Element community moved to C++ was the availability of
facilities that supported generic programming that greatly reduced the
number of lines of code needed to implement a particular capability.
Talk to a someone who is developing a scientific application in C++
and one of the the first things they will bring up is they can
implement something in a few hundred lines of code that might take
thousands of lines in Fortran. Also in the case of scientific programming,
static polymorphism along with aggregation and composition are much more
important than pure inheritance and dynamic polymorphism. For many tasks,
an object based approach is just as acceptable (and a lot less prone
to errors) as a pure object oriented one and Fortran has supported
object based programming since Fortran 90/95. This has been demonstrated
several times over the past twenty or so years in books, papers, and
dissertations. What is really missing is something that reduces the
amount of lines of code that you have to write to implement what
are now accepted as common programming tasks required to implement
modern algorithms in areas like CFD and CSM. While others might think
that the situations where lists are needed don't constitute
a large fraction of the code base or consume a lot of cycles,
they can be critical to making your code work in the most efficient
manner or making it work at all.





Marco

unread,
Jun 20, 2016, 1:49:16 PM6/20/16
to
Richard, I am following this discussion with lot of interest. I wonder
if you or anybody else could point to some algorithm, together with an
implementation, that demonstrates something that you need, that you
find difficult to implement in Fortran and that can be done more
easily in another language.

I am thinking here about something that can be expressed within a
modest number of code lines, so that it would be possible for people
to read it - just mentioning library XYZ would not work.

I think that such an example could really help this discussion, tying
it to specific language elements and programming paradigms.

(I could maybe come up with such examples myself, but I am sure you
have something specific in mind and would really like to see this
discussion focusing on some concrete example).

Marco


Anton Shterenlikht

unread,
Jun 20, 2016, 2:44:13 PM6/20/16
to
Wolfgang Kilian <kil...@invalid.com> writes:

>Oh, thanks for pointing this out. I didn't know that that group is
>alive - Fortran 90 is distant past, isn't it? :-)

The list started a long time ago, hence the name.
But the contents are fully up to date, 2015 and beyond.

>> I guess if you really want to push your agenda forward,
>> you might eventually find yourself on the committee,
>> putting your argument in the committee mailing lists
>> and at the meetings.
>>
>> Anton

>Does require some extra travel money, though.

Yes, this is a barrier.

I don't have a good solution for this.

Anton

GianLuigi Piacentini

unread,
Jun 20, 2016, 3:23:32 PM6/20/16
to
Dear all,

some time ago it happened that I needed a list container for a derived type,
so I searched around.
I found that Ada has several of such facilities. Now, I only know Ada by
fame, but it seemed to me that none of them is an 'intrinsic', all are
libraries, taking advantage of the generic capabilities of that language.
It's a lot of time that Ada is around, and seems to me that Fortran borrowed
some ideas from it. Why not go further and borrow generics too ?


Just my 2 cent

Gigi

PS. I ended with an array, used with an interface that resembles a list...
And genericity is by text substitution...I do not see evil in that.

fj

unread,
Jun 20, 2016, 3:48:55 PM6/20/16
to
> I also know that there are members of the committee who would support an enhancement of interfaces. Again speaking for myself, I would like to have something similar to java's capability in which multiple inheritance is disallowed, but implementing multiple interfaces is allowed. Possibly those interfaces could be inherited from abstract derived types, but I'll admit to not having thought through the details yet, partly because the time for considering new features has not yet come.

I agree with this one. JAVA interfaces are really an interesting feature : making possible to group together objects which behave in the same way but which do not necessarily share the same data.

herrman...@gmail.com

unread,
Jun 20, 2016, 4:19:43 PM6/20/16
to
On Monday, June 20, 2016 at 12:48:55 PM UTC-7, fj wrote:

(snip)
> I agree with this one. JAVA interfaces are really an interesting feature : making
> possible to group together objects which behave in the same way but which do
> not necessarily share the same data.

More specifically, interfaces describe the methods but not an implementation.

The List interface has methods like add, clear, isEmpty, and remove.

Some classes that implement List are LinkedList, ArrayList, and Stack.

Even though a stack is normally FIFO, the Java Stack allows one to insert or remove
items other than from the ends. On the other hand, it might not to that efficiently.

You can write a program for the List interface, and then choose later:

List l=new ArrayList(); or List l=new LinkedList();

But as for the OP, this is all not part of the Java "language".

There are some classes in java.lang that one might say are part of the language,
that you wouldn't do without, such as java.lang.Math, where routines like sqrt() and sin() are.

But List is in java.util, so distributed with the usual downloads, but not part of the
language otherwise.

It would, however, be silly for someone to write a different List interface, using methods
with different names. On the other hand, one could implement LinkedList different from
the Sun/Oracle version. It might be more or less efficient, but would accept the same
method calls.

fj

unread,
Jun 20, 2016, 4:38:49 PM6/20/16
to
Le lundi 20 juin 2016 22:19:43 UTC+2, herrman...@gmail.com a écrit :
> More specifically, interfaces describe the methods but not an implementation.

I remember having tried to convince Fortraners about the necessity to implement something like JAVA interfaces, but without great success...

Just search for "Implementing JAVA interfaces in FORTRAN 20xx" on comp.lang.fortran; a post written in 2008.

Wolfgang Kilian

unread,
Jun 20, 2016, 5:36:40 PM6/20/16
to
That sounds very familiar. Nevertheless, C++ has its well known
inherent problems and inconveniences -- at least, that's my personal
impression, otherwise I also would have switched long ago.

It's interesting that you mention aggregation - another area where some
small extension to Fortran syntax could improve usability by a big
margin. Say delegation of methods to object components other than the
base type.

Code size reduction: STL aside, C++ is also intrinsically less verbose
in syntax. But this is a mixed blessing ...

-- Wolfgamg


JB

unread,
Jun 21, 2016, 3:35:05 AM6/21/16
to
On 2016-06-19, Stefano Zaghi <stefan...@gmail.com> wrote:
> There are many cases where ADT is helpful, to cite just one I could say that re-invent the wheel is a bad programming approach. List/tree of abstract, etherogeneous data is very very helpful (in my peculiar work for adaptive mesh refinement): having a builtin intrinsic list or tree is convenient as having arrays. Do you think that arrays facilities can be cinvenient trimmed out from built-ins and left to external libraries?

How about a little thought exercise?

1. If the language didn't have arrays as a fundamental builtin type,
how would you implement an array? Lets not worry about the syntax, but
just the semantics, i.e. the usual properties we consider arrays to
have, e.g. dense storage, adjacent elements are adjacent in memory,
the usual big-O properties etc.?

2. What about the same with linked lists?


I claim that 1. is not possible. Especially since, if the language
didn't have arrays, it certainly wouldn't have any mechanism to
allocate a big chunk of memory either. OTOH, for 2., once you have
record types (derived types in Fortran) and pointers implementing a
linked list in Fortran code with the same semantics as a hypothetical
builtin linked list is straightforward. What's missing is just a way
to make the list generic, so you don't have to play with INCLUDE
tricks or such.

Now, you could say there is a case for having special syntax for
dealing with lists, such as Lisp, Haskell, python etc. I'm somewhat
more symphatetic to that argument, but the counter argument would
perhaps be that lists aren't usually such a fundamental data structure
in the problem domains Fortran is usually used for and thus don't
deserve their own syntax.


--
JB

Wolfgang Kilian

unread,
Jun 21, 2016, 7:20:36 AM6/21/16
to
If lists were implemented in a similar way as ADT etc. are available in
various other languages, you might encounter syntax like

use generic_fortran_container_module, only: list
...
type (list (real(dp))) :: data_list
...
call data_list%append (1.3_dp)

which would be both expressive and convenient. I'd also expect some
sort of transformation methods from/to array ['from' can be bound to
assignment] and some iterator type for scanning the list, say

type (list_iterator (real(dp))) :: data_it
...
list = [1.0_dp, 2.0_dp]
...
call data_it%init (data_list)
call data_it%print ()

etc. etc.

Is there any need for more special syntax?

Arrays are special becaus of direct access a(:). Direct access is
usually neither desired nor efficient for other types of container.

-- Wolfgang

JB

unread,
Jun 21, 2016, 9:31:23 AM6/21/16
to
I think that looks reasonable for Fortran, no argument there. With
special syntax support for lists, I was thinking of something like you
see in the languages I mentioned above. E.g.

list(read(dp)) :: data_list, another_data_list
data_list = {1.0_dp, 2.0_dp}
another_data_list = data_list:1.3_dp

(Using {} here because IIRC [] is already taken for array
constructors). Probably ":" for appending/prepending is also a bad
choice for similar reasons, clashes with array indexing.

> which would be both expressive and convenient. I'd also expect some
> sort of transformation methods from/to array ['from' can be bound to
> assignment] and some iterator type for scanning the list, say
>
> type (list_iterator (real(dp))) :: data_it
> ...
> list = [1.0_dp, 2.0_dp]
> ...
> call data_it%init (data_list)
> call data_it%print ()
>
> etc. etc.

Awfully verbose, and specific; Is "print" a method of list_iterator?
What if you want to do something else? Should list_iterator have
methods for everything you might want to do with a list element?

What about stealing from Haskell:

map(print *, data_list)

This doesn't work in Fortran since "print" is a statement and not an
expression. Gah, oh well. And how can the map procedure know how to
iterate over data_list? Of course, if lists are builtin to the
language, then one can define it to work for lists, period. But if one
is going to do something like this, one might as well do it properly,
and make it usable for stuff like arrays and user defined data
structures? Again, taking a hint from Haskell, one can define a
"Functor" type class (~interfaces in stuff like Java), that data
structures that one can map over must implement.

Well, turning Fortran into Haskell is maybe biting into a bit too
much. But for something a little bit closer to Fortran style
imperative languages, lets steal from Rust instead:

do element in data_list
print *, element
end do

Where now data_list must implement the "Iterator" trait. Very roughly,
traits in Rust ~ type classes in Haskell ~ interfaces in Java.

> Is there any need for more special syntax?

Well, I'm not arguing Fortran actually should have special syntax for
lists. So what I think would be useful:

- Generics.
- Type classes, traits, or whatever you want to call them, are a
powerful concept.
- And, once you have type classes some kind of loop construct to walk
through all elements in a data structure without having to manually
index or walk pointers, would be nice.


--
JB

Richard Weed

unread,
Jun 21, 2016, 10:10:01 AM6/21/16
to
What Wolfgang outlines here is along the lines of what I was
thinking a list facility in Fortran should look like and
would be my preferred approach.

An alternative one would be to mimic the current string facilty in Fortran.
Its easy to think of strings as a list of characters.
Borrowing from Wolfgangs example you might then have something
like

data_list = 1.0 ! initial reference
data_list = data_list//3.0 ! append to end
data_list = 3.0//data_list ! prepend to start

Iterating throught the list could then be done on an index
I = list_index(data_list, value=3.0)
data_list = data_list(I)//4.0

etc.

I would also like to point out (to my mind) a very important
reason for providing a native list (and other ADTs) facility.
One of the biggest sources of error in creating and navigating
linked list is the need for recursive pointers to next and/or
previous values. Anything that hides the pointers from the user
and relieves him or her of the responsibility of keeping up
with their usage will greatly reduce things like memory leaks
etc. that plague all pointer based operations.

Stefano Zaghi

unread,
Jun 21, 2016, 12:46:45 PM6/21/16
to
Il giorno lunedì 20 giugno 2016 18:50:21 UTC+2, FortranFan ha scritto:
>...
> Also, see my comments on Stefano Zaghi's wonderful work on a string library

Dear FortranFan you are too much kind. However, you are wrong, you have not failed, you have greatly inspired me as many others like Damian, Richard, Ian... I can say that even Robin teaches me to be more kind...

Il giorno lunedì 20 giugno 2016 19:49:16 UTC+2, m ha scritto:
> Richard, I am following this discussion with lot of interest. I wonder
> if you or anybody else could point to some algorithm, together with an
> implementation, that demonstrates something that you need, that you
> find difficult to implement in Fortran and that can be done more
> easily in another language.
>
> I am thinking here about something that can be expressed within a
> modest number of code lines, so that it would be possible for people
> to read it - just mentioning library XYZ would not work.

Dear Marco, I am not sure to accomplish task to be concise and readable, but I try.

At this link you can find the whole implementation of my "generic" (oc/quad)tree

https://github.com/szaghi/OFF/blob/testing/src/Data_Type_Tree.f90

It is essentially based on a hash table.

The "generic" data contained into a node is defined as

class(*), pointer:: d => null() !< Node data.


The full public API of the Tree is

type, public :: Type_Tree
private
type(Type_Tree_Node), allocatable:: ht(:)
integer(I4P):: leng = 0_I4P
integer(I4P):: ref_ratio = 0_I4P
integer(I4P):: ref_max = 0_I4P
integer(I8P), allocatable, public:: IDs(:)
integer(I8P), public:: ID = 0_I8P
type(Type_Tree_Connectivity), public:: connectivity
! parallel enabling data
integer(I4P), public:: myrank = 0_I4P
integer(I4P), public:: parts = 0_I4P
integer(I8P), allocatable, public:: First_IDs(:)
integer(I8P), allocatable, public:: Last_IDs(:)
contains
procedure :: hash
procedure :: init
procedure :: free
procedure :: node
procedure :: put
procedure :: get
procedure :: dat
procedure :: del
procedure :: length
procedure :: getIDs
procedure :: update
procedure :: loopID
procedure :: print
procedure :: parent_ID
procedure :: child_ID
procedure :: siblings_IDs
procedure :: child_number
procedure :: ref_level
procedure :: path_IDs
procedure :: first_ID
procedure :: last_ID
procedure :: get_max_level
procedure :: linearID
procedure :: exist_ID
procedure :: str_ref_ratio
final :: finalize_tree
! private procedures
procedure :: assign_tree
endtype Type_Tree

Excluding some peculiar methods devoted to the oc/quad nature of the tree, the other methods are the "classical" getters/setters ones. The problems come when dealing in concrete with the abstract data container defined into "Type_Tree_Node" the API of which is


type, public:: Type_Tree_Node
private
integer(I8P), allocatable:: ID
class(*), pointer:: d => null()
type(Type_Tree_Node), pointer:: next => null()
contains
procedure :: free
procedure :: node
procedure :: dat
procedure :: put
procedure :: get
procedure :: del
procedure :: length
procedure :: getIDs
procedure :: print
procedure :: parent_ID
procedure :: child_ID
procedure :: siblings_IDs
procedure :: child_number
procedure :: ref_level
procedure :: path_IDs
procedure :: max_level
final :: finalize_node
! private procedures
procedure :: assign_tree_node
endtype Type_Tree_Node

You already see the code-duplication that is very frustrating. To go in much details of the "bothering" issues I would like to consider the method "loopID" that is my poor replacement of the "in" iterator statement of Python. The "loopID" function is an impure function that return a logical (as a sentinel for a while loop) and the pointer to the current node-data, e.g. I can do something like

class(Type_Global) :: global
type(Type_Block_Dimensions), pointer :: blkdims
integer(I8P) :: ID

do while(global%block_dims%loopID(ID=ID))
blkdims => global%block_dims%dat(ID=ID)
blkdims%Np = global%species0%Np
blkdims%Nc = global%species0%Nc
blkdims%Ns = global%species0%Ns
enddo

where "loopID" return .true. or .false. for the while and also the update the curent ID value used to get the actual data.

Just this example shows that my approach has many "cons". In Python I can do something like

for blkdims in global.block_dims:
blkdims.Np = ...

The syntax is more concise and clear, but more importantly I have a real abstract container (not based in class(*) workaround). The worst thing is that the above snippet is not standard, the standard compliant version is even more verbose, I have to use "select type"...

As for the example of strings done without "character" type, I can do ADT tree without generic containers, but with a lot of work and in "poor" way.

Il giorno lunedì 20 giugno 2016 21:23:32 UTC+2, GianLuigi Piacentini ha scritto:
> PS. I ended with an array, used with an interface that resembles a list...
> And genericity is by text substitution...I do not see evil in that.

Dear Gigi, I am not sure to what you are referring when you allude to "text substitution", anyhow if you are talking about pre-processing the source exploiting macro expansions or similar, these are workarounds that are surely effective (I used this, I even wrote my own preprocessor), but I think here we are talking about how to improve the language.

Il giorno martedì 21 giugno 2016 09:35:05 UTC+2, JB ha scritto:
>...
> How about a little thought exercise?

Dear JB,

my statement was a provocation, I am conscious that we cannot have array out from the intrinsic. I would like to contrast the second part of your final statement, i.e. "he counter argument would perhaps be that lists aren't usually such a fundamental data structure in the problem domains Fortran is usually used for": the need for generic containers is great. Someone dislike to have generic containers into the intrinsic language (I have not completely understand all the reasons) and prefer to have them in "intrinsic module": I do not argue about this, I argue that the need of having a standard generic containers providing me features like I have in Python is a real, concrete desiderata.

My best regards.

herrman...@gmail.com

unread,
Jun 21, 2016, 1:08:46 PM6/21/16
to
On Tuesday, June 21, 2016 at 7:10:01 AM UTC-7, Richard Weed wrote:

(snip)

> An alternative one would be to mimic the current string facilty in Fortran.
> Its easy to think of strings as a list of characters.
> Borrowing from Wolfgangs example you might then have something
> like

> data_list = 1.0 ! initial reference
> data_list = data_list//3.0 ! append to end
> data_list = 3.0//data_list ! prepend to start

In Java, it looks like:

import java.util.*;

public class listtest {
public static void main(String args[]) {
List data_list=new LinkedList();
data_list.add(1.0f);
data_list.add(3.0f);
data_list.add(0,3.0f);
System.out.println(data_list);
}
}


(along with printing the resulting list)

> Iterating throught the list could then be done on an index
> I = list_index(data_list, value=3.0)
> data_list = data_list(I)//4.0

Java has iterators for iterating through Collections, but this isn't iteration.

l=data_list.indexOf(3.0f);

(There is also a lastIndexOf(), for when you need that.)

I am not sure what operation the last statement is supposed to be.

If you want to replace the element with the value 3.0f, that would be:

data_list.set(l,4.0f);

You could add a new element before or after with:

data_list.add(l,4.0f);

or

data_list.add(l+1,4.0f);

I don't know OO Fortran enough to write that.

Presumably one could translate the Java, though not test it, without an actual implementation
of a List class.

With all the above, it looks like:

import java.util.*;

public class listtest {
public static void main(String args[]) {
int l;
List data_list=new LinkedList();
data_list.add(1.0f);
data_list.add(3.0f);
data_list.add(0,3.0f);
System.out.println(data_list);
l=data_list.indexOf(3.0f);
data_list.set(l,4.0f);
data_list.add(l,4.0f);
data_list.add(l+1,4.0f);
System.out.println(data_list);
}
}





Wolfgang Kilian

unread,
Jun 21, 2016, 3:05:44 PM6/21/16
to
print was probably too specific. More like

element = data_it%get ()

Note that except for the type declaration -- a type depending on another
type -- all this is standard Fortran. (disregarding any typos)

>
> What about stealing from Haskell:
>
> map(print *, data_list)
>
> This doesn't work in Fortran since "print" is a statement and not an
> expression. Gah, oh well. And how can the map procedure know how to
> iterate over data_list? Of course, if lists are builtin to the
> language, then one can define it to work for lists, period. But if one
> is going to do something like this, one might as well do it properly,
> and make it usable for stuff like arrays and user defined data
> structures? Again, taking a hint from Haskell, one can define a
> "Functor" type class (~interfaces in stuff like Java), that data
> structures that one can map over must implement.

Lots of opportunities, but Fortran is not a functional language, so the
most economical ways of list handling (map, fold) won't fit.

>
> Well, turning Fortran into Haskell is maybe biting into a bit too
> much. But for something a little bit closer to Fortran style
> imperative languages, lets steal from Rust instead:
>
> do element in data_list
> print *, element
> end do

Another variant to DO ... this would at least fit as a language
extension. 90% of lists are probably scanned only sequentially. More
complicated scanning patterns (tree) require explicit iterators, still.

> Where now data_list must implement the "Iterator" trait. Very roughly,
> traits in Rust ~ type classes in Haskell ~ interfaces in Java.

>> Is there any need for more special syntax?
>
> Well, I'm not arguing Fortran actually should have special syntax for
> lists. So what I think would be useful:
>
> - Generics.
> - Type classes, traits, or whatever you want to call them, are a
> powerful concept.
> - And, once you have type classes some kind of loop construct to walk
> through all elements in a data structure without having to manually
> index or walk pointers, would be nice.

Yes. The latter point is an extra bonus, but I admit that a 'foreach'
loop or similar is very common in modern languages.

-- Wolfgang


JB

unread,
Jun 21, 2016, 3:49:41 PM6/21/16
to
On 2016-06-21, Stefano Zaghi <stefan...@gmail.com> wrote:
> Il giorno martedì 21 giugno 2016 09:35:05 UTC+2, JB ha scritto:
>>...
>> How about a little thought exercise?
>
> Dear JB,
>
> my statement was a provocation, I am conscious that we cannot have array out from the intrinsic. I would like to contrast the second part of your final statement, i.e. "he counter argument would perhaps be that lists aren't usually such a fundamental data structure in the problem domains Fortran is usually used for": the need for generic containers is great. Someone dislike to have generic containers into the intrinsic language (I have not completely understand all the reasons) and prefer to have them in "intrinsic module": I do not argue about this, I argue that the need of having a standard generic containers providing me features like I have in Python is a real, concrete desiderata.

I'm not arguing against generic containers. I imagine they would be
very useful. But, I believe the better approach to get them would be
if the language would provide constructs ("generics", or whatever you
want to call them) so that external libraries could provide
type-generic lists, trees etc., instead of building a type-generic
list (and tree? and something else?) into the language itself, without
the possibility for Fortran code to implement something equivalent
using the facilities provided by the language.

So whether one wants a minimal language with lots of needed and useful
functionality provided by external libraries, or a "batteries
included" approach such as python, is not a purely technical decision
that one can make in some kind of vacuum. For instance, for Java
Sun/Oracle could dedicate a 1000(?) full-time engineers to build a
massive standard library. However, the reality is that that kind of
money simply isn't available in the Fortran world. Add to that the
fact that Fortran is an ISO standard, and getting stuff into the
standard is expensive and time-consuming, and the implementation
effort to then actually implement the standard is multiplied over
several actively developed compilers. Contrast this again with Java,
where there is ~1 implementation, so in that sense no "wasted" effort.

Hence I think that one should think VERY carefully about adding stuff
to the Fortran standard. In particular, whether the proposed
functionality could be implemented using standard Fortran instead of
being builtin to the language. And if not, what is the minimum
required feature additions to the standard so that the desired
functionality could be implemented using standard Fortran. E.g.,
generics vs. having builtin every data structure under the sun.


--
JB

JB

unread,
Jun 21, 2016, 4:10:07 PM6/21/16
to
On 2016-06-21, Wolfgang Kilian <kil...@invalid.com> wrote:
> On 06/21/2016 03:31 PM, JB wrote:
>> On 2016-06-21, Wolfgang Kilian <kil...@invalid.com> wrote:
> Lots of opportunities, but Fortran is not a functional language, so the
> most economical ways of list handling (map, fold) won't fit.

Sure, I agree. The real trick, of course, isn't to point out that
"Ooh, language X has cool feature Y" but rather to produce something
which fits well into the existing Fortran language. Unfortunately, I
don't have any rabbits to pull out of my hat on this.

>> Well, turning Fortran into Haskell is maybe biting into a bit too
>> much. But for something a little bit closer to Fortran style
>> imperative languages, lets steal from Rust instead:
>>
>> do element in data_list
>> print *, element
>> end do
>
> Another variant to DO ... this would at least fit as a language
> extension. 90% of lists are probably scanned only sequentially. More
> complicated scanning patterns (tree) require explicit iterators, still.

I think the usefulness of such a do loop variant is dependent on
traits, otherwise you'd have to hardwire the syntax to only support a
few builtin types which isn't very satisfying.

E.g. in Rust anything which implements the "Iterator" trait can be
used in the "for e in collection" style loop.

So for instance, if you implement a tree type, you could implement the
Iterator trait as a, say, in-order left-right depth-first traversal.

Now, how to retrofit something like traits/type classes/interfaces/
into Fortran? No idea, sorry.


--
JB

Ian Harvey

unread,
Jun 21, 2016, 4:49:32 PM6/21/16
to
On 2016-06-21 2:03 AM, Wolfgang Kilian wrote:
> On 06/20/2016 05:13 PM, Richard Weed wrote:
>> It appears that the main objections to my original posts
>> are due to the word "intrinsic". I would be perfectly
>> happy with a separate facility like ISO_VARYING_STRING
>> defined in a Technical Specification if I had some faith
>> that the compiler vendors would actually implement them.

The use of the word intrinsic certainly confused me. In the context of
a type it means to be built in like the INTEGER and REAL types - the
type never has to be defined, it is always available, and you can often
do special things with it that you can't do with types defined in your
own source code. Similar magic in the context of procedure names,
intrinsic procedures very often have special powers that source code
written by mortals cannot duplicate.

I don't just want compiler provided containers, I want to be able to
easily write and use my own, and I want to be able to write and use
things that rely on the sort of generic programming capability that
not-built-in container support would require, but then use it for things
that don't look anything like containers.

> I do use ISO_VARYING_STRING all the time, but that might be an
> exception. I don't know of a vendor who implements the module natively.

I likewise used to use ISO_VARYING_STRING, prior to adequate support for
deferred length allocatable character from my preferred compiler.

I thought that worked quite well as a model - here is a specification
(but not implementation) of useful stuff provided in the form a module,
that reasonably could be expected to be implemented in the language of
the day (though I think ISO_VARYING_STRING actually required the
allocatable TR to do it right), and that:

- saved users from having to design such a specification themselves;

- perhaps saved users from having to implement such a specification
themselves, if they could find someone that had already done that job in
standard source code for them;

- helped interoperability between disparate sets of sources through The
specification of a common string type.

Even though ISO_VARYING_STRING is somewhat regarded as obsolete, given
deferred length character support in the language (from a current
language specification perspective, rather than user code), I still
think the last point is quite significant.

My compiler vendor could have provided me with an implementation of that
module installed with the compiler, perhaps one that even used compiler
specific stuff behind the scenes to make the module more efficient or
whatever, but they didn't (they may have provided a link to download a
third party implementation). But that really wasn't a problem - as
portable third party source code was available under appropriate terms
(and if it wasn't - I could probably have written that module myself).

Another model that is worth considering is that of the boost libraries
and their role in C++. They are a channel for community contributions
of peer reviewed, high quality, permissively licensed libraries that
help solve common programming tasks not dealt with by the standard C++
facilities of the day. In some cases, libraries that started out in
boost, after extensive production use, have then gone onto become part
of the C++ standard library with minimal changes.

(Some of the boost libraries deal with tasks that are not covered by
standard C++, so the source code for parts of those libraries is
inherently platform specific and has to deal with compiler specific
intricacies (including bugs). That means that building some boost
libraries is not as easy as "here is some source, just add it alongside
your current sources and compile it". Other parts of those libraries
are just standard source code.)

The benefit of this separate-but-related approach with these libraries
is in their ability to be much more responsive than an ISO language
standard committee process. The timescale of library specification and
implementation is decoupled from the timescale of standard development
and compiler implementation, the barriers to contribution are also much
lower, and the breadth of programmer needs that can be concurrently
addressed is much wider than it otherwise would be.

There are downsides to that approach, including that the libraries don't
necessarily come with your standard C++ compiler (but in many cases they
do - for example most linux distributions that I am aware of provide
those libraries). The more responsive nature also means that individual
libraries can change or come obsolescent faster than may be the case
under the standard process. But libraries that are comprised of
standard source code are likely to just be standard source code for
quite a long period.

>> As far as I know, the standard does not compel compiler
>> developers to implement anything that is not in the
>> standard document. Even then the standard is just a
>> suggestion as to what functionality and programming
>> interfaces should be provided to the user. Other than
>> being able to say "we conform to the standard" there
>> is nothing that requires the developers to implement
>> anything in the standard.
>
> I think that all vendors are heading towards complete F2008 now, but
> their resources are limited. Fortran is important (to me, at least) but
> it is a niche product, even if the absolute number of users is not small.

As you know, there is also a difference between where compilers intend
to be today in terms of standard support, and where they practically are
from the point of view of an end user, due to the reasonably chance that
newly implemented features in a compiler come with newly implemented
compiler bugs.

The timescales being seen with implementation of language features is
very clear evidence of the limited resources available, even after the
standard has been finalized.

>> As to the need for a native (if you prefer that word to
>> intrinsic) facility for handling ADTs, one of the primary
>> reasons that most of the new development in the Finite Element
>> community moved to C++ was the availability (through the STL
>> and other libraries) of a consistent transportable way of
>> creating things like lists etc. that would work (most of the time)
>> with any C++ compiler. I really don't understand the resistance
>> to implementing a similar capability in Fortran. Richard Maine
>> commented on the dwindling number of people on the committee.
>> I suspect that has probably reduced the input from people
>> who see the language from an end user perspective and not
>> and not from a compiler developer one. It seems that a common
>> excuse as to why something can't be implemented is that it is
>> to hard or the language is already too bloated and complicated.
>> I just don't see those as valid excuses for excluding things that
>> would make the users life easier. If the attitude I sense from
>> some on this group had persisted in my profession (Aerospace Engineer)
>> we would have never gone to the moon, built the Space Shuttle
>> and Mach 3 plus aircraft, or sent robotic probes to explore the
>> solar system and beyond. Just because something is hard doesn't
>> mean it shouldn't be done.

There are many additional aspects that could be addressed in the
language. There are many different options for how those aspects are
addressed. The issue is not whether some one thing is hard or easy, the
issue is what to do, and what not to do, in the face of limited resources.

> I'm writing C++ code only occasionally, but the STL (the containers, in
> particular) is so convenient that it's appearing everywhere, even in my
> code.
>
> Fortran is definitely in need of a facility that parallels the STL. I
> think the reluctance is not due to Fortran being bloated, but because
> the STL/templates also carries a bad reputation as a feature that is not
> well designed. Templates are somewhat in-between of a macro facility
> and a language intrinsic, and some people may argue that it exhibits the
> flaws of both. A language designer might fear the effort to do this
> right the next time, not opening a can of worms.

I am principally a C++ programmer these days. The STL isn't perfect,
but something doesn't have to be perfect to be a very, very useful tool
for programmers. Flaws in its design, or flaws more generally in C++'s
template feature, need to be kept in perspective.

You can look at some of the evolutionary directions of C++ to see where,
with the benefit of hindsight, they might have done things differently.
There are proposals around "concepts" - in recognition of the difficulty
that library code has had in specifying requirements on client types
used as template arguments. There have also been issues and changes
around export and extern templates. FortranFan recently posted a link
to the module proposal, which also has implications for how template
code is provided and consumed (it is also very much aimed at avoiding
problems with the C heritage preprocessor).

>> I agree with Richard that it would have been better to put some
>> things on a slower track. I also think that would have happened if
>> the developer community had allowed the users to define what they
>> thought was important and not what a few members on the standards
>> committee thought was needed to make the language competitive with
>> C++ or other languages. While I applaud the committee for adding
>> things like coarrays and object-oriented programming, I don't think
>> the user community would have placed as high a priority on their
>> implementation a did the standards committee.

Different people, different priorities.

> The Fortran OO facility, at least, is lightweight and suprisingly well
> done. For instance, unlike C struct / C++ class, it works on the level
> of Fortran 90 derived types and classic Fortran procedures. The
> classical design patterns can be implemented flawlessly, and it is very
> robust against typical coding errors. You can translate OO patterns of
> other languages literally (or even better), if you like. Design by
> committee does succeed, occasionally.

I think it was well done too, and my use of it is ubiquitous.

>> Again all I'm really asking for is native support in the language
>> for common programming tasks that doesn't require me to
>> rely on third party libraries or reinventing the wheel.
>
> Yes.

I want support in the language to permit me to not have to re-invent the
wheel, time and time again. But I am happy to invent the wheel once (or
pay someone else to invent it for me) - the wheel doesn't necessarily
have to be in the language. I might prefer wheels that have a bit more
flashy chrome than those that come standard, for example. If you do
bundle wheels with the language, make sure I can change them.

herrman...@gmail.com

unread,
Jun 21, 2016, 6:06:12 PM6/21/16
to
On Tuesday, June 21, 2016 at 1:49:32 PM UTC-7, Ian Harvey wrote:

(snip)
> The use of the word intrinsic certainly confused me. In the context of
> a type it means to be built in like the INTEGER and REAL types - the
> type never has to be defined, it is always available, and you can often
> do special things with it that you can't do with types defined in your
> own source code. Similar magic in the context of procedure names,
> intrinsic procedures very often have special powers that source code
> written by mortals cannot duplicate.

It used to be even less obvious. There used to be "intrinsic functions"
and "external functions". Intrinsic functions were usually (though not
required to be) generated inline by the compiler. INT and MOD are some
examples. Basic external functions came in a library and are usually
linked in with the object file, such as SIN and SQRT. (Strangely,
MOD and AMOD are intrinsic, while DMOD is basic external.)

In terms of actual Fortran code, this meant that some were available to use
as actual arguments and some were not.

> I don't just want compiler provided containers, I want to be able to
> easily write and use my own, and I want to be able to write and use
> things that rely on the sort of generic programming capability that
> not-built-in container support would require, but then use it for things
> that don't look anything like containers.

> > I do use ISO_VARYING_STRING all the time, but that might be an
> > exception. I don't know of a vendor who implements the module natively.

> I likewise used to use ISO_VARYING_STRING, prior to adequate support for
> deferred length allocatable character from my preferred compiler.

> I thought that worked quite well as a model - here is a specification
> (but not implementation) of useful stuff provided in the form a module,
> that reasonably could be expected to be implemented in the language of
> the day (though I think ISO_VARYING_STRING actually required the
> allocatable TR to do it right), and that:

> - saved users from having to design such a specification themselves;

> - perhaps saved users from having to implement such a specification
> themselves, if they could find someone that had already done that job in
> standard source code for them;

> - helped interoperability between disparate sets of sources through The
> specification of a common string type.

I am not so sure how ISO_VARYING_STRING works, but in Java the
classes like List and Stack are not part of the language. Specifically,
in Java terms, they are in java.util.* and not in java.lang.*.

There is an import java.util.*; at the top, which might have similarity to
the Fortran USE statement. (In the Sun/Oracle implementation, it reads the
needed data out of the compiled .class file or .jar, instead of a separate file.)

> Even though ISO_VARYING_STRING is somewhat regarded as obsolete, given
> deferred length character support in the language (from a current
> language specification perspective, rather than user code), I still
> think the last point is quite significant.

> My compiler vendor could have provided me with an implementation of that
> module installed with the compiler, perhaps one that even used compiler
> specific stuff behind the scenes to make the module more efficient or
> whatever, but they didn't (they may have provided a link to download a
> third party implementation). But that really wasn't a problem - as
> portable third party source code was available under appropriate terms
> (and if it wasn't - I could probably have written that module myself).

I am not so sure how the Sun open source license works, and even more,
how it works now that it is Oracle, but all this used to be open source.

-- glen

David Duffy

unread,
Jun 21, 2016, 8:50:18 PM6/21/16
to
Wolfgang Kilian <kil...@invalid.com> wrote:
> use generic_fortran_container_module, only: list
> type (list (real(dp))) :: data_list
> call data_list%append (1.3_dp)

This looks attractive, but I would think a homogenous type list like
this is very easy to implement via macro/preprocessing. And possibly
efficient for compiling?

I've previously pointed to the template language used for the
Inverse Ocean Modeling System:
http://journals.ametsoc.org/doi/full/10.1175/2008JTECHO519.1
which uses Haskell (!) as the meta-language to implement Fortran generics,
automatic differentiation etc. Sure it does require recompilation from job to
job, but the additions to the code look unobtrusive and easy to learn.

Another 2c, David Duffy.

herrman...@gmail.com

unread,
Jun 21, 2016, 10:15:16 PM6/21/16
to
On Tuesday, June 21, 2016 at 5:50:18 PM UTC-7, David Duffy wrote:
> Wolfgang Kilian <kil...@invalid.com> wrote:
> > use generic_fortran_container_module, only: list
> > type (list (real(dp))) :: data_list
> > call data_list%append (1.3_dp)

> This looks attractive, but I would think a homogenous type list like
> this is very easy to implement via macro/preprocessing. And possibly
> efficient for compiling?

Yes.

I have a few times written C programs that needed linked lists of some kind, where
each node held a small number of simple values, and it is very easy to do, often
using arrays.

In the Fortran 66 and 77 days, there were many data structures made out of a group
of arrays, where corresponding elements are one list item, and the list pointers are
array index values.

But you mention efficiency. If you need efficiency, yes a custom data structure
and methods is likely best, and not all that hard.

Often enough, though, it is out of the critical path, such that being slow really doesn't
effect the overall speed.

The Java HashTable and HashMap are reasonably efficient, and automatically
resize when necessary. Generating a fixed sized hash table isn't all that hard, but
auto resize is nice, though a little slower and less memory efficient.

One that I didn't explain about Java, when you do:

list.add(3.0f);

Java actually does:

list.add(new Float(3.0f));

as only objects can go into List. There are wrapper classes, Byte, Short, Char, Int,
Long, Float, Double, for all the primitive types. It used to be that you had to explicitly
create the wrapper object, but now the compiler can figure it out.

I have also put small arrays, even only one element, in hash tables, as arrays are
object in Java.

> I've previously pointed to the template language used for the
> Inverse Ocean Modeling System:
> http://journals.ametsoc.org/doi/full/10.1175/2008JTECHO519.1
> which uses Haskell (!) as the meta-language to implement Fortran generics,
> automatic differentiation etc. Sure it does require recompilation from job to
> job, but the additions to the code look unobtrusive and easy to learn.

-- glen

Ian Harvey

unread,
Jun 21, 2016, 11:45:11 PM6/21/16
to
I might be repeating myself from posts some months ago, and I am also
probably a) telling you things you already know, and b) "picking on
details" for something only intended as an indicative concept, but at
some stage, details start to matter if this is to be progressed (and yes
- this is something I intend to put effort into progressing, at some
future stage you will all get a chance to do the picking - but don't
hold your breath).

Bindings that are names in current Fortran (F2008) are tied to the
concept of type extension - for example, if you were to write a list
type today with an append binding, the actual argument corresponding to
the list object would need to be declared CLASS(list). If the type with
the binding is not intended to be extended, this effectively introduces
some pointless work for the implementation around maintaining
polymorphic descriptors and the like for the argument. Similarly if the
type is not extensible, you simply cannot have bindings.

Fortran 202X doesn't have to be that way, and perhaps there are
reasonable arguments around namespace management that mean you may want
to make bindings that are names more applicable to types that will never
be extended, but that is the way things are now.

(Bindings that are not names exist somewhere in between - they introduce
capability associated with type bound defined assignment that you simply
cannot do with stand-alone generic identifiers, but they still require
polymorphic passed arguments. Again, perhaps this inconsistency is
further argument that something should change.)

It will depend on details, but based on the situation with other
languages I expect most generic containers would not be intended to be
extended. Consequently the natural form, in the absence of other
changes to the language, would be both a type and a procedure that were
parameterised on type. Back to ye-old'e Fortran 95 syntax:

call append(data_list, 1.3_dp)

When you start talking about types and procedures, you are talking about
modules, i.e. I think for generic container support you are talking
about type parameterised modules.

Even if you exposed things like `append` though bindings, the procedures
that is nominated by a binding is not actually part of a type definition
- it defined completely separately (the one procedure may be nominated
by bindings in completely separate types) - so even if my comments above
about named-bindings-are-really-just-for-type-extension are contentious,
you still have a problem in terms of how type definitions and bindings
and procedures are all currently specified. Fortran 202X could change
everything to solve that problem, say by making procedures belong to
type definitions, but that would be additional change

Further, below there is discussion about an iterator. If that is
another type then we actually have two types that are commonly
parameterised, perhaps more if there are internal implementation types
supporting the container. Fortran currently lacks nested types, where
parameterisation of an outer type could conceptually flow through to the
nested type. Again, nested types could be in Fortran 202X, but they are
not in F2008.

That doesn't mean that type parameterisation of types might not have a
role to play elsewhere, the situation does not have to be one or the
other, but my view is that module parameterisation is the least
revolutionary point of application of type parameterisation to support
containers and other generic programming fun.

>> I think that looks reasonable for Fortran, no argument there. With
>> special syntax support for lists, I was thinking of something like you
>> see in the languages I mentioned above. E.g.
>>
>> list(read(dp)) :: data_list, another_data_list
>> data_list = {1.0_dp, 2.0_dp}
>> another_data_list = data_list:1.3_dp
>>
>> (Using {} here because IIRC [] is already taken for array
>> constructors). Probably ":" for appending/prepending is also a bad
>> choice for similar reasons, clashes with array indexing.

A value that is a sequence of subvalues that all have the same type and
kind looks just like an array value to me.

I'd be considering an operator symbol for an appending/preprepending
operation that created a new list value. Concatenation as a concept is
already established in the language.

>>> which would be both expressive and convenient. I'd also expect some
>>> sort of transformation methods from/to array ['from' can be bound to
>>> assignment] and some iterator type for scanning the list, say
>>>
>>> type (list_iterator (real(dp))) :: data_it
>>> ...
>>> list = [1.0_dp, 2.0_dp]
>>> ...
>>> call data_it%init (data_list)
>>> call data_it%print ()
>>>
>>> etc. etc.
>>
>> Awfully verbose, and specific; Is "print" a method of list_iterator?
>> What if you want to do something else? Should list_iterator have
>> methods for everything you might want to do with a list element?

As mentioned by Wolfgang elsethread, being able to easily forward stuff
to a component of an object is something that would be useful in
situations like this, and other contexts, given "wrap it in a derived
type" is a very common requirement.
Requiring that a type have a particular method available for use in a
particular form of built-in statement seems a little irregular to me.
Classic c++ survived with just the canonical for loop over stl
containers for quite some years. I similarly find the requirements for
its newer ranged for syntax irregular, perhaps that will wear off with
familiarity over time.

Being able to flatten an arbitrary object back into an array in some way
would allow you to use the existing language support for elemental
operations.

Ian Harvey

unread,
Jun 22, 2016, 12:44:22 AM6/22/16
to
On 2016-06-22 10:50 AM, David Duffy wrote:
> Wolfgang Kilian <kil...@invalid.com> wrote:
>> use generic_fortran_container_module, only: list
>> type (list (real(dp))) :: data_list
>> call data_list%append (1.3_dp)
>
> This looks attractive, but I would think a homogenous type list like
> this is very easy to implement via macro/preprocessing. And possibly
> efficient for compiling?

The issue with "dumb" text macro/pre-processors, like the C
pre-processor for example, is that they are ignorant of the semantics of
the code that they are processing. Depending on their dumbness, they
may violate otherwise "language natural" things such as Fortran's
scoping rules (the same identifier may mean very different things in
different scopes in the same file) and they may not offer the programmer
the ability to constrain/check what the user supplies as a parameter in
a meaningful way (the parameterisation may require a type or procedure
with a certain interface).

Smarter pre-processors can be written that are aware of things like the
scoping rules, but a separate pre-processing step would still be working
outside the realm of otherwise in-built stuff like Fortran modules, and
complicate things like error reporting as the source the real compiler
sees is not the source the user provided.

I think there is a reasonable amount of experience with other languages
that shows that pre-processors are far from an ideal solution for this
type of problem. At some reasonable early point, you are better off
incorporating the parameterisation in the base language and in the
compilers themselves.

> I've previously pointed to the template language used for the
> Inverse Ocean Modeling System:
> http://journals.ametsoc.org/doi/full/10.1175/2008JTECHO519.1
> which uses Haskell (!) as the meta-language to implement Fortran generics,
> automatic differentiation etc. Sure it does require recompilation from job to
> job, but the additions to the code look unobtrusive and easy to learn.

That is clearly a pre-processor at the smarter end of the range, given
it parses the input source into an abstract syntax tree, but the issues
above likely remain. The syntax is also not particularly consistent
with the rest of the language.

Stefano Zaghi

unread,
Jun 22, 2016, 4:22:10 AM6/22/16
to
Il giorno martedì 21 giugno 2016 21:49:41 UTC+2, JB ha scritto:
> I'm not arguing against generic containers. I imagine they would be
> very useful. But, I believe the better approach to get them would be
> if the language would provide constructs ("generics", or whatever you
> want to call them) so that external libraries could provide
> type-generic lists, trees etc., instead of building a type-generic
> list (and tree? and something else?) into the language itself, without
> the possibility for Fortran code to implement something equivalent
> using the facilities provided by the language.

Dear JB,

I will be very happy to improve the "generic facility" to allow easy library development, this is not in contrast with the desire of having built-in list: simply, the real generic-type aim seems to me a more challenging aim than a list-facility. Python offer only built-in list, not tree-octree... The list, in its simplest concept, is a different "aggregate" of elements with respect array: the cost of add-remove elements is O(1) in list, but is expensive to access element n-th, whereas array has O(1) access and more costly add-remove operation. I will be happy even to have only the simplest elements-uniform list as a starting point. If you can offer more (real generic-facility, parameter-module allowing easy development of generic-library) I will be even more happy.

> So whether one wants a minimal language with lots of needed and useful
> functionality provided by external libraries, or a "batteries
> included" approach such as python, is not a purely technical decision
> that one can make in some kind of vacuum.

Maybe I am wrong, but when I think of tiny language strongly based on external libraries the first language that comes into my mind is not Fortran: one Fortran strong point seems to be its "wide batteries of Math weapons", if you have to translate formula Fortran gives you all you need out-of-the-box.

> For instance, for Java
> Sun/Oracle could dedicate a 1000(?) full-time engineers to build a
> massive standard library. However, the reality is that that kind of
> money simply isn't available in the Fortran world. Add to that the
> fact that Fortran is an ISO standard, and getting stuff into the
> standard is expensive and time-consuming, and the implementation
> effort to then actually implement the standard is multiplied over
> several actively developed compilers. Contrast this again with Java,
> where there is ~1 implementation, so in that sense no "wasted" effort.

I am conscious of that, modifying the standard is a challenging task. This makes me somehow confused: why when you talk about adding "real-generic facility" the money-need-for-changing-the-standard is not an issue, whereas when I hope to start with a hopefully simple list we need 1000 full-time engineers?

Again, if you think that adding real generic facility is cheaper you are making real one of my dream.

> Hence I think that one should think VERY carefully about adding stuff
> to the Fortran standard. In particular, whether the proposed
> functionality could be implemented using standard Fortran instead of
> being builtin to the language.

In the actual status, developer cannot build real generic library in Fortran standard, there workarounds, but the real-generic aim is not totally achieved. The builtin language must be improved anyway: you propose to add generic-facility to allow easy-building of generic library? I am with you, I agree, but I think that this task could be not so simple. I would make do with only a "type list", but this seems to be a bigger problem. So, yes, I think VERY carefully to my desiderata: if you give me real generic facility you will make me VERY happy.

> And if not, what is the minimum
> required feature additions to the standard so that the desired
> functionality could be implemented using standard Fortran. E.g.,
> generics vs. having builtin every data structure under the sun.

The current F2008 standard is not enough, it should be improved evidently: I think that many agree on that, the current standard should be improved on generic containers support.

I pointed out the missing of list, you say to not add the list because someone else could ask other data structure... doing nothing is not a good answer.

I think that as much as like it happens for Python, a type list can allow the easy development of other data structure by means of external libraries, it the starting point, similar as the array is the starting point for all the goodness of Fortran. Maybe the type list is not the right answer and the Pythoners are silly programmers, but surely the current standard should add more generic support.


Il giorno martedì 21 giugno 2016 22:49:32 UTC+2, Ian Harvey ha scritto:
> The use of the word intrinsic certainly confused me. In the context of
> a type it means to be built in like the INTEGER and REAL types - the
> type never has to be defined, it is always available, and you can often
> do special things with it that you can't do with types defined in your
> own source code. Similar magic in the context of procedure names,
> intrinsic procedures very often have special powers that source code
> written by mortals cannot duplicate.

Dear Ian,

I agree, poor mortals like me cannot duplicate many aspect of the built-ins, thus my generic-list workaround is so poor.

> I don't just want compiler provided containers, I want to be able to
> easily write and use my own,

I agree with you.

> and I want to be able to write and use
> things that rely on the sort of generic programming capability that
> not-built-in container support would require, but then use it for things
> that don't look anything like containers.

Can you elaborate more? My bad English comes out and I am not able to figure out what you are alluding to.

> I thought that worked quite well as a model - here is a specification
> (but not implementation) of useful stuff provided in the form a module,

I agree, but this makes me afraid: when I think to Fortran I refer always to only the "specification" part, I was used to think that the "implementation" part is not an issue for the standard, but only the Compiler Vendors, I am wrong? Richard said that the standard has not the concept of "compiler" at all. In my mind when we talk about "improve the language" we are talking about "improve the standard specifications", is this wrong? As consequence, for me there is not practical difference (in my usage) between the specification of a standard module like "iso_fortran_env" or a new bultin.

> Another model that is worth considering is that of the boost libraries
> and their role in C++. They are a channel for community contributions
> of peer reviewed, high quality, permissively licensed libraries that
> help solve common programming tasks not dealt with by the standard C++
> facilities of the day. In some cases, libraries that started out in
> boost, after extensive production use, have then gone onto become part
> of the C++ standard library with minimal changes.

This is a very interesting model, it seems to be very attractive.

> The benefit of this separate-but-related approach with these libraries
> is in their ability to be much more responsive than an ISO language
> standard committee process.

This is pro but also a cons: standard committee people are super-hero that did a great job, the Standard is a "God's gift"... but a compromise with a responsive-high-quality libraries set and a slow-but-super-quality-standard-builtins is welcome.

> There are downsides to that approach, including that the libraries don't
> necessarily come with your standard C++ compiler (but in many cases they
> do - for example most linux distributions that I am aware of provide
> those libraries). The more responsive nature also means that individual
> libraries can change or come obsolescent faster than may be the case
> under the standard process. But libraries that are comprised of
> standard source code are likely to just be standard source code for
> quite a long period.

I agree.

> There are many additional aspects that could be addressed in the
> language. There are many different options for how those aspects are
> addressed. The issue is not whether some one thing is hard or easy, the
> issue is what to do, and what not to do, in the face of limited resources.

I agree, but such a decision should be on the shoulders of the committee (like you): we can only explain our desiderata, only the committee can define the priorities.

> I am principally a C++ programmer these days. The STL isn't perfect,
> but something doesn't have to be perfect to be a very, very useful tool
> for programmers. Flaws in its design, or flaws more generally in C++'s
> template feature, need to be kept in perspective.

Can I ask you a personal thought? You are a guru of Fortran, and now I learn of also C++: which language you prefer? I only superficially view some of the C++ features, but my (pre)judice is that Fortran is a more "sane" language.

> Different people, different priorities.

I agree. Many people nowadays are asking for generic containers adding a different priority.


> I want support in the language to permit me to not have to re-invent the
> wheel, time and time again. But I am happy to invent the wheel once (or
> pay someone else to invent it for me) - the wheel doesn't necessarily
> have to be in the language.

I agree, but currently we to reinvent all times.

> I might prefer wheels that have a bit more
> flashy chrome than those that come standard, for example. If you do
> bundle wheels with the language, make sure I can change them.

On the contrary, I think that the standard is really flashy chrome :-)

My best regards.

Marco

unread,
Jun 22, 2016, 6:17:06 AM6/22/16
to
Am Tue, 21 Jun 2016 09:46:41 -0700 schrieb Stefano Zaghi:

> Dear Marco, I am not sure to accomplish task to be concise and readable, but I try.
>
> At this link you can find the whole implementation of my "generic" (oc/quad)tree
>
> https://github.com/szaghi/OFF/blob/testing/src/Data_Type_Tree.f90
>
> It is essentially based on a hash table.

Dear Stefano, thank you very much for taking the time to submit this!

Coming to your comments:

> You already see the code-duplication that is very frustrating.

This could be addressed introducing a base type Type_Object that
provides the structure of getters/setters that you want for all your
objects and deriving from it all your types: since it is your library
it is not a problem asking all your types to extend Type_Object.

Then of course each tipe should likely provide its own implementation
of setters and getters, but how else could this be?


> To go in much details of the "bothering" issues I would like to consider the method "loopID" that is my poor replacement of the "in" iterator statement of Python. The "loopID" function is an impure function that return a logical (as a sentinel for a while loop) and the pointer to the current node-data, e.g. I can do something like

OK, here is my attempt at putting together an iterable module (it
should compile and run).

Things that I like:

1) From the user viewpoint, the code seems safe to me: the user only
gets abstract types defining abstract methods, so he can not mess with
the internal representation.

2) The user never cares about pointers nor targets

3) User code can not leak memory

4) there are some "SELECT TYPE" constructs, but they always have one
case, so I consider them a minor syntactic annoyance rather than a
flaw in the generic design.

5) the "for item in items:" equivalent is surely more verbose than
python, but I am not completely unhappy with it:

call vars%new_iterator( iter )
do; call iter%yield( item )
if(.not.allocated(item)) exit

enddo

Here I have chosen to allocate a copy of item; I could have returned a
pointer, which would allow modifying the item itself. Unfortunately we
don't have pointers to constants.


Things that I would like to be able to do better:

1) the user must derive from c_content : this is where something
like Java interfaces would really be a nice thing

2) the implementation has to use pointers to ensure that things are
TARGET. It would be nice to say that some components of a derived type
are TARGETs due to their internal representation, without asking the
user to remember this.


Concerning 1), CLASS(*) would probably work for this simple example,
but would not work if the contents must have some requirements, for
instance have a hash value as in your example.


How does this fit with your wishes?

Marco

P.S. The attached code works for me with gfortran printing

item%i = 1
item%i = 2
item%i = 3
item%i = 4
Finalizing a t_iterable_impl with 4 entries.

which is what I expect, while with ifort it prints

item%i = 1
item%i = 1
item%i = 1
item%i = 1
Finalizing a t_iterable_impl with 4 entries.

I might be overlooking something, still I think it shows my point.




module m_iterable

implicit none

private

! ---------------------------------------------------------------------
! The user gets abstract types and factories

public :: c_content, c_iterable, c_iterator, new_iterable

type, abstract :: c_content
end type c_content

type, abstract :: c_iterable
contains
procedure(i_new_iterator), deferred, pass(it) :: new_iterator
end type c_iterable

type, abstract :: c_iterator
contains
procedure(i_yield), deferred, pass(iterator) :: yield
end type c_iterator

abstract interface
subroutine i_new_iterator(it,iterator)
import :: c_iterable, c_iterator
implicit none
class(c_iterable), intent(in) :: it
class(c_iterator), allocatable, intent(out) :: iterator
end subroutine i_new_iterator
end interface

abstract interface
subroutine i_yield(iterator,item)
import :: c_iterator, c_content
implicit none
class(c_iterator), intent(inout) :: iterator
class(c_content), allocatable, intent(out) :: item
end subroutine i_yield
end interface

! ---------------------------------------------------------------------

! The implementation defines its private concrete types
type, extends(c_iterable) :: t_iterable_impl
class(c_content), pointer :: objects(:) => null()
contains
procedure, pass(it) :: new_iterator
final :: finalize_t_iterable_impl
end type t_iterable_impl

type, extends(c_iterator) :: t_iterator_impl
integer :: here
class(c_content), pointer :: items(:) => null()
contains
procedure, pass(iterator) :: yield
end type t_iterator_impl

!-----------------------------------------------------------------------

contains

!-----------------------------------------------------------------------

subroutine new_iterable( it , content )
class(c_content), intent(in) :: content(:)
class(c_iterable), allocatable, intent(out) :: it

allocate( t_iterable_impl :: it )
select type(it); class is(t_iterable_impl)

allocate( it%objects , source = content )

end select
end subroutine new_iterable

subroutine finalize_t_iterable_impl( it )
type(t_iterable_impl), intent(inout) :: it

write(*,*) &
"Finalizing a t_iterable_impl with ",size(it%objects),"entries."

deallocate( it%objects )

end subroutine finalize_t_iterable_impl

!-----------------------------------------------------------------------

subroutine new_iterator(it,iterator)
class(t_iterable_impl), intent(in) :: it
class(c_iterator), allocatable, intent(out) :: iterator

allocate( t_iterator_impl :: iterator )
select type(iterator); class is(t_iterator_impl)

if(size(it%objects).gt.0) then
iterator%here = 1
iterator%items => it%objects
else
iterator%here = -1
endif

end select
end subroutine new_iterator

subroutine yield(iterator,item)
class(t_iterator_impl), intent(inout) :: iterator
class(c_content), allocatable, intent(out) :: item

if(iterator%here.gt.0) then
allocate( item , source=iterator%items(iterator%here) )
if( size(iterator%items).gt.iterator%here ) then
iterator%here = iterator%here + 1
else
iterator%here = -1
endif
else
! leave item unallocated
endif

end subroutine yield

!-----------------------------------------------------------------------

end module m_iterable



program iterate

use m_iterable

type, extends(c_content) :: t_integer
integer :: i
end type t_integer

class(c_iterator), allocatable :: iter
class(c_content), allocatable :: item
class(c_iterable), allocatable :: vars

type(t_integer) :: my_data(4)

my_data%i = (/ 1,2,3,4 /)

call new_iterable( vars , my_data )

call vars%new_iterator( iter )
do; call iter%yield( item )
if(.not.allocated(item)) exit
select type(item); class is(t_integer)

write(*,*) "item%i = ", item%i

end select
enddo

! clean-up
deallocate(vars,iter)

end program iterate


Stefano Zaghi

unread,
Jun 22, 2016, 6:37:42 AM6/22/16
to
Il giorno mercoledì 22 giugno 2016 12:17:06 UTC+2, m ha scritto:
> Dear Stefano, thank you very much for taking the time to submit this!

Dear Marco, you are welcome, here is my preferred place to learn Fortran, thus this time is not wasted at all.

> This could be addressed introducing a base type Type_Object that
> provides the structure of getters/setters that you want for all your
> objects and deriving from it all your types: since it is your library
> it is not a problem asking all your types to extend Type_Object.

I totally agree, indeed, I am currently moving on "abstracting" many of my objects (the example I posted previously is quite old, 2014 I think).

> Then of course each tipe should likely provide its own implementation
> of setters and getters, but how else could this be?

Yes, I like very much the "program-by-abstract-contract" model.

> OK, here is my attempt at putting together an iterable module (it
> should compile and run).
>
> Things that I like:
>
> 1) From the user viewpoint, the code seems safe to me: the user only
> gets abstract types defining abstract methods, so he can not mess with
> the internal representation.
>
> 2) The user never cares about pointers nor targets
>
> 3) User code can not leak memory
>
> 4) there are some "SELECT TYPE" constructs, but they always have one
> case, so I consider them a minor syntactic annoyance rather than a
> flaw in the generic design.
>
> 5) the "for item in items:" equivalent is surely more verbose than
> python, but I am not completely unhappy with it:
>
> call vars%new_iterator( iter )
> do; call iter%yield( item )
> if(.not.allocated(item)) exit
>
> enddo
>
> Here I have chosen to allocate a copy of item; I could have returned a
> pointer, which would allow modifying the item itself. Unfortunately we
> don't have pointers to constants.

I agree, indeed, we already moved in this direction: a very great programmer, Chris Mackmackin the author of FORD, has started a library very close to your model (an abstract with iterator/set/get/add/del facilities but based on "transfer" trick to achieve generic behavior). I like this model, but I still think these are "poor" workarounds.

> Things that I would like to be able to do better:
>
> 1) the user must derive from c_content : this is where something
> like Java interfaces would really be a nice thing

I agree, I do not know Java interface, but this step could be viewed as an overhead.

> 2) the implementation has to use pointers to ensure that things are
> TARGET. It would be nice to say that some components of a derived type
> are TARGETs due to their internal representation, without asking the
> user to remember this.

Right observation.


> How does this fit with your wishes?

It fits very well :-) However, concerning language improvement, I still think these are workarounds and not real solutions.

> P.S. The attached code works for me with gfortran printing

Today I have not the time to study your module, but I have already archived it in my HD... thank you very much!

My best regards.

JB

unread,
Jun 22, 2016, 3:28:18 PM6/22/16
to
On 2016-06-22, Stefano Zaghi <stefan...@gmail.com> wrote:
> Il giorno martedì 21 giugno 2016 21:49:41 UTC+2, JB ha scritto:
>> I'm not arguing against generic containers. I imagine they would be
>> very useful. But, I believe the better approach to get them would be
>> if the language would provide constructs ("generics", or whatever you
>> want to call them) so that external libraries could provide
>> type-generic lists, trees etc., instead of building a type-generic
>> list (and tree? and something else?) into the language itself, without
>> the possibility for Fortran code to implement something equivalent
>> using the facilities provided by the language.
>
> Dear JB,
>
> I will be very happy to improve the "generic facility" to allow easy library development, this is not in contrast with the desire of having built-in list:

Well, I agree to the extent that adding some builtin list to the
language does need to prevent the addition of generics. My point is
more that if we had generics, a builtin list would be redundant since
it could just as well be provided by an external library.

> simply, the real generic-type aim seems to me a more challenging aim than a list-facility.

I agree; Generics are a much more powerful feature than a builtin
list, and as such, it's an apples to oranges comparison.

> Maybe I am wrong, but when I think of tiny language strongly based on external libraries the first language that comes into my mind is not Fortran

Sure, Fortran is by no means a minimal language, the standard document
is steadily trending towards the magical 1000 pages (compare this to
e.g. R5RS Scheme for something fairly minimal). But if you compare the
Fortran intrinsic modules and procedures with something like the Java
standard library, it's very tiny indeed.

>> For instance, for Java
>> Sun/Oracle could dedicate a 1000(?) full-time engineers to build a
>> massive standard library. However, the reality is that that kind of
>> money simply isn't available in the Fortran world. Add to that the
>> fact that Fortran is an ISO standard, and getting stuff into the
>> standard is expensive and time-consuming, and the implementation
>> effort to then actually implement the standard is multiplied over
>> several actively developed compilers. Contrast this again with Java,
>> where there is ~1 implementation, so in that sense no "wasted" effort.
>
> I am conscious of that, modifying the standard is a challenging task. This makes me somehow confused: why when you talk about adding "real-generic facility" the money-need-for-changing-the-standard is not an issue, whereas when I hope to start with a hopefully simple list we need 1000 full-time engineers?

Again, I don't think it makes sense to compare the effort required to
standardize generics vs. a builtin list.

And yes, it's entirely possible that the standards committee considers
generics too much work and chooses to not work on this.

And no, I don't think adding a "simple list" would require 1000
full-time engineers. Where "1000 engineers" would be needed where if
there was consensus that Fortran should evolve to become a "big
language" with a massive standard library so most programs wouldn't
need to use external libraries. Some people want a linked list,
someone else wants something else, etc. and soon you have a massive
monstrosity.

> I pointed out the missing of list, you say to not add the list because someone else could ask other data structure... doing nothing is not a good answer.

Au contraire, "doing nothing" might not be such a bad idea
actually. Compilers are already straining to implement already
standardized features, so waiting a while for compilers to actually
support the latest standard and users getting actual production
experience with the current features might make perfect sense. Maybe
even more important than generics. But anyway, not my decision, I'm
just a guy ranting on usenet... :-/


--
JB

Stefano Zaghi

unread,
Jun 22, 2016, 4:30:54 PM6/22/16
to
Dear JB,

I am happy to read that we are essentially in agreement :-)

>Au contraire, "doing nothing" might not be such a bad idea
actually. Compilers are already straining to implement already
standardized features, so waiting a while for compilers to actually
support the latest standard and users getting actual production
experience with the current features might make perfect sense. Maybe
even more important than generics. But anyway, not my decision, I'm
just a guy ranting on usenet... :-/

I have admit that this has perfectly sense, a good point for you, maybe the time is not yet mature after 60 years :-) Seriously, I think you are probably right, F201x will not define any generic-facility improvment for the reasons you have listed.

My best regards.

Wolfgang Kilian

unread,
Jun 22, 2016, 4:33:56 PM6/22/16
to
Let me first remark that if such a facility was available in the form
that you indicate, I would be happy and use it. There is nothing wrong
with a procedure-based approach to generics, nor with parameterized modules.

Nevertheless, I see a few distinct advantages that a method-based
approach could provide, some syntactical and some semantical.

- A parameterized module that exports types and procedure names will
export a bunch of names. There would be some "list" type, an "append"
procedure, and so on. The same names would be exported by the same
module with a different parameterization. Rename them individually?
Add a generic interface for the specific procedures?
Should the parameterized module export altered names based on the type
parameter(s)? such as
call list_real_append (data_list, 1.3_dp)

In a method-based approach where the container module is not
parameterized but the entities within are, fewer names are exported (the
type names only), no name ambiguities arise between different
instantiations of the generic type, and method calls are concise.
call data_list%append (1.3_dp)

- Method syntax comes along with polymorphism for the container type, as
you point out. This might not be required. However, the redundancy is
irrelevant to the user of the module, client code doesn't need to use
CLASS declarations. On the other hand, there is some potential in
extending a container type. For instance

type, extends (list(real)) :: named_dataset
character(:), allocatable :: name
end type

could be useful. All container methods are available by inheritance.

I agree that a method-based version requires both parameterized types
and parameterized procedures that are be bound to them.
Parameterization of both types and (intrinsic) procedures, but not of
modules, is already in the language. The presently allowed parameters
are KIND or LEN values; this would have to be extended to type
specifiers. I see no inherent problem in types depending on types; such
dependence would be already resolved at compile time.

- Defined assignment has to become type-bound assignment for a container
type, because generic assignment via INTERFACE would not propagate in
recursive assignment.

>
> Further, below there is discussion about an iterator. If that is
> another type then we actually have two types that are commonly
> parameterised, perhaps more if there are internal implementation types
> supporting the container. Fortran currently lacks nested types, where
> parameterisation of an outer type could conceptually flow through to the
> nested type. Again, nested types could be in Fortran 202X, but they are
> not in F2008.

Within a type definition, the specification of a parameter type would be
a 'dummy' declaration, analogous to procedure dummy arguments. Such
declarations would be required in any case.

>
> That doesn't mean that type parameterisation of types might not have a
> role to play elsewhere, the situation does not have to be one or the
> other, but my view is that module parameterisation is the least
> revolutionary point of application of type parameterisation to support
> containers and other generic programming fun.

I think that module vs. type/procedure parameterization have different
purposes. There are languages where modules can depend on other modules
as parameters (functors), while simultaneously types can depend on
types, etc. One has to think about the level of meta-programming that
should be supported. Fine-grained generics (types, procedures) might
appear somewhat more accessible to users than abstraction at the module
level only.

>>> I think that looks reasonable for Fortran, no argument there. With
>>> special syntax support for lists, I was thinking of something like you
>>> see in the languages I mentioned above. E.g.
>>>
>>> list(read(dp)) :: data_list, another_data_list
>>> data_list = {1.0_dp, 2.0_dp}
>>> another_data_list = data_list:1.3_dp
>>>
>>> (Using {} here because IIRC [] is already taken for array
>>> constructors). Probably ":" for appending/prepending is also a bad
>>> choice for similar reasons, clashes with array indexing.
>
> A value that is a sequence of subvalues that all have the same type and
> kind looks just like an array value to me.
>
> I'd be considering an operator symbol for an appending/preprepending
> operation that created a new list value. Concatenation as a concept is
> already established in the language.

The most popular STL container might actually be 'vector', which shares
properties of both lists and arrays. Efficiency might be suboptimal,
but the construct is versatile, and the user can forget about size
management. The access syntax is secondary.
Agreed.

-- Wolfgang


Wolfgang Kilian

unread,
Jun 23, 2016, 2:39:46 AM6/23/16
to
That sounds like Java containers need only store and shuffle pointers
behind the scene, while the actual objects may reside somewhere else in
memory. That's another issue one has to think about when dealing with
containers in Fortran. Fortran objects would require the TARGET
attribute or you may lose them on the way, and this is error-prone to
handle in real code. There is no such thing as a persistent TARGET
attribute - in the interplay of actual and dummy argument
correspondence, that is.

>
> I have also put small arrays, even only one element, in hash tables, as arrays are
> object in Java.
>
>> I've previously pointed to the template language used for the
>> Inverse Ocean Modeling System:
>> http://journals.ametsoc.org/doi/full/10.1175/2008JTECHO519.1
>> which uses Haskell (!) as the meta-language to implement Fortran generics,
>> automatic differentiation etc. Sure it does require recompilation from job to
>> job, but the additions to the code look unobtrusive and easy to learn.
>
> -- glen
>

-- Wolfgang

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

JB

unread,
Jun 23, 2016, 2:56:25 AM6/23/16
to
On 2016-06-22, Wolfgang Kilian <kil...@invalid.com> wrote:
> On 06/22/2016 05:43 AM, Ian Harvey wrote:
>> On 2016-06-22 5:05 AM, Wolfgang Kilian wrote:
>>> On 06/21/2016 03:31 PM, JB wrote:
>>>> I think that looks reasonable for Fortran, no argument there. With
>>>> special syntax support for lists, I was thinking of something like you
>>>> see in the languages I mentioned above. E.g.
>>>>
>>>> list(read(dp)) :: data_list, another_data_list
>>>> data_list = {1.0_dp, 2.0_dp}
>>>> another_data_list = data_list:1.3_dp
>>>>
>>>> (Using {} here because IIRC [] is already taken for array
>>>> constructors). Probably ":" for appending/prepending is also a bad
>>>> choice for similar reasons, clashes with array indexing.
>>
>> A value that is a sequence of subvalues that all have the same type and
>> kind looks just like an array value to me.
>>
>> I'd be considering an operator symbol for an appending/preprepending
>> operation that created a new list value. Concatenation as a concept is
>> already established in the language.
>
> The most popular STL container might actually be 'vector', which shares
> properties of both lists and arrays. Efficiency might be suboptimal,
> but the construct is versatile, and the user can forget about size
> management. The access syntax is secondary.

As an aside, AFAIK lists in python are actually implemented similarly
to std::vector in C++ rather than a classic linked list. In most cases
it's actually faster than a classic linked list due to better cache
behavior.

I suppose one could argue that with reallocation on assignment,
Fortran is partly there. What's missing is a separation of allocated
size vs. "logical" size, so that, say, appending one element at a time
to an array doesn't cause a reallocation and copy for every element.



--
JB

Ian Harvey

unread,
Jun 23, 2016, 4:05:25 AM6/23/16
to
To some extent, that is really just implementation detail. There is no
need for the memory allocation that sits behind an allocatable variable
to match the minimum storage required to store the value of the
variable. Such a situation could conceivably arise when an existing
array is truncated.

INTEGER, ALLOCATABLE :: array(:)
array = [ 1, 2, 3, 4, 5 ]

array = array(:3)

A smart compiler could identify that the assignment above could be
implemented by simply changing the bounds of the array in the
descriptor, leaving two unused elements behind the array.

For a following statement such as:

array = [ array, 6, 7 ]

the compiler could then first check whether there was sufficient spare
storage to append the values beyond the existing storage of the array,
without a relatively expensive allocate, copy and deallocate sequence.

When I'm not worrying about performance I frequently take advantage of
these sorts of simple and succinct source constructs.

I don't expect this sort of optimisation to be in compilers today, and
perhaps I am delusional about ever seeing it, but as support for Fortran
2003 becomes established these are the sorts of improvements that I
would like to see investigated.

But as you say, there is no way that a programmer can specify that
additional storage should be reserved.

Marco

unread,
Jun 23, 2016, 5:19:56 AM6/23/16
to
Am Wed, 22 Jun 2016 03:37:40 -0700 schrieb Stefano Zaghi:

> Il giorno mercoledì 22 giugno 2016 12:17:06 UTC+2, m ha scritto:
>> OK, here is my attempt at putting together an iterable module (it
>> should compile and run).
>>
>> Things that I like:
>>
>> 1) From the user viewpoint, the code seems safe to me: the user only
>> gets abstract types defining abstract methods, so he can not mess with
>> the internal representation.
>>
>> 2) The user never cares about pointers nor targets
>>
>> 3) User code can not leak memory
>>
>> 4) there are some "SELECT TYPE" constructs, but they always have one
>> case, so I consider them a minor syntactic annoyance rather than a
>> flaw in the generic design.
>>
>> 5) the "for item in items:" equivalent is surely more verbose than
>> python, but I am not completely unhappy with it:
>>
>> call vars%new_iterator( iter )
>> do; call iter%yield( item )
>> if(.not.allocated(item)) exit
>>
>> enddo
>>
>> Here I have chosen to allocate a copy of item; I could have returned a
>> pointer, which would allow modifying the item itself. Unfortunately we
>> don't have pointers to constants.
>
> I agree, indeed, we already moved in this direction: a very great programmer, Chris Mackmackin the author of FORD, has started a library very close to your model (an abstract with iterator/set/get/add/del facilities but based on "transfer" trick to achieve generic behavior). I like this model, but I still think these are "poor" workarounds.

This is a discussion about terminology and personal views, so I don't
think we should expect much convergence here, still I mention that I
don't necessarily consider most of what can be done with today Fortran
a workaround.

For a me a workaround is something that does the job in a suboptimal,
sometimes even very problematic way. Reasons can be:
- the code is not portable
- the code is error prone
- the code is hard to understand and maintain

Specific reasons could be
- the code involves a lot of repetitions
- the code uses low-level tools to represent high-level concepts, a
typical example being the use of pointers and casting to do abstract
programming, or the use of TRANSFER that you mention
- the code uses a language feature not because of its main effect but
because of some obscure side effect: an example is my use of
pointers to ensure "targetness"

The purpose of the exercise I am proposing here, namely taking
specific code examples, should be to take fully advantage of the
language as it is now and show what can be done cleanly and what
does need a workaround, and thus is calling for additions to the
language.

In my example, and also in your code, I see two things requiring a
workaround: the lack of a functionality similar to Java interfaces and
the difficulty for a library ensuring that something is TARGET, when
the objects are instantiated by client code.

Everything else is fine in my opinion and perfectly satisfying. Of
course Fortran doesn't have the Python syntax, but is this a problem
in its own?

I think this way of reasoning has two benefits compared to the general
request for "more" that I see in this thread: it shows what is already
in the language and it guides the discussion towards specific features
which might have a chance to be considered.

Marco

herrman...@gmail.com

unread,
Jun 23, 2016, 5:34:46 AM6/23/16
to
On Thursday, June 23, 2016 at 1:05:25 AM UTC-7, Ian Harvey wrote:


(snip, someone wrote)
> > I suppose one could argue that with reallocation on assignment,
> > Fortran is partly there. What's missing is a separation of allocated
> > size vs. "logical" size, so that, say, appending one element at a time
> > to an array doesn't cause a reallocation and copy for every element.

> To some extent, that is really just implementation detail. There is no
> need for the memory allocation that sits behind an allocatable variable
> to match the minimum storage required to store the value of the
> variable. Such a situation could conceivably arise when an existing
> array is truncated.

Reminds me, I believe that there is some version of BASIC that supports
arrays with either 0 or 1 origin. For whatever value you give for the bound,
it allocates space for elements 0 through N.

> INTEGER, ALLOCATABLE :: array(:)
> array = [ 1, 2, 3, 4, 5 ]

> array = array(:3)

> A smart compiler could identify that the assignment above could be
> implemented by simply changing the bounds of the array in the
> descriptor, leaving two unused elements behind the array.

> For a following statement such as:

> array = [ array, 6, 7 ]

> the compiler could then first check whether there was sufficient spare
> storage to append the values beyond the existing storage of the array,
> without a relatively expensive allocate, copy and deallocate sequence.

Java ArrayList does that. ArrayList supports List operations, with an
underlying array. For adding or removing elements from either end, it
normally doesn't have to copy the whole array. If you add too many elements
to either end, it will allocate an appropriately larger array.

> When I'm not worrying about performance I frequently take advantage of
> these sorts of simple and succinct source constructs.

> I don't expect this sort of optimisation to be in compilers today, and
> perhaps I am delusional about ever seeing it, but as support for Fortran
> 2003 becomes established these are the sorts of improvements that I
> would like to see investigated.

Hard to say. It is an optimization if you often make partial array copies
like that, but wasteful if you don't. The compiler doesn't have a good
way to know.

> But as you say, there is no way that a programmer can specify that
> additional storage should be reserved.

A Java String is backed by a Java Char array. If you so substring, it generates
a new String object backed by the same array. (Strings are immutable, so the
backing array can't be changed.) Most of the time this is most efficient,
but if you store many small substrings of large strings, it is wasteful
of memory. Guess how I found this out?

-- glen

herrman...@gmail.com

unread,
Jun 23, 2016, 6:08:13 AM6/23/16
to
On Wednesday, June 22, 2016 at 11:39:46 PM UTC-7, Wolfgang Kilian wrote:

(snip)

> That sounds like Java containers need only store and shuffle pointers
> behind the scene, while the actual objects may reside somewhere else in
> memory. That's another issue one has to think about when dealing with
> containers in Fortran. Fortran objects would require the TARGET
> attribute or you may lose them on the way, and this is error-prone to
> handle in real code. There is no such thing as a persistent TARGET
> attribute - in the interplay of actual and dummy argument
> correspondence, that is.

Java objects are only used through reference variables.

So, for example, there are eight sort routine in Java, one for each
primitive type (byte, char, short, int, long, float, double) and one for Object.

Compare to C's qsort which can sort any array, such as an array of struct
or array of pointers. In Java, there are arrays of primitive types and
arrays of object references. No arrays of objects themselves.

In Fortran, on the other hand, you can have arrays of structures,
but not arrays of pointers to structures or pointers to anything else.


Ian Harvey

unread,
Jun 23, 2016, 5:26:20 PM6/23/16
to
On 2016-06-22 8:17 PM, Marco wrote:
> Am Tue, 21 Jun 2016 09:46:41 -0700 schrieb Stefano Zaghi:
>
>> Dear Marco, I am not sure to accomplish task to be concise and readable, but I try.
>>
>> At this link you can find the whole implementation of my "generic" (oc/quad)tree
>>
>> https://github.com/szaghi/OFF/blob/testing/src/Data_Type_Tree.f90
>>
>> It is essentially based on a hash table.
>
> Dear Stefano, thank you very much for taking the time to submit this!
>
> Coming to your comments:
>
>> You already see the code-duplication that is very frustrating.
>
> This could be addressed introducing a base type Type_Object that
> provides the structure of getters/setters that you want for all your
> objects and deriving from it all your types: since it is your library
> it is not a problem asking all your types to extend Type_Object.
>
> Then of course each tipe should likely provide its own implementation
> of setters and getters, but how else could this be?
>
>
>> To go in much details of the "bothering" issues I would like to consider the method "loopID" that is my poor replacement of the "in" iterator statement of Python. The "loopID" function is an impure function that return a logical (as a sentinel for a while loop) and the pointer to the current node-data, e.g. I can do something like
>
> OK, here is my attempt at putting together an iterable module (it
> should compile and run).
>
> Things that I like:
>
> 1) From the user viewpoint, the code seems safe to me: the user only
> gets abstract types defining abstract methods, so he can not mess with
> the internal representation.
>
> 2) The user never cares about pointers nor targets
>
> 3) User code can not leak memory

(You need to provide defined assignment for your container type.)

> 4) there are some "SELECT TYPE" constructs, but they always have one
> case, so I consider them a minor syntactic annoyance rather than a
> flaw in the generic design.
>
> 5) the "for item in items:" equivalent is surely more verbose than
> python, but I am not completely unhappy with it:
>
> call vars%new_iterator( iter )
> do; call iter%yield( item )
> if(.not.allocated(item)) exit
>
> enddo
>
> Here I have chosen to allocate a copy of item; I could have returned a
> pointer, which would allow modifying the item itself. Unfortunately we
> don't have pointers to constants.
>
>
> Things that I would like to be able to do better:
>
> 1) the user must derive from c_content : this is where something
> like Java interfaces would really be a nice thing

It is perhaps just a workaround of a different sort, with its own
issues, but an option here is to extract the substantial body of your
m_iterable module (starting immediately after the type definition of the
c_content abstract type) out into its own file, and then direct clients
of that stretch of code to use INCLUDE to "instantiate" the generic
code. The user code is required to provide a type named c_content in
the scope of the include, but that is easy to do with USE renaming.

That is, from the client code perspective, use of the generic container
looks something like:

module my_type
implicit none

! No requirement here for a particular parent.
type, public :: t_integer
integer :: i
end type t_integer
end module my_type

module my_iterable
use my_type, c_content => t_integer
implicit none

private
public :: c_iterator, c_iterable, new_iterable

! In this file goes the body of your m_iterable
! module, starting immediately after the c_content
! type definition (which is no longer required) and
! up to the end of the yield subroutine.
include 'iterable.i90'
end module my_iterable


program iterate
use my_type
use my_iterable

implicit none

class(c_iterator), allocatable :: iter
class(t_integer), allocatable :: item
class(c_iterable), allocatable :: vars

type(t_integer) :: my_data(4)

my_data%i = (/ 1,2,3,4 /)

call new_iterable( vars , my_data )

call vars%new_iterator( iter )
do; call iter%yield( item )
if(.not.allocated(item)) exit
select type(item); class is(t_integer)

write(*,*) "item%i = ", item%i

end select
enddo

! clean-up
deallocate(vars,iter)
end program iterate

This approach offers the benefit that there is no need for select type
in client code to access the returned object, and similarly, the client
code is not constrained to a particular inheritance hierarchy. A
material disadvantage of this approach is that it uses INCLUDE,
operating at a level barely above text substitution. In the general
case there will be additional requirements on the subject type (i.e. it
must come with these components, these bindings, these free standanding
procedures, etc) that can only be implicitly specified at the moment
(client gets an error, they must have not met one of the requirements,
now to guess which one).

(Opinions vary about this, but it may also be possible to rename
intrinsic types via USE. In the stretch of code you provided the
objects being stored are held via a polymorphic component, which
requires an extensible type, which excludes intrinsic types. But that's
a design decision - providing a polymorphic component enables storing
objects that are extensions, which may be useful. There's no reason why
both variants couldn't be provided in different containers, though that
can be the first step down a combinatorial explosion, which is a
distinct possibility once you consider other attributes.)

Additional language features that could be used to simplify things in
both library and client code include the F2008 feature that permits a
function reference with data pointer result to appear as a variable, and
the F2008 feature of intrinsic polymorphic allocation with F2003
functions with allocatable polymorphic results to provide container and
iterator constructors.

With all the above I am merely highlighting generic programming
alternatives with the current state of the language, I am not pretending
that those alternatives are ideal or acceptable.

> 2) the implementation has to use pointers to ensure that things are
> TARGET. It would be nice to say that some components of a derived type
> are TARGETs due to their internal representation, without asking the
> user to remember this.

Yes. The need to use pointer components to robustly ensure that
something is guaranteed to be a target is a nuisance. However,
conceptually this could get tricky.

An example of using INCLUDE to implement a generic "shared pointer" can
be found at www.megms.com.au/shared-pointers.htm

Other issues that I have encountered while putting that together:

- Fortran's model of finalization has what I regard as significant holes
to do with ALLOCATE(..., SOURCE=xxx) and VALUE dummy arguments - the
generic library code loses control of aspects of construction and
finalization of those objects.

- Often containers require defined assignment as part of their
implementation. Defined assignment is part of the internal
implementation, but it suppresses intrinsic assignment and the
associated reallocation on assignment of an object, which is visible to
clients. The workaround is to use an intermediate wrapper type in the
library code, which, as far as I can tell, insulates the client code.

- Forwarding calls of a type bound procedure of a contained object
requires use of a temporary as you cannot apply binding references to
function results. (You can apply operators which map to type bound
procedures, and you can use non-type bound procedure references.)


William Clodius

unread,
Jun 24, 2016, 9:41:52 AM6/24/16
to
JB <f...@bar.invalid> wrote:

> <snip>
> As an aside, AFAIK lists in python are actually implemented similarly
> to std::vector in C++ rather than a classic linked list. In most cases
> it's actually faster than a classic linked list due to better cache
> behavior.
> <snip>
As I understand it python lists are implemented as doubly linked lists
of arrays (with cyclic links at the ends). If you insert an element in
the list that causes the need for more memory than can be satisfied near
the insertion point then the next list element allocated is an array
larger than the last array allocated as a list "element".

Marco

unread,
Jun 28, 2016, 5:40:43 AM6/28/16
to
Ian, thank you for the observation.

I have come to the conclusion that for types such as c_content I never
use assignment nor source allocations. Instead, I provide two methods

type, abstract :: c_content
contains
procedure :: source
procedure, deferred :: copy
end type c_content

"source" has a default implementation which does source allocation,
but has the advantage that the user can override it. The problem is
that, if the generic code uses

allocate( var , source=c_content_object )

than the client code can not redefine this operation while extending
c_content. Wrapping the source allocation in a c_content%source method
allows such control. However, there is no way to forbid using directly
the native source allocation, so one has to be disciplined. Also, I
don't provide methods for all possible cases of source allocation:
scalars and arrays of different ranks.

"copy" serves the purpose of assigning the value of an object to
another one which is already defined - whatever this means. This is a
deferred method and must be defined when providing a concrete
c_content.

I think that I should also provide a defined assignment which simply
calls "abort", so that the generic code must use the user provided
"copy" method. The problem is that the native "=" seems to do too many
things to control them properly (think about reallocation on
assignment, assignment of a scalar to an array, etc.)


For the container type: how would you leak memory using defined
assignment?

I can see that my present implementation can have two containers
pointing to the same content. This might or might not be waht is
desired. If it is, than the final subroutine must handle this
correctly.

I think my preferred solution would be disabling assignment (i.e.
writing a fined assignment which calls "abort") and providing two
methods clone and make_a_reference .
I see, so this has the effect that now in the module defining the
iterator c_content is a parameter which acquires a specific meaning
when the code is included in the client module.

Nice indeed!

I would still consider this a workaround according to "uses low level
tools (text processing) to achieve high-level functionality", but I
agree that it is a feasible option using today Fortran.

Some difficulties that I see are:
1) the code for the generic iterable container can not be compiled on
its own, it must be included
2) if there are some requirements on c_content, such as having the
"source" and "copy" methods that I mention above, they can not be
specified as deferred of an abstract type. Instead, one has to rely on
some documentation to tell the user what methods must be provided in
my_type.
Yes, indeed!

> (Opinions vary about this, but it may also be possible to rename
> intrinsic types via USE. In the stretch of code you provided the
> objects being stored are held via a polymorphic component, which
> requires an extensible type, which excludes intrinsic types. But that's
> a design decision - providing a polymorphic component enables storing
> objects that are extensions, which may be useful. There's no reason why
> both variants couldn't be provided in different containers, though that
> can be the first step down a combinatorial explosion, which is a
> distinct possibility once you consider other attributes.)

Agree. But I think that in this respect my code could be improved:
either we have some requirements on c_content, such as the two
"source" and "copy" methods, which would exclude the intrinsic types,
or we could use class(*) which would allow also the intrinsic types.

Still, it would be nice to have all the intrinsic types extending a
base "numeric" type, which could be extended also by user defined
types. This would allow a generic treatment of objects sharing an
interface with +,-,*,/ and maybe other intrinsics...

> Additional language features that could be used to simplify things in
> both library and client code include the F2008 feature that permits a
> function reference with data pointer result to appear as a variable, and

Interesting! Would this allow writing getters which look like
components, such as container%get_data()(1:2:10) ?

> the F2008 feature of intrinsic polymorphic allocation with F2003
> functions with allocatable polymorphic results to provide container and
> iterator constructors.

Could you provide an example of this?

> With all the above I am merely highlighting generic programming
> alternatives with the current state of the language, I am not pretending
> that those alternatives are ideal or acceptable.
>
>> 2) the implementation has to use pointers to ensure that things are
>> TARGET. It would be nice to say that some components of a derived type
>> are TARGETs due to their internal representation, without asking the
>> user to remember this.
>
> Yes. The need to use pointer components to robustly ensure that
> something is guaranteed to be a target is a nuisance. However,
> conceptually this could get tricky.
>
> An example of using INCLUDE to implement a generic "shared pointer" can
> be found at www.megms.com.au/shared-pointers.htm

Interesting! Are you aware of any proposed extension of the language
that would allow this without INCLUDE? I wonder whether one could
rewrite your code with such an extension together with an "ad hoc"
preprocessor to produce standard Fortran code. Parametrized modules
have been mentioned on this list by you and others; do you also have
examples using them?

> Other issues that I have encountered while putting that together:
>
> - Fortran's model of finalization has what I regard as significant holes
> to do with ALLOCATE(..., SOURCE=xxx) and VALUE dummy arguments - the
> generic library code loses control of aspects of construction and
> finalization of those objects.

As mentioned above, I also don't like source allocation. I think there
should be a way to redefine this, much as there is now a way to
redefine what WRITE means.

Also, I don't like the overlapping between source allocation and
assignment. I think that both of them are somehow too smart.
(Concerning assignment, yes, it can be redefined, which is already
good, but there are many overloaded operators and it is not easy to
redefine *all* of them).

> - Often containers require defined assignment as part of their
> implementation. Defined assignment is part of the internal
> implementation, but it suppresses intrinsic assignment and the
> associated reallocation on assignment of an object, which is visible to
> clients. The workaround is to use an intermediate wrapper type in the
> library code, which, as far as I can tell, insulates the client code.

Yes, again, I see you are also not completely happy with assignment.

> - Forwarding calls of a type bound procedure of a contained object
> requires use of a temporary as you cannot apply binding references to
> function results. (You can apply operators which map to type bound
> procedures, and you can use non-type bound procedure references.)

How is this related to your comment above about

> F2008 feature that permits a function reference with data pointer
> result to appear as a variable


Thank you very much for your thoughts!

Marco

Stefano Zaghi

unread,
Jun 29, 2016, 12:27:40 AM6/29/16
to
A source of inspiration for "containers"

https://github.com/emirpasic/gods

I would to be able to implement a similar library in Fortran.

My best regards.

fj

unread,
Jun 29, 2016, 3:22:18 AM6/29/16
to
And for that, one just needs java-like interfaces... I don't know the Go language, but it seems that this one has adopted the java interfaces which make easy the programming by contract (to implement an interface, a class (a type?) has to implement all the abstract procedures imposed by the interface).

Any derived type variable implementing a particular interface (Iterator for instance) may by declared class(Iterator).

Of course a derived type would be able to implement any number of interfaces...

Wolfgang Kilian

unread,
Jun 29, 2016, 1:33:14 PM6/29/16
to
The interfaces themselves are probably available ... any abstract or
concrete derived type could serve as an interface, just as in
PROCEDURE(foo), foo can be any abstract or concrete interface or an
accessible procedure. The part about implementing such a 'type
interface', in place of extending a type, is missing.

-- Wolfgang

GianLuigi Piacentini

unread,
Jun 29, 2016, 4:30:33 PM6/29/16
to
May be the following one is easier
http://www.adaic.org/resources/add_content/standards/05rm/html/RM-A-18.html

Seems to me that the very problem is emulating
http://www.adaic.org/resources/add_content/standards/05rm/html/RM-12.html

Hoping that this helps.

Gigi


Ian Harvey

unread,
Jun 30, 2016, 12:11:40 AM6/30/16
to
I was imprecisely bundling "cannot leak memory" with general memory
management issues. Without defined assignment you will end up with a
"double free" situation, as you discuss below, if the user uses
assignment on a container.

> I can see that my present implementation can have two containers
> pointing to the same content. This might or might not be waht is
> desired. If it is, than the final subroutine must handle this
> correctly.

I don't think it is possible to write a final subroutine that can handle
that situation correctly.

> I think my preferred solution would be disabling assignment (i.e.
> writing a fined assignment which calls "abort") and providing two
> methods clone and make_a_reference .

From the perspective of a client using the container, if they want to
make a copy of the value of the container, assignment is a pretty
natural way to go about doing that. Therefore, if possible, I think it
preferable to enable clients to be able to safely use that natural way,
particularly given that there is no way currently in the language
(perhaps there should be a way) of preventing clients from using
assignment at compile time.

A runtime error telling the client that they have done something silly
is probably better than nothing, but it is not ideal.

At some point you have to rely on the client reading, understanding and
implementing their use of your library as per your documentation, but as
a general principle, the more that things work as might otherwise be
naively expected (least surprise), the better.

So if you need defined assignment to make objects of your type do
sensible things with assignment, you should be providing defined assignment.

(Another somewhat relevant principle is that the more that can be
defended against at compile time, the better.)

With F2003, the natural way to copy the value of a polymorphic object is
to use ALLOCATE(dest, SOURCE=source). It very much bothers me that
this natural way will break resource management objects that rely on
finalization and defined assignment, even though I can write "don't use
ALLOCATE(dest, SOURCE=source)" in the documentation for my objects.

(VALUE arguments also have issues, but they aren't particularly natural
for Fortran procedures, so perhaps they can be ignored.)

Bear in mind that issues with assignment and ALLOCATE(...SOURCE=xxx)
apply to aggregates too, perhaps in the case where the problematic type
is several levels deep amongst the detailed implementation of a
component hierarchy, and not particularly visible to the programmer
writing an otherwise innocuous looking statement.
"Workaround" is probably being too nice. It is a hack, that
unfortunately needs to be considered with the language of today.

> Some difficulties that I see are:
> 1) the code for the generic iterable container can not be compiled on
> its own, it must be included

This is a good point. Ideally, given the specification of the
requirements of the object (as per immediately below), you want the
compiler to check that the generic code is internally consistent with
those requirements - e.g. if your generic code calls a binding of a
object of parameterised type, then the requirements on that object must
explicitly specify that such a binding is accessible.
I don't think that "extending" - taking that to specifically mean type
extension - has to be the way this is done. Other have mentioned
"interfaces" as they appear in java and other languages - I think is
likely to be more useful - please supply a type that has a given
not-the-fortran-concept-of-interface (given characteristics?), where
that not-the-fortran-concept-of-interface looks like some subset of that
of the numeric intrinsic types.

>> Additional language features that could be used to simplify things in
>> both library and client code include the F2008 feature that permits a
>> function reference with data pointer result to appear as a variable, and
>
> Interesting! Would this allow writing getters which look like
> components, such as container%get_data()(1:2:10) ?

No. You cannot, today, chain subobject selectors, such as a subscript
list, substring range or component selector, onto a function reference.

You could provide something approaching the equivalent of the subobject
selector through additional arguments to your get_data function:

! Start at one, go to 2, stepping 10
container%get_data(1,2,10) = xxx

I am in two minds about whether this is a problem or not. Careful
thought would need to be put into possible syntax ambiguity if the
possibility of chaining was considered.

>> the F2008 feature of intrinsic polymorphic allocation with F2003
>> functions with allocatable polymorphic results to provide container and
>> iterator constructors.
>
> Could you provide an example of this?

In the example code from your post above, you had a subroutine to return
a new iterator. It looked like:

subroutine new_iterator(it,iterator)
class(t_iterable_impl), intent(in) :: it
class(c_iterator), allocatable, intent(out) :: iterator

allocate( t_iterator_impl :: iterator )
select type(iterator); class is(t_iterator_impl)

if(size(it%objects).gt.0) then
iterator%here = 1
iterator%items => it%objects
else
iterator%here = -1
endif

end select
end subroutine new_iterator

and referenced in client code:

class(c_iterator), allocatable :: iter
...
call vars%new_iterator(item)

That could be rewritten:

function new_iterator(it) result(iterator)
class(t_iterable_impl), intent(in) :: it
type(t_iterator_impl) :: iterator

if(size(it%objects).gt.0) then
iterator%here = 1
iterator%items => it%objects
else
iterator%here = -1
endif

end function new_iterator

and referenced in client code:

class(c_iterator), allocatable :: iter
...
item = vars%new_iterator()

>> With all the above I am merely highlighting generic programming
>> alternatives with the current state of the language, I am not pretending
>> that those alternatives are ideal or acceptable.
>>
>>> 2) the implementation has to use pointers to ensure that things are
>>> TARGET. It would be nice to say that some components of a derived type
>>> are TARGETs due to their internal representation, without asking the
>>> user to remember this.
>>
>> Yes. The need to use pointer components to robustly ensure that
>> something is guaranteed to be a target is a nuisance. However,
>> conceptually this could get tricky.
>>
>> An example of using INCLUDE to implement a generic "shared pointer" can
>> be found at www.megms.com.au/shared-pointers.htm
>
> Interesting! Are you aware of any proposed extension of the language
> that would allow this without INCLUDE? I wonder whether one could
> rewrite your code with such an extension together with an "ad hoc"
> preprocessor to produce standard Fortran code. Parametrized modules
> have been mentioned on this list by you and others; do you also have
> examples using them?

There have been many proposals. In terms of things reasonably concrete
that I've seen, a proposal for parameterized modules that was considered
for F2008 is at http://j3-fortran.org/doc/year/05/05-195.pdf . That was
followed by a proposal for intelligent macros - see
http://j3-fortran.org/doc/year/05/05-280.txt - which was removed from
F2008 at quite a late stage.

(I am somewhat relieved that the macro approach was removed, as I think
the generic code that resulted with that approach was difficult to read,
plus I think there is reasonable experience from other languages that a
token substitution approach operates at too low a level - the author of
the generic code needs to be able to describe their requirements for
client supplied parameters in terms of the entities that result from the
semantic analysis of tokens.)

>> Other issues that I have encountered while putting that together:
>>
>> - Fortran's model of finalization has what I regard as significant holes
>> to do with ALLOCATE(..., SOURCE=xxx) and VALUE dummy arguments - the
>> generic library code loses control of aspects of construction and
>> finalization of those objects.
>
> As mentioned above, I also don't like source allocation. I think there
> should be a way to redefine this, much as there is now a way to
> redefine what WRITE means.

Yes - it may be possible to fix this hole by including a "value
construction binding" that is invoked as part of ALLOCATE(dest,
SOURCE=source).

Things become messier when considering VALUE arguments.

> Also, I don't like the overlapping between source allocation and
> assignment. I think that both of them are somehow too smart.
> (Concerning assignment, yes, it can be redefined, which is already
> good, but there are many overloaded operators and it is not easy to
> redefine *all* of them).

Assignment is special, compared to operators. If you don't provide an
definition of an operator for your derived type and a client uses that
operator, they get a diagnostic from the compiler. You don't "redefine"
a particular operator, you extend its definition to cover your type. You
cannot redefine the intrinsic operations.

But a user can, today, always use assignment, whether you [re]define it
or not.

>> - Often containers require defined assignment as part of their
>> implementation. Defined assignment is part of the internal
>> implementation, but it suppresses intrinsic assignment and the
>> associated reallocation on assignment of an object, which is visible to
>> clients. The workaround is to use an intermediate wrapper type in the
>> library code, which, as far as I can tell, insulates the client code.
>
> Yes, again, I see you are also not completely happy with assignment.
>
>> - Forwarding calls of a type bound procedure of a contained object
>> requires use of a temporary as you cannot apply binding references to
>> function results. (You can apply operators which map to type bound
>> procedures, and you can use non-type bound procedure references.)
>
> How is this related to your comment above about
>
>> F2008 feature that permits a function reference with data pointer
>> result to appear as a variable

Above, the inability to put a subobject selector of some sort on the end
of a function reference was discussed. You cannot stick a binding
reference on a function reference either. In the following, if get_data
is a binding of the container object to a function that returns an
object that is of a type that has a binding `some_binding`, you cannot
do something like:

xyz = container%get_data()%some_binding(x)

In the first instance, you need a temporary:

class(xxx), allocatable :: tmp
tmp = container%get_data()
xyz = tmp%some_binding(x)

(The parenthetical bits were because you can do something like
(obviously - this is just using a function reference as an actual argument):

xyz = some_procedure(container%get_data(), x)

where some_procedure does the same thing as some_binding, though without
the dispatch based on dynamic type that bindings involve.

If you still want that dynamic dispatch, and the nature of the other
arguments to the procedure is such that they can be operands, then you
could alternatively write something like:

xyz = container%get_data() .someoperator. x

where .someoperator. is a type bound binary defined operator.)

evan

unread,
Jul 2, 2016, 6:12:33 AM7/2/16
to
Personally, a module for random number generation from various distributions. It would be nice if that is compatible with openmp.

On Sunday, 19 June 2016 04:02:54 UTC+1, Richard Weed wrote:
> I would like to start a dialog on what people like me (a long time
> Fortran user developing codes for computational fluid and structural
> dynamics applications) would like to see in the next iteration of
> Fortran. In particular, I want to discuss what I think is missing
> from Fortran that would make my programming life a lot easier if
> implemented from a user standpoint (as opposed to a compiler
> developer and/or member of the standards committee). Some of the
> topics I intend to cover in separate posts are:
>
> 1. The need for a standard module and submodule format to allow
> interoperability between modules compiled with different
> compilers
>
> 2. The need for an intrinsic ADT facility that supports lists, queues,
> trees etc. (I know this has been discussed before at some length
> but I would like to put forward my ideas on how I would like to
> see them implemented)
>
> 3. The need for an intrinsic linear algebra facility that defines
> standard intrinsic types for matricies (dense and sparse) and standard
> interfaces with meaningful procedure names and not the abbreviated
> mess that is LAPACK (the implementation is still left to the compiler
> developers, I just want interfaces that will work with any linear
> algebra package in a standard way) to the most common linear algebra
> tasks (LU factorization, solving systems of equations, finding
> eigenvalues and eigenvectors condition numbers, matvecs, etc.)
>
> 4. Some things that I think should have been in the previous standards but
> for some reason were left out or rejected by the standards committee.
>
>
> I'll start with the need for a standard format for modules and submodules. I ran into this problem yesterday when I tried to use a version of PLplot I installed via software manager on my Linux Mint system with some code I compiled with the Intel compiler. I was trying to use the Fortran 90 interfaces so of course when I tried to USE plplot I got errors. Obviously, I could download PLplot and build an Intel specific version but my point is, why should I have to. I tried first to use an old version of PLplot I had compiled with Intel but after several OS upgrades etc. some of the shared object files needed were no longer found. If there was a standard format (it could be in addition to the existing compiler specific format but selected by a compiler flag say -fiso-module-format) I wouldn't have to waste time building PLplot. I could just use whats available and not worry about which compiler was used to build the third-party library (as long as the .o files are compatible - which is the case with Intel and gcc on Linux).
>
> So my questions to the user community (and compiler developers and standards committee folks) are.
>
> 1. Do others see the need for a standard module format that is interoperable
> between compilers (at least on Linux/Unix/BSD)
> 2. Has this been proposed in the past to the standards committees and if so
> why was it rejected
> 3. I realize this probably doesn't have a snowballs chance of being implemented
> but if it was I would like to hear from others on possible issues that
> would prevent it from being implemented
>
> I'll post my ideas on subjects 2-4 in separate posts
>
> RW

David Duffy

unread,
Jul 3, 2016, 1:40:48 AM7/3/16
to
evan <evan...@gmail.com> wrote:
> Personally, a module for random number generation from various
> distributions. It would be nice if that is compatible with openmp.

You mean like?

use fgsl
...
rv = fgsl_ran_landau_pdf(2.0d0)

kargl

unread,
Jul 3, 2016, 2:41:48 AM7/3/16
to
This of course has the drawback that GSL is a library covered
by a GPL license, which may restrict one's ability to use the GSL
in one's software.

I think Evan is suggesting that the Fortran standard should
include an API for a module such as ISO_RANDOM.

--
steve

Marco

unread,
Jul 5, 2016, 12:31:30 PM7/5/16
to
Am Thu, 30 Jun 2016 14:09:46 +1000 schrieb Ian Harvey:

> On 2016-06-28 7:40 PM, Marco wrote:
>>
>> For the container type: how would you leak memory using defined
>> assignment?
>
> I was imprecisely bundling "cannot leak memory" with general memory
> management issues. Without defined assignment you will end up with a
> "double free" situation, as you discuss below, if the user uses
> assignment on a container.
>
>> I can see that my present implementation can have two containers
>> pointing to the same content. This might or might not be waht is
>> desired. If it is, than the final subroutine must handle this
>> correctly.
>
> I don't think it is possible to write a final subroutine that can handle
> that situation correctly.

OK, I see. So once you have two pointers pointing to the same memory
freeing that memory through one of them is calling for problems with
the other one. One would need some mechanism to notify all the
pointers pointing to the same memory once such memory is deallocated,
but this is very difficult if the user can create those pointers at
will without passing through some methods.

To me, this seems one more reason to forbid client code from using
source allocation.

>> I think my preferred solution would be disabling assignment (i.e.
>> writing a fined assignment which calls "abort") and providing two
>> methods clone and make_a_reference .
>
> From the perspective of a client using the container, if they want to
> make a copy of the value of the container, assignment is a pretty
> natural way to go about doing that. Therefore, if possible, I think it
> preferable to enable clients to be able to safely use that natural way,
> particularly given that there is no way currently in the language
> (perhaps there should be a way) of preventing clients from using
> assignment at compile time.

The situation I have in mind is the following:

1) there is a library providing a container, let's say a linked list

2) there are other libraries using the container to provide generic
implementations of some algorithms, for instance one libraries for
ordinary differential equation (ODE) solvers and another one for
sparse matrices

3) there is a final user which has some data and needs the two
libraries for ODE and sparse matrices: this user will format his data
so that they can be inserted in the container, extending c_content,
and pass them to the two libraries.

I think the main goal should be shifting the burden of writing robust
code as much as possible on the container library 1), then on the two
libraries 2). Life should be made as simple as possible for the final
user 3).

My idea is requiring the ODE solver and the sparse matrix library to
use only two methods: source and copy. They should never use
"ALLOCATE" nor assignment. Then the final user 3) needs to provide
only these two methods to work reliably with his libraries.

Sure, when implementing 2) sometimes it would be easy to use "=" in
all its possible incarnations: arrays, scalars, elemental,
(re)allocate on assignment, but then the final user 3) *must*
implement all these methods. ALLOCATE is even worse, because the final
user might format his data using pointer components which then gets
duplicated behind his back.

> A runtime error telling the client that they have done something silly
> is probably better than nothing, but it is not ideal.

I agree, if possible I would prefer a compile time error, but I don't
know how to obtain it.

> At some point you have to rely on the client reading, understanding and
> implementing their use of your library as per your documentation, but as
> a general principle, the more that things work as might otherwise be
> naively expected (least surprise), the better.

OK, maybe triggering an error for "=" is too much, especially because
the final user might want to provide such a method for his own use.
Still, I would ask the code for the ODE solver and the sparse matrix
library to avoid both = and ALLOCATE - unfortunately there is no
compiler support here, one must rely on documentation. (Notice that
such error would be very difficult to find: everything is likely to
work for many cases where the default behavior of assignment and
source allocation is the right thing to do, but would fail in the more
complicated situations.)

> So if you need defined assignment to make objects of your type do
> sensible things with assignment, you should be providing defined assignment.
>
> (Another somewhat relevant principle is that the more that can be
> defended against at compile time, the better.)
>
> With F2003, the natural way to copy the value of a polymorphic object is
> to use ALLOCATE(dest, SOURCE=source). It very much bothers me that
> this natural way will break resource management objects that rely on
> finalization and defined assignment, even though I can write "don't use
> ALLOCATE(dest, SOURCE=source)" in the documentation for my objects.

Yes!

> (VALUE arguments also have issues, but they aren't particularly natural
> for Fortran procedures, so perhaps they can be ignored.)

Yes, I have never used VALUE myself, but I see the problem.

> Bear in mind that issues with assignment and ALLOCATE(...SOURCE=xxx)
> apply to aggregates too, perhaps in the case where the problematic type
> is several levels deep amongst the detailed implementation of a
> component hierarchy, and not particularly visible to the programmer
> writing an otherwise innocuous looking statement.

Yes, again, at a certain point I went through all of my codes and
removed (almost) all the source allocations. Now I see it as very low
level construct that should be isolated as much as possible from the
higher level code.

>>> Additional language features that could be used to simplify things in
>>> both library and client code include the F2008 feature that permits a
>>> function reference with data pointer result to appear as a variable, and
>>
>> Interesting! Would this allow writing getters which look like
>> components, such as container%get_data()(1:2:10) ?
>
> No. You cannot, today, chain subobject selectors, such as a subscript
> list, substring range or component selector, onto a function reference.
>
> You could provide something approaching the equivalent of the subobject
> selector through additional arguments to your get_data function:
>
> ! Start at one, go to 2, stepping 10
> container%get_data(1,2,10) = xxx
>
> I am in two minds about whether this is a problem or not. Careful
> thought would need to be put into possible syntax ambiguity if the
> possibility of chaining was considered.

I see.
OK. Still I think I prefer the subroutine version, where there is no
need to copy a c_iterator object. (OK, I am probably a little paranoid
about using assignment with polymorphic types!)

>>> With all the above I am merely highlighting generic programming
>>> alternatives with the current state of the language, I am not pretending
>>> that those alternatives are ideal or acceptable.
>>>
>>>> 2) the implementation has to use pointers to ensure that things are
>>>> TARGET. It would be nice to say that some components of a derived type
>>>> are TARGETs due to their internal representation, without asking the
>>>> user to remember this.
>>>
>>> Yes. The need to use pointer components to robustly ensure that
>>> something is guaranteed to be a target is a nuisance. However,
>>> conceptually this could get tricky.
>>>
>>> An example of using INCLUDE to implement a generic "shared pointer" can
>>> be found at www.megms.com.au/shared-pointers.htm
>>
>> Interesting! Are you aware of any proposed extension of the language
>> that would allow this without INCLUDE? I wonder whether one could
>> rewrite your code with such an extension together with an "ad hoc"
>> preprocessor to produce standard Fortran code. Parametrized modules
>> have been mentioned on this list by you and others; do you also have
>> examples using them?
>
> There have been many proposals. In terms of things reasonably concrete
> that I've seen, a proposal for parameterized modules that was considered
> for F2008 is at http://j3-fortran.org/doc/year/05/05-195.pdf . That was
> followed by a proposal for intelligent macros - see
> http://j3-fortran.org/doc/year/05/05-280.txt - which was removed from
> F2008 at quite a late stage.

Interesting. Seems to me that there are two ways of approaching the
problem:
1) you provide a template and "instantiate" it for the required cases
2) you provide a specific type and guarantee that it conforms to some
abstract model

Parametrized modules are an instance of 1), Java interfaces and
Haskell classes are examples of 2)


>>> Other issues that I have encountered while putting that together:
>>>
>>> - Fortran's model of finalization has what I regard as significant holes
>>> to do with ALLOCATE(..., SOURCE=xxx) and VALUE dummy arguments - the
>>> generic library code loses control of aspects of construction and
>>> finalization of those objects.
>>
>> As mentioned above, I also don't like source allocation. I think there
>> should be a way to redefine this, much as there is now a way to
>> redefine what WRITE means.
>
> Yes - it may be possible to fix this hole by including a "value
> construction binding" that is invoked as part of ALLOCATE(dest,
> SOURCE=source).

Indeed.

> Things become messier when considering VALUE arguments.

Do you think that there are many use cases for VALUE with "complex"
derived types? My understanding is that it is mostly useful for C
interoperability, which is restricted to "simple" types.

>> Also, I don't like the overlapping between source allocation and
>> assignment. I think that both of them are somehow too smart.
>> (Concerning assignment, yes, it can be redefined, which is already
>> good, but there are many overloaded operators and it is not easy to
>> redefine *all* of them).
>
> Assignment is special, compared to operators. If you don't provide an
> definition of an operator for your derived type and a client uses that
> operator, they get a diagnostic from the compiler. You don't "redefine"
> a particular operator, you extend its definition to cover your type. You
> cannot redefine the intrinsic operations.
>
> But a user can, today, always use assignment, whether you [re]define it
> or not.

Yes.
OK, nice language acrobatic... Still I think that all in all I can
live also without these.

Thank you again,
Marco

Thomas Koenig

unread,
Jul 5, 2016, 2:25:15 PM7/5/16
to
Wolfgang Kilian <kil...@invalid.com> schrieb:
> Templates are somewhat in-between of a macro facility
> and a language intrinsic, and some people may argue that it exhibits the
> flaws of both. A language designer might fear the effort to do this
> right the next time, not opening a can of worms.

At least C++ templates are Turing complete (which the C++ standards
comittee was not aware of when they specified them). This, of
course, means that there is no algorithm to decide if a C++ program
is valid or not, because this would solve the halting problem.

Sooo... be careful what features you wish for. You might get them :-)

herrman...@gmail.com

unread,
Jul 5, 2016, 9:17:31 PM7/5/16
to
On Tuesday, July 5, 2016 at 9:31:30 AM UTC-7, m wrote:

(snip)

> > I don't think it is possible to write a final subroutine that can handle
> > that situation correctly.

> OK, I see. So once you have two pointers pointing to the same memory
> freeing that memory through one of them is calling for problems with
> the other one. One would need some mechanism to notify all the
> pointers pointing to the same memory once such memory is deallocated,
> but this is very difficult if the user can create those pointers at
> will without passing through some methods.

Java uses garbage collection, so that the user (programmer) doesn't have
to keep track of what to deallocate. There is some inefficiency, but maybe
not huge. Some garbage collect systems can't figure out circular linked
lists, where every element has a pointer to it, but you still can't get there.

> To me, this seems one more reason to forbid client code from using
> source allocation.

(snip)

> 1) there is a library providing a container, let's say a linked list

> 2) there are other libraries using the container to provide generic
> implementations of some algorithms, for instance one libraries for
> ordinary differential equation (ODE) solvers and another one for
> sparse matrices

> 3) there is a final user which has some data and needs the two
> libraries for ODE and sparse matrices: this user will format his data
> so that they can be inserted in the container, extending c_content,
> and pass them to the two libraries.

> I think the main goal should be shifting the burden of writing robust
> code as much as possible on the container library 1), then on the two
> libraries 2). Life should be made as simple as possible for the final
> user 3).

As usual, being more general means less efficient. Often that doesn't
matter, but sometimes it does.

I suspect that both for ODE and sparse matrix solvers, efficiency is
fairly important, and that it is worth writing one for the specific case
at hand.

> My idea is requiring the ODE solver and the sparse matrix library to
> use only two methods: source and copy. They should never use
> "ALLOCATE" nor assignment. Then the final user 3) needs to provide
> only these two methods to work reliably with his libraries.


(snip)

-- glen

Wolfgang Kilian

unread,
Jul 6, 2016, 4:16:37 AM7/6/16
to
That was the "can of worms" part :-)

I'd guess that a templating mechanism where an entity can't depend on
itself, directly or indirectly, would evade some dangers without
excluding the most wanted applications. Modules in Fortran are subject
to such a restriction, and compilers detect circular dependencies.

Another argument against plain preprocessor/macro solutions, which
typically allow recursive expansion.

Van Snyder

unread,
Jul 6, 2016, 10:16:26 PM7/6/16
to
On Saturday, June 18, 2016 at 10:59:37 PM UTC-7, campbel...@gmail.com wrote:

> In the present design, the interface definition and the routine are a duplicate of the routines interface. This duplication of code is wrong and I would like to see the INTERFACE defined in a module, which can be USEd in the routine, as the definition of the interface. In this way we could have a "USE all_interfaces" that could provide routine checking throughout the code, without all the mess that is there at present.

Put procedures in modules instead of using external procedures. There is no separate interface (unless you use submodules), no duplication, and no chance to get it wrong without the compiler checking.

Van Snyder

unread,
Jul 6, 2016, 10:21:36 PM7/6/16
to
On Saturday, June 18, 2016 at 8:02:54 PM UTC-7, Richard Weed wrote:
> 2. The need for an intrinsic ADT facility that supports lists, queues,
> trees etc. (I know this has been discussed before at some length
> but I would like to put forward my ideas on how I would like to
> see them implemented)

The current definition of object-oriented programming in Fortran makes building containers of any sort difficult. If containers (lists, stacks, queues, trees, ...) were easier to write, and one could contain any type of object, perhaps even heterogeneous objects, would that solve your problem?

Van Snyder

unread,
Jul 6, 2016, 10:29:51 PM7/6/16
to
On Sunday, June 19, 2016 at 6:25:26 AM UTC-7, herrman...@gmail.com wrote:
> Note that Fortran finally has a matrix multiply intrinsic, though even for
> that case there might be better ways for some users. No intrinsic matrix
> inversion, though. (Unless added since I looked last.)

If you're solving a linear system, you might think that you want the matrix inverse, but generally you don't. Computing the inverse and then multiplying it by the RHS costs twice as much as just solving the system.

You might want the inverse if you want the covariance matrix for the solution of a least-squares problem, but this is easier to compute either from the QR decomposition or the Cholesky factorization, which you need to do anyway if you want a solution (as opposed to just wanting a covariance matrix).

Where else do you actually want the inverse?

Van Snyder

unread,
Jul 6, 2016, 10:31:20 PM7/6/16
to
On Sunday, June 19, 2016 at 6:25:26 AM UTC-7, herrman...@gmail.com wrote:

> I don't know Fortran OO well enough yet. Is there anything like the
> Java interface?

Fortran OO is based on ideas from Simula and Oberon.

Van Snyder

unread,
Jul 6, 2016, 10:37:18 PM7/6/16
to
On Sunday, June 19, 2016 at 12:00:37 PM UTC-7, herrman...@gmail.com wrote:
> On Sunday, June 19, 2016 at 9:40:40 AM UTC-7, Richard Weed wrote:
> > 2. My call for intrinsic facilities for ADTs...
> > Object based routines using unlimited polymorphism to handle linked lists,
> > queues, red-black trees etc. After several thousand lines of code I have something
> > that works for both instrinsic data types and a user derived type.
>
> There has been discussion of that, but as far as I know, you are the first to do it.
>
> As far as I know, it is pretty recently that unlimited polymorphism was ready to be
> able to do such.

Unlimited polymorphism isn't quite ready for it. There are limitations intended to be helpful that actually make development of general containers quite difficult.

Van Snyder

unread,
Jul 6, 2016, 10:39:24 PM7/6/16
to
On Sunday, June 19, 2016 at 9:40:40 AM UTC-7, Richard Weed wrote:

> Again, thanks to all for your comments. Hopefully, we are providing the standards folks with ideas for the next Fortran

Please consider participating as one of the standards folks, instead of as a back-bencher. Standards committees are not "by invitation only" clubs. We rely on volunteers. We need members who have interests other than anti-trust protection and limiting workload.

Van Snyder

unread,
Jul 6, 2016, 10:53:18 PM7/6/16
to
On Sunday, June 19, 2016 at 2:10:26 PM UTC-7, Wolfgang Kilian wrote:
> As I understand the OP's post, he also refers to a distinct capability
> gap in the language, namely the inability to provide generic containers
> which are strongly typed, in the same sense as arrays are strongly
> typed. Class(*) doesn't solve this problem in any satisfactory way.
>

> > That's not to say that there isn't substantial room for improvement in
> > how the language supports things like generic data structures, I could
> > rant for days about that, but that is not the same thing as actually
> > building specific data structures into the base language.
> >
> > I recall some proverb from school that went something like "Give a
> > programmer a new intrinsic type and you keep them happy for a day, teach
> > their language how to support generic libraries and keep them happy for
> > a lifetime", but I might have that wrong - too busy fishing to pay
> > attention.

> The ability to write strongly typed generic code can only come as an
> extension of the language itself. Specific incarnations (list, queue,
> etc.) might be provided via intrinsic modules as a convenience (see
> STL), but that's secondary.

While Fortran 2004 was still under development, Richard Maine remarked that there were serious gaps in the integration of type-bound procedures and parameterized data types. In particular, it is possible to write a type with kind type parameters, and provide some type-bound procedures to operate on objects of the type. But if you fail to provide a sufficient spectrum of type-bound procedures that have kind type parameters for their arguments and results that might be used to instantiate objects, you can't even compile the code. The problem is that one can declare an object with any kind type parameter the processor provides, but the procedures are cast in concrete; you can't instantiate them with different kind type parameters the way you can declare objects.

To address this, "generic programming" was briefly on the work plan for Fortran 2015. There was discussion to provide it using parameterized modules, along the lines of Ada generic packages, or macros. Macros were chosen (I prefer parameterized modules), but eventually the perfect was the enemy of the good enough, and nothing was done.

BTW, I prefer parameterized modules because it is easy to convince oneself that the types and their type-bound procedures are consistent. Macros don't offer much obvious help in this direction (and they're ugly too).

Van Snyder

unread,
Jul 6, 2016, 10:58:04 PM7/6/16
to
On Sunday, June 19, 2016 at 6:22:52 PM UTC-7, Richard Maine wrote:

> Now if someone has good ideas on how the base language can better
> facilitate users doing such structures [ADTs], that's a completely different
> matter.

The difficulty in developing containers arises from restrictions on polymorphism that are intended to be helpful (i.e., compile-time checking vs. going bang at run-time without a chance to catch the error) but that make it very difficult to write containers (stacks, lists, queues, trees, ...). I proposed a a facility to address this, but it went nowhere.

Van Snyder

unread,
Jul 6, 2016, 11:05:18 PM7/6/16
to
On Sunday, June 19, 2016 at 8:41:22 AM UTC-7, Richard Maine wrote:
> ... Sure it is easy and cheap to have someone else do
> things for you. But adding things to the standard is not at all easy,
> cheap, or fast. It just happens to be work done by oher people than you.

I agree with Richard that the standard should provide general rather than specific support.

Things done by the standard are helpful for users, but perhaps difficult and expensive for vendors. The difference is that vendors have thousands (hopefully) of customers, so whatever they provide can be amortized over their customer base at reasonable cost, rather than every customer who needs it needing to invent it again, at something more closely approaching the vendor's cost.

I don't object to paying for my compiler license. If the fee increased by a few percent per year because the vendor invested some significant effort to make my life more efficient and reliable (and hopefully the same for others), I don't begrudge paying for it. Having other people than me doing it isn't the same as having other people do it for free.

Van Snyder

unread,
Jul 6, 2016, 11:16:35 PM7/6/16
to
On Sunday, June 19, 2016 at 5:07:42 PM UTC-7, Ian Harvey wrote:


> Support for generic data structures would be great. Bring it on...
> where do I sign?

I proposed parameterized modules in http://j3-fortran.org/doc/year/05/05-195.pdf (and earlier papers cited therein).

You can join J3 (now called PL22.3) any time you wish. It's not an invitation-only club. Unfortunately, you can't really accomplish much unless you actually do join and participate. I tried to do this for many years and didn't accomplish anything at all. We need more users. The current committee is dominated by vendors who appear to be primarily interested in three things: Pushing their new stuff, anti-trust protection, and limiting their workloads.

> (Just don't do it using macros or other dumb text preprocessing please.)

I agree 100%.

Van Snyder

unread,
Jul 6, 2016, 11:21:37 PM7/6/16
to
On Monday, June 20, 2016 at 1:34:34 AM UTC-7, m wrote:

> 1) the ability of saying that two polymorphic objects have the same
> dynamic type, like
>
> subroutine multiply( res , a , b )
> class(t_vector) :: a
> type( the_same_dynamic_time_as_a ) :: b, res

This was suggested and rejected during development of requirements for the object-oriented system in Fortran 2003. The problem is that it could create an un-catchable runtime error. Block-structured exception handling has also been proposed, to address this sort of problem (and others), but that's been rejected too.

Ian Harvey

unread,
Jul 7, 2016, 12:07:07 AM7/7/16
to
On 7/7/2016 1:16 PM, Van Snyder wrote:
> On Sunday, June 19, 2016 at 5:07:42 PM UTC-7, Ian Harvey wrote:
>
>
>> Support for generic data structures would be great. Bring it on...
>> where do I sign?
>
> I proposed parameterized modules in
> http://j3-fortran.org/doc/year/05/05-195.pdf (and earlier papers
> cited therein).
>
> You can join J3 (now called PL22.3) any time you wish. It's not an
> invitation-only club...

I suspect actually going to a typical meeting might be a bit beyond the
limits of my Opal card though.

Ian Harvey

unread,
Jul 7, 2016, 12:32:20 AM7/7/16
to
In the general case, unlimited polymorphic things (CLASS(*)) are not the
right concept for implementing general containers. This is independent
of any language limitations, helpful or otherwise.

They have a role for dynamic storage of things where, from a runtime
perspective, the stretch of source code using unlimited polymorphic has
absolutely no clue or care about what is being stored. But that role is
quite atypical.

What are the "limitations intended to be helpful" that you refer to?
It is loading more messages.
0 new messages