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

Handling arrays of derived types in an object-oriented way

264 views
Skip to first unread message

Blokbuster

unread,
Dec 21, 2015, 4:00:45 AM12/21/15
to

I've been trying to learn the object-oriented aspects of modern Fortran and frequently come across the same problem. Perhaps I am not thinking about this the right way, or do not understand the oop approach in general. I would be grateful for any input.

Say I have a derived type like this:

type typeA
private
! some variables
contains
! some type-bound procedures
end type typeA

I often want to make use of arrays of a derived type. If I want to define type-bound procedures that combine or compare the elements of such an array, this cannot be done with elemental routines, and I have to do something like:

type typeB
private
type(typeA), allocatable :: my_types(:)
! perhaps some other variables
contains
! some type-bound procedures dealing with array my_types
end type typeB


The problem now is that typeB does not have access to the variables of typeA, since I want to keep these private. So I would have to create lots of "getter" and "setter" routines in type A, which would probably only be used when typeB wants to act on its internal typeA array. This seems clumsy to me.

An alternative that occurs to me is something like this:


module dostuff

implicit none
private :: typeC
public :: typeA, typeB


type typeC
! some public variables
contains
! some type-bound procedures
end type typeC

type typeA
private
type(typeC) :: my_type
! maybe some other variables
contains
! perhaps some extra procedures
end type typeA

type typeB
private
type(typeC), allocatable :: my_types(:)
! maybe some other variables
contains
! some type-bound procedures
end type typeB

contains

! definitions of type-bound procedures

end module dostuff

This seems reasonable, although I would have to keep all this in one module if I want to restrict access to typeC. This may get unwieldy.

All I really want to do is to allow typeB access to the variables in typeA, without allowing free access to these variables. Is there any better way of doing this?

A more specific question, in module dostuff above, instead of typeA can I do something like:

type, extends(typeC) :: typeA_new
private
! perhaps some extra variables
contains
! perhaps some extra procedures
end type typeA_new

to achieve the same thing? It doesn't seem so - if I try a simple example the variables defined in typeC remain public despite the "private" in typeA_new.

many thanks,
B

FortranFan

unread,
Dec 21, 2015, 9:00:19 AM12/21/15
to
On Monday, December 21, 2015 at 4:00:45 AM UTC-5, Blokbuster wrote:

> .. Perhaps I am not thinking about this the right way, or do not understand the oop approach in general. I would be grateful for any input.
>
> .. I want to define type-bound procedures that combine or compare the elements of such an array, this cannot be done with elemental routines, ..

If you can post some actual code of a small case that illustrates what you exactly you mean by "combine or compare the elements" instead of "pseudo" code, it might make it easier to suggest approaches.

Separately I do suggest you review OO design and programming general (for C++, Java, Microsoft .NET, Ruby, etc.), for that will allow you to create programming solutions in Fortran that are largely consistent with recommended "good practices" of the OO paradigm as followed more broadly in the programming world.

Finally, some food for thought: if you look at OO design and programming in other languages, you will notice there are some accepted practices to code certain actions on class members to be done by member functions of the class (type-bound procedures in Fortran) but some actions by so-called "friends" of the class (module procedures in Fortran perhaps come closest to this?). Is the latter an option for you? Can you simply have module procedures for "combiner" and "comparer" actions in the module for typeA? An alternative might be type-bound procedures with NOPASS attribute, but its usage can be confusing for some "consumers" of your class.

Blokbuster

unread,
Dec 21, 2015, 9:55:34 AM12/21/15
to
Thanks very much for your input - I'll have a think about a simple example that shows what I mean.

At your suggestion I've had a bit of a read and it looks like I am asking for an equivalent of "friend" classes in C++, but this doesn't exist in Fortran (as far as I can tell).

many thanks,
B

Wolfgang Kilian

unread,
Dec 21, 2015, 10:34:18 AM12/21/15
to
In Fortran there is no requirement for modules to contain just one type.
Neither is this required by OO good practice, it merely happens to be
mandatory in some popular languages other than Fortran. Modules collect
pieces that logically belong together and sometimes have to access each
others' internals. (After 2008, the latter part would be deferred to
submodules.) So take the liberty to collect both the element and the
array in a common module. Modules are more coarse-grained entities than
types.

Regarding extending a type, you may do this in the same module - then
all private components are accessible. Or you do it in a different
module - then they are inaccessible, but you still automatically
delegate calls from the extension to the base type if you do not
override the TBP. Such design depends on the nature of the problem.

-- Wolfgang

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

Blokbuster

unread,
Dec 21, 2015, 11:06:59 AM12/21/15
to

>
> In Fortran there is no requirement for modules to contain just one type.
> Neither is this required by OO good practice, it merely happens to be
> mandatory in some popular languages other than Fortran. Modules collect
> pieces that logically belong together and sometimes have to access each
> others' internals. (After 2008, the latter part would be deferred to
> submodules.) So take the liberty to collect both the element and the
> array in a common module. Modules are more coarse-grained entities than
> types.
>
> Regarding extending a type, you may do this in the same module - then
> all private components are accessible.


Now I didn't know that. I think my problem just (more or less) evaporated. Thank you very much.

B

michael siehl

unread,
Dec 21, 2015, 11:19:20 AM12/21/15
to
|In Fortran there is no requirement for modules to contain just one type.
| Neither is this required by OO good practice, it merely happens to be
|mandatory in some popular languages other than Fortran. Modules collect
|pieces that logically belong together and sometimes have to access each
|others' internals. (After 2008, the latter part would be deferred to
|submodules.) So take the liberty to collect both the element and the
|array in a common module. Modules are more coarse-grained entities than
|types.

I agree with that. I have long-termed experiences with handling F9x Abstract Data Type collections that way. Since the collection and it's objects declarations and code are in the same module, it allows to directly access the object members from the collection code. (I plan to leave the collection's code into a submodule of it's own). Together with Fortran's array syntax and WHERE construct, this allows a coding style somewhat similar to Microsoft's LINQ to Objects style (nevertheless, we used the Fortran style long before they invented LINQ), but with a much higher perfomance. It also allows a kind of general-pupose SIMD parallelsim if we can solve the problem of data allignment. (An important issue for many-core).

FYI, I am currently coding an example program that also shows how we can use Coarray Fortran to "distribute" ADT objects to a limited set of coarray images (resp. processor cores). It will be online in January or February I guess, and I will give insights into the simple coding requirements soon.

best regards
Michael

www.coarray-fortran.michael-siehl.de

FortranFan

unread,
Dec 21, 2015, 12:06:13 PM12/21/15
to
On Monday, December 21, 2015 at 11:06:59 AM UTC-5, Blokbuster wrote:
> >
> > In Fortran there is no requirement for modules to contain just one type.
> > Neither is this required by OO good practice, ..
> > Regarding extending a type, you may do this in the same module - then
> > all private components are accessible.
>
>
> Now I didn't know that. I think my problem just (more or less) evaporated. Thank you very much.
>

Not sure what you're implying here - is it about modules having more than one type? Your original post shows your alternative case to have more one type, so it came across that you were aware of it.

Re: the post you quote which indicated, "Neither is this required by OO good practice" about "no requirement for modules to contain just one type", few things, if any, are ever truly required by good practices - there are strong recommendations for or against certain things in any G*P sets, I'm not sure any of them can truly be viewed as requirements, per se.

Anyways, there indeed is a OO good practice recommendation for Fortran that suggest limiting to one "class" (derived type with TBPs in Fortran) per module (I'm unable to immediately provide a reference, but I might be able to look it up later). But as to whether you want to follow it or not is up to you.

If you want to pursue OO more deeply, you should consider the approach where certain procedures (functions), depending on what they do, may be "friend of the class" rather than member functions. In your case, it could turn out to be just a simple module procedures that operates on the TYPE (as opposed to a TBP with CLASS attribute for the dummy argument for the passed object which can have some overhead).

Richard Maine

unread,
Dec 21, 2015, 12:47:20 PM12/21/15
to
FortranFan <pare...@gmail.com> wrote:

> Anyways, there indeed is a OO good practice recommendation for Fortran
> that suggest limiting to one "class" (derived type with TBPs in Fortran)
> per module (I'm unable to immediately provide a reference, but I might
> be able to look it up later). But as to whether you want to follow it
> or not is up to you.

I've certainly seen that recommended. But, as with many style issues,
the recommendation isn't universal. For example, I don't much agree with
that one.

This is partly the difference, which I have mentioned in general terms
before, between Fortran being an "object-oriented language" versus a
language that includes object-oriented concepts.

If you start with the thesis that object orientation is the
be-all/end-all, then you wrap everything around it and you end up with
principles like that classes and modules are practically
indistinguishable.

But if you view object-oriented features as just part of Fortran's tool
set, then the mapping of a class to a module isn't always as natural.
Sometimes, but not always. That's more my general leaning.

It's also the way that OO stuff got introduced into the language. I
recall the presentation (by John Cuthbertson - hope I spelled that
right, as it has been over 2 decades) at a J3 meeting where I first
started to "get" some of the OO principles. That was because John showed
what they meant in terms of existing Fortran features in a way that made
me realize that stuff could help my existing code. Indeed, I had been
using some of the ideas without knowing that they counted as OO ideas
and without knowing the terms. In John's presentation I saw how the
language could help instead of hinder application of those ideas; I also
saw some generalizations and expansions that I had not previously
appreciated.

Alas, adequately widespread compiler support was slow enough in comming
that I never had the opportunity to actually use the f2003 OO features
in my real work before I retired in 2007. (My apps needed to work with
a broad spectrum of compilers - not just a handful. And no, telling
users that they could install one of the supported compilers was not
viable for reasons discussed here before.)

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

Wolfgang Kilian

unread,
Dec 22, 2015, 2:11:02 AM12/22/15
to
On 21.12.2015 18:06, FortranFan wrote:
> On Monday, December 21, 2015 at 11:06:59 AM UTC-5, Blokbuster wrote:
>>>
>>> In Fortran there is no requirement for modules to contain just one type.
>>> Neither is this required by OO good practice, ..
>>> Regarding extending a type, you may do this in the same module - then
>>> all private components are accessible.
>>
>>
>> Now I didn't know that. I think my problem just (more or less) evaporated. Thank you very much.
>>
>
> Not sure what you're implying here - is it about modules having more than one type? Your original post shows your alternative case to have more one type, so it came across that you were aware of it.
>
> Re: the post you quote which indicated, "Neither is this required by OO good practice" about "no requirement for modules to contain just one type", few things, if any, are ever truly required by good practices - there are strong recommendations for or against certain things in any G*P sets, I'm not sure any of them can truly be viewed as requirements, per se.
>
> Anyways, there indeed is a OO good practice recommendation for Fortran that suggest limiting to one "class" (derived type with TBPs in Fortran) per module (I'm unable to immediately provide a reference, but I might be able to look it up later). But as to whether you want to follow it or not is up to you.

Maybe there is, but this particular one I would not follow. The
software designer should use the distinction between type (class) and
module to his advantage, such that the logical and algorithmic structure
is reflected transparently in code design.

There are useful design patterns (or, you could think of mathematical
structures) that basically consist of more than one object type. They
naturally map into modules, typically one module for the abstract types
(interface) and one or more separate modules for the concrete extensions
(implementation).

> If you want to pursue OO more deeply, you should consider the approach where certain procedures (functions), depending on what they do, may be "friend of the class" rather than member functions. In your case, it could turn out to be just a simple module procedures that operates on the TYPE (as opposed to a TBP with CLASS attribute for the dummy argument for the passed object which can have some overhead).
>

The necessity for 'friend' and similar concepts in languages like C++ is
often quoted as a deficiency in language design.

Blokbuster

unread,
Dec 22, 2015, 2:16:56 AM12/22/15
to
On Monday, December 21, 2015 at 5:06:13 PM UTC, FortranFan wrote:
> On Monday, December 21, 2015 at 11:06:59 AM UTC-5, Blokbuster wrote:
> > >
> > > In Fortran there is no requirement for modules to contain just one type.
> > > Neither is this required by OO good practice, ..
> > > Regarding extending a type, you may do this in the same module - then
> > > all private components are accessible.
> >
> >
> > Now I didn't know that. I think my problem just (more or less) evaporated. Thank you very much.
> >
>
> Not sure what you're implying here - is it about modules having more than one type? Your original post shows your alternative case to have more one type, so it came across that you were aware of it.
>

I wasn't aware that the type-bound procedure of one derived type can access the private variables of another, if both the derived types are in the same module.

> Re: the post you quote which indicated, "Neither is this required by OO good practice" about "no requirement for modules to contain just one type", few things, if any, are ever truly required by good practices - there are strong recommendations for or against certain things in any G*P sets, I'm not sure any of them can truly be viewed as requirements, per se.
>
> Anyways, there indeed is a OO good practice recommendation for Fortran that suggest limiting to one "class" (derived type with TBPs in Fortran) per module (I'm unable to immediately provide a reference, but I might be able to look it up later). But as to whether you want to follow it or not is up to you.
>

This is what I have been doing up until now. But now I am thinking whether I may have to change this approach, and group together closely related types.

> If you want to pursue OO more deeply, you should consider the approach where certain procedures (functions), depending on what they do, may be "friend of the class" rather than member functions. In your case, it could turn out to be just a simple module procedures that operates on the TYPE (as opposed to a TBP with CLASS attribute for the dummy argument for the passed object which can have some overhead).

I think I could also do what I want with friend functions. However, I do wonder whether friend functions actually break encapsulation, since anything can access them. I need to read up on this a bit more, but it seems to me initially that having "friend" types sharing a module is the better approach.

many thanks,
B

michael siehl

unread,
Dec 22, 2015, 9:36:02 AM12/22/15
to
|I wasn't aware that the type-bound procedure of one derived type can access |the private variables of another, if both the derived types are in the same |module.


I can't confirm that this will work, but I am also somehow off-topic here because I am a F90/95-style developer and do not use type-bound procedures. My above post relates to F9x Abstract Data Types. Instead of code reuse through type extension (inheritence) we use type inclusion and, more importantly, a simple naming convention which turns all of our F90/95-style code into template code.
With that, we believe to have better access to Fortran's SIMD parallelism (see my post above) as well as Fortran's MIMD parallelism (Coarray Fortran).

best regards
michael

Wolfgang Kilian

unread,
Dec 22, 2015, 10:22:46 AM12/22/15
to
On 22.12.2015 15:35, michael siehl wrote:
> |I wasn't aware that the type-bound procedure of one derived type can access |the private variables of another, if both the derived types are in the same |module.

A module procedure can access the private components of a derived-type
object if (1) it can access the object, and (2) the object type
definition resides in the same module as the procedure code.

This is not related to type binding in any way, the rule is part of
plain Fortran 90. The F2003 feature of binding a procedure to a type is
nothing more than a syntactic shortcut, as far as this rule is concerned.
>
> I can't confirm that this will work, but I am also somehow off-topic here because I am a F90/95-style developer and do not use type-bound procedures. My above post relates to F9x Abstract Data Types. Instead of code reuse through type extension (inheritence) we use type inclusion and, more importantly, a simple naming convention which turns all of our F90/95-style code into template code.
> With that, we believe to have better access to Fortran's SIMD parallelism (see my post above) as well as Fortran's MIMD parallelism (Coarray Fortran).

Please keep us up to date if you can post more details, I'd be interested.

> best regards
> michael

michael siehl

unread,
Dec 22, 2015, 2:18:37 PM12/22/15
to
| Please keep us up to date if you can post more details, I'd be interested.

Thanks for your interest. I will post more details soon.

FortranFan

unread,
Dec 22, 2015, 6:37:38 PM12/22/15
to
On Tuesday, December 22, 2015 at 2:11:02 AM UTC-5, Wolfgang Kilian wrote:

> ..
> Maybe there is, but this particular one I would not follow. The
> software designer should use the distinction between type (class) and
> module to his advantage, such that the logical and algorithmic structure
> is reflected transparently in code design.
>
> ..
>
> The necessity for 'friend' and similar concepts in languages like C++ is
> often quoted as a deficiency in language design.
>
> ..


It's perhaps a certain fraction of OO purists who think of "friend" feature in C++, etc. to be a deficiency in the language i.e., in its ability to handle data encapsulation "properly" in program design. The same OO purists will absolutely scoff at Fortran offerings for OO in general and practices such as those by yourself in particular if you routinely allow more than one "class" aka derived type with TBPs in a Fortran module. The point is worthless.

Now I don't believe in hard and fast rules, definitely not for OO where several patterns can similarly meet code design needs and requirements. It's just that in general, from a data encapsulation point of view, it is a safe starting point, especially for beginners in OO such as the OP here, to have only one "class" aka derived type with TBPs in a Fortran module. But to each their own..

Back to the point on "friend" functions, it's of no relevance what certain OO purists might think. The analogy of "friend" functions in this thread is only of importance to OP in his attempt to learn OO concepts further and to tie the code design options as followed by OO practitioners in other languages to what might be a decent approach for him in Fortran. And the other point is that certain actions are better done by plain old module procedures rather than TBPs.

The bad part of this thread is that OP won't explain what is meant by, "I want to define type-bound procedures that combine or compare the elements of such an array". Clear exposition of this would have led to a good discussion of OO design options; obfuscation of this detail (wherein lies the crux of the matter in the original post) can only help yet another c.l.f thread to veer off in the useless direction.

Jos Bergervoet

unread,
Dec 22, 2015, 7:44:23 PM12/22/15
to
On 12/23/2015 12:37 AM, FortranFan wrote:
> On Tuesday, December 22, 2015 at 2:11:02 AM UTC-5, Wolfgang Kilian wrote:
>> ..
>> Maybe there is, but this particular one I would not follow. The
>> software designer should use the distinction between type (class) and
>> module to his advantage, such that the logical and algorithmic structure
>> is reflected transparently in code design.
>> ..
>>
>> The necessity for 'friend' and similar concepts in languages like C++ is
>> often quoted as a deficiency in language design.
>> ..
>
> It's perhaps a certain fraction of OO purists who think of "friend" feature
> in C++, etc. to be a deficiency in the language i.e.,

But I see clear arguments given in this thread. What about
Blokbuster's remark that friend functions "may actually
break encapsulation, since anything can access them"?

> The same OO purists will absolutely scoff at Fortran offerings for OO in general

They may not always be the same (I'm not sure if Wolfgang
will scoff at Fortran offerings, for instance).

> and practices such as those by yourself in particular if you routinely allow
> more than one "class" aka derived type with TBPs in a Fortran module.
> The point is worthless.

Perhaps you could give some arguments as well? (Lest OP
might do exactly that: more than one in a module!)

..
> The bad part of this thread is that OP won't explain what is meant by,
> "I want to define type-bound procedures that combine or compare the
> elements of such an array". Clear exposition of this would have led
> to a good discussion of OO design options; obfuscation of this detail
> (wherein lies the crux of the matter in the original post) can only help
> yet another c.l.f thread to veer off in the useless direction.

You may be right. Explicit examples are always very useful.
But still.. finding the definitive answer about the desirability
of friend functions could be an important topic by itself.

--
Jos

Blokbuster

unread,
Dec 23, 2015, 3:04:34 AM12/23/15
to

> The bad part of this thread is that OP won't explain what is meant by, "I want to define type-bound procedures that combine or compare the elements of such an array". Clear exposition of this would have led to a good discussion of OO design options; obfuscation of this detail (wherein lies the crux of the matter in the original post) can only help yet another c.l.f thread to veer off in the useless direction.


OK, here is a simple (perhaps far too simple) example:

Say I have a derived type "month" with a private variable "days":


type month
private
integer :: days
end type month

Then I have another type "year" that includes an array of "month"s:

type year
private
type(month) :: months(12)
end type year

Let's say I want a type-bound procedure that calculates the total days in the year:


type year
private
type(month) :: months(12)
contains
procedure :: total_days
end type year

What I have learned in this thread is that if I put "month" and "year" in the same module, then the procedure "total_days" can be written simply:

function total_days(self)
class(year) :: self
integer :: total_days
total_days = sum(self%months%days)
end function total_days

I didn't previously realise that. However, if I have types "month" and "year" in separate modules, how would I do that? The options I am aware of are:

1) write a "get_days" procedure in "month" to retrieve the number of days in the month. "Year" would then use this to calculate the number of days in the year.

2) write a type-bound no-pass procedure in "month" that sums the number of days in an array of months.

3) In the same module as "month", write a "friend" function that calculates the number of days in an array of months. "year" could then use this function.

To me, (1) seems pointless, I may as well just make the variables in "month" public. (2) is confusing, as the days in a year are an aspect of a year, not a month. (3) is a possibility, and works, but allows the days of arbitrary groups of months to be summed - perhaps I only want to operate on the specific set of months that make up a year. Of course I could write the friend function with restrictions to make sure it only sums over a year, but again, the detail of what a year is surely belongs in the "year" type, and not in the module with the "month" type.

B

Damian Rouson

unread,
Dec 23, 2015, 1:21:52 PM12/23/15
to
On Wednesday, December 23, 2015 at 12:04:34 AM UTC-8, Blokbuster wrote:
> > The bad part of this thread is that OP won't explain what is meant by, "I want to define type-bound procedures that combine or compare the elements of such an array". Clear exposition of this would have led to a good discussion of OO design options; obfuscation of this detail (wherein lies the crux of the matter in the original post) can only help yet another c.l.f thread to veer off in the useless direction.
>
>
> OK, here is a simple (perhaps far too simple) example:
>
> Say I have a derived type "month" with a private variable "days":
>
>
> type month
> private
> integer :: days
> end type month

I realize you have probably simplified things for the sake of discussion, but the above code exposes a possible design problem that might also explain why you want to avoid setters and getters. If the runtime overhead or coding hassle of calling a function to get data (or a single datum in this case) versus accessing the data directly is significant, then it's very likely that one needs to step back and rethink the choice of data structures vis a vis the overall algorithm.

It is quiet often the case that scientific programmers who first encounter OOP find it to be inefficient (I'm guessing you consider setters and getters to be inefficient or a hassle) when actually the problem is not OOP. The problem lies in the object-oriented design (OOD), which I'll define as the chosen decomposition of the application into a set of derived types with specific (private) components and type-bound procedures, including the relationships between types (aggregation, composition, inheritance, etc.).

All this is to say that a derived type that contains nothing more than a single scalar value is not especially useful unless what one wants to do with that derived type is only a tiny fraction of the execution time or tiny fraction of the code and is therefore not a performance bottleneck or a coding hassle. In that case, writing and using setters and getters should not seem especially burdensome. On the other hand, if the code plays a critical role in performance or is used in some way that invoking a setter or getter seems burdensome, then there is a good chance that such a fine-grained decomposition of the problem is inappropriate and a different OOD should be considered.

Of all the principles of OOP, the one that I generally adhere to most strictly is data privacy (the only exceptions are during brief debugging sessions). Some on this thread might therefore label me a "purist". I don't think such labels (which sound dismissive and pejorative to me) are helpful. What might be more helpful is talking about the reasoning behind each decision and so one can decide for oneself what is most appropriate for the given coding project.

The reason I hold most strictly to data privacy is that it attacks a problem that grows quadratically with the size of the code: the problem wherein changes to any one line of code can propagate out to impact (and potentially break) any of the other N-1 lines of code. In such a scenario, the data dependencies in the code scale like N(N-1) and the complexity of debugging code where data can be accessed directly and globally is prohibitive as a project grows in size. Spaghetti dependencies are one example of spaghetti code. For more details on this, see the the following open-access journal article:

http://downloads.hindawi.com/journals/sp/2008/393918.pdf

Often it's the case that people don't want to write setters and getters simply because they feel burdensome and they've grown used to accessing unencapsulated data in non-OO language. That works for small projects. The question becomes what happens when you decided to change that component from the default integer kind to another integer kind (e.g., integer(int32))? Without data privacy (which implies the need for setters and getters), how many places of your code are you going to need to search to find all the impacts of that decision. Data privacy goes a long way (though most certainly not all the way) to limiting that search to the module that contains the data and at least simplifying the search outside the module.

To be sure, these issues are not always as easy to quantify as described above, but I've seen OOP described as the most successful programming paradigm from the standpoint that vast majority of modern languages support OOP. It proves its worth most as the size and complexity of the code grows in various measures, but that can also make it challenging to discuss in the context of simplified examples.

Damian Rouson

unread,
Dec 23, 2015, 1:31:43 PM12/23/15
to
On Monday, December 21, 2015 at 7:34:18 AM UTC-8, Wolfgang Kilian wrote:
>
> In Fortran there is no requirement for modules to contain just one type.
> Neither is this required by OO good practice, it merely happens to be
> mandatory in some popular languages other than Fortran. Modules collect
> pieces that logically belong together and sometimes have to access each
> others' internals. (After 2008, the latter part would be deferred to
> submodules.)

This is a great point and it addresses one of the reasons I have had a tendency
to define only one derived type per module (analogous to C++ friend classes).
The reason was that it tended to lead to bloated, catch-all modules that might
or might not have any discernible organization strategy such as collecting the
procedures bound to one type into one part of the module.

I am so far loving my experiences with submodules, which I only started to explore
once submodule support entered the pre-release gfortran 6.0.0 development trunk
a few months ago. I infer from what you're saying that derived types that represent
"friend classes" can be gathered into one module, but their type-bound procedures
can be implemented in separate submodules. I think that's a big win in terms of
modularity. I love this idea.

Damian

Damian Rouson

unread,
Dec 23, 2015, 1:41:12 PM12/23/15
to
P.S. Submodules are supported by the latest versions of the IBM, Cray, GNU, and Intel compilers.

Jos Bergervoet

unread,
Dec 23, 2015, 1:41:52 PM12/23/15
to
Maybe counterproductive as a third qualifier? (If writing clear code
is the objective..) I often find OO practices pointless, confusing, or
counterproductive. And the proponents (whether they are purists or not)
never seem to be prepared to admit it in those cases! Even though this
example seems well-suited to clarify things, they will probably evade
the points you raise.

--
Jos

Damian Rouson

unread,
Dec 23, 2015, 2:10:52 PM12/23/15
to
On Wednesday, December 23, 2015 at 10:41:52 AM UTC-8, Jos Bergervoet wrote:
>
> Maybe counterproductive as a third qualifier? (If writing clear code
> is the objective..) I often find OO practices pointless, confusing, or
> counterproductive. And the proponents (whether they are purists or not)
> never seem to be prepared to admit it in those cases! Even though this
> example seems well-suited to clarify things, they will probably evade
> the points you raise.

Such ad hominem attacks on this heavily testosterone-laden forum are precisely why I often go months without reading it. I'm certain that I'm not the only person who feels that way about this forum. I'm just one of the few gluttons for punishment who occasionally wades into these discussions anyway. Most others who have expressed similar sentiments to me about their experiences here simply stopped reading comp.lang.fortran or stopped responding long ago.

Damian

Jos Bergervoet

unread,
Dec 23, 2015, 3:35:26 PM12/23/15
to
On 12/23/2015 8:10 PM, Damian Rouson wrote:
> On Wednesday, December 23, 2015 at 10:41:52 AM UTC-8, Jos Bergervoet wrote:
>>
>> Maybe counterproductive as a third qualifier? (If writing clear code
>> is the objective..) I often find OO practices pointless, confusing, or
>> counterproductive. And the proponents (whether they are purists or not)
>> never seem to be prepared to admit it in those cases! Even though this
>> example seems well-suited to clarify things, they will probably evade
>> the points you raise.
>
> Such ad hominem attacks

I do not see ad hominem attacks anywhere in this thread.
There clearly is criticism on your behavior, but it is
directed towards the downright insulting way in which you
evade the clearly posed problem of Blokbuster by giving
your long-winded and patronizing reply, without addressing
any of the three proposed approaches in his example.

--
Jos

Damian Rouson

unread,
Dec 23, 2015, 4:16:59 PM12/23/15
to
Labeling proponents of an approach as purists strikes me as dismissive and insulting. Calling an approach pointless is dismissive. Saying that proponents of an approach can't admit when the approach doesn't apply is insulting. To the extent that ad hominem implies attacks on one particular person, I stand corrected regarding the posts prior to the latest ones. Those instead labeled whole groups of people and dismissed an entire programming paradigm. The latest post, however, is clearly directed at one person so ad hominem applies directly.

In all the time I've read the LinkedIn Fortran programmers group, I've never witnessed a discussion in which any person, group of people, or whole programming paradigm was described in such language. Every thread I've seen there is more civil, kind, and respectful than a large fraction of the threads in this forum. Maybe that's because the other group has a moderator, although I'm unaware of he moderator deleting any posts so I suspect the group just attracts a different crowd less interested in insulting people.


Damian

Jos Bergervoet

unread,
Dec 23, 2015, 5:10:56 PM12/23/15
to
On 12/23/2015 10:16 PM, Damian Rouson wrote:
..
> Labeling proponents of an approach as purists strikes me
> as dismissive and insulting.

Do you believe "purist" is an insulting term? Your
definition of insulting seems very strange.

> Calling an approach pointless is dismissive.

Dismissive for the approach, yes. The only claims, however,
were that the approach "seems pointless" in a particular case
(by Blokbuster) and that it was "often found pointless" (by
me) which neither is completely dismissive.

> Saying that proponents of an approach can't
> admit when the approach doesn't apply is insulting.

It is being critical, not insulting.

> To the extent that ad hominem implies attacks on one
> particular person, I stand corrected regarding the posts

I will not hold it against you. But "argumentum ad
hominem" means that criticism on the person is used
*as an argument agianst his claims*.

This, I believe, has not been the case in this thread.
(But you may be right that in other threads it may have
occured).

> prior to the latest ones. Those instead labeled whole groups
> of people

That doesn't seem to make it an argumentum ad hominem,
it then isn't directed against a person.

> and dismissed an entire programming paradigm.

Dismissing a programming paradigm is not an argumentum
ad hominem. And I haven't seen a paradigm being dismissed
here. (Would you consider it insulting?)

> The latest post, however, is clearly directed at one person
> so ad hominem applies directly.

There was no "argumentum ad hominem" in the sense that
criticism on a person was used as an argument to disprove
this person's claims.

There was criticism on a person. There also was
scientific doubt about some of his claims (although
not a priori rejection). But there was no attempt to
use the former to support the latter.

(The criticism on the person, by the way, was of course
purely meant to further illustrate the argumentation
methods in this interesting discussion! Nobody in his
right mind would take it seriously, of course.)

--
Jos



Damian Rouson

unread,
Dec 23, 2015, 6:22:26 PM12/23/15
to
Points well made and well taken.

FortranFan

unread,
Dec 23, 2015, 8:21:43 PM12/23/15
to
On Wednesday, December 23, 2015 at 3:04:34 AM UTC-5, Blokbuster wrote:

> ..
>
> OK, here is a simple (perhaps far too simple) example:
>
> ..
>
> To me, (1) seems pointless, I may as well just make the variables in "month" public. (2) is confusing, as the days in a year are an aspect of a year, not a month. (3) is a possibility, and works, but allows the days of arbitrary groups of months to be summed ..

Yes, your example does indeed come across as too simple; it doesn't seem to reflect what you indicated by "combine or compare the elements of such an array" in the original post. Your original post suggested some aspects of Comparator-type of interfaces that are made available for some OO language implementations, especially with managed run-time environments, e.g. Java (see http://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html)

With such a case, it's rather difficult to get into any meaningful discussion on OO design choices. If your actual situations are along the same lines, what makes best sense to you in line with your needs (whether they be performance or code maintenance, etc.) should be alright.

As some other comments have alluded to in this thread, if you are going to do OO, do note that OO design is very important. You may want to pay close attention to terms such as deep class hierarchies, lazy classes, etc. and their impact on design, coding, performance, etc., if you do investigate OO further.

Good luck,

FortranFan

unread,
Dec 23, 2015, 10:12:19 PM12/23/15
to
On Tuesday, December 22, 2015 at 7:44:23 PM UTC-5, Jos Bergervoet wrote:

>
> ..
> But I see clear arguments given in this thread. What about
> Blokbuster's remark that friend functions "may actually
> break encapsulation, since anything can access them"?
>

My own opinion is similar to those of many C++ practitioners I interact with who hold that when applied with judicious caution, friend functions of a class can actually help enhance data encapsulation for the class. Generally these are used for operator overloading e.g., a binary operator of += or *, etc. So if a friend functions is tied to an operator, the chances of misuse on account of the function having access to private members is reduced somewhat. A point to keep in mind is that if programmers have a need to access private members for anything, say a multiply operation for matrix and vector classes, then they might otherwise do so in ways that either destroy encapsulation or cause pollution (e.g., vector and matrix classes get merged just to support multiply leading to unhealthiness is code design in other aspects).

In Fortran parlance, if one wants to "combine or compare the elements of " private members of a derived type, one option will be allow consumers of the type to do so using defined operators (say, .combine. and .compare.), generally mark all module entities as private, implement module procedures for combine and compare operations, and only mark the operator interface as public. This way, the private members of the type are only accessed via such operators which might be a reasonable compromise between the concept of information hiding and the need to something using private data, as in combination or comparison.

> > The same OO purists will absolutely scoff at Fortran offerings for OO in general
>
> They may not always be the same (I'm not sure if Wolfgang
> will scoff at Fortran offerings, for instance).
>

My point was not that Wolfgang Kilian would scoff at anything, rather that the point he made about some opinions out there suggesting "friend of a class" functionality as being a deficiency is usually held by those who find faults in almost all the popular OO languages (c.f. Tiobe Index) as not being "pure" enough and who want to design better programming languages , but what they come up with rarely get used in practical codes. Fortran has lost some serious ground to C++ in the last 2 decades, even in HPC and scientific/technical computing domains. "Friend of a class" functionality in C++ is used safely and commonly in scientific and engineering applications. To me, that view is of little relevance to the Fortran world.

> ..
>
> Perhaps you could give some arguments as well? (Lest OP
> might do exactly that: more than one in a module!)
>

I though I did so already: see my comment, ".. from a data encapsulation point of view, it is a safe starting point, especially for beginners in OO such as the OP here, to have only one "class" aka derived type with TBPs in a Fortran module." Damian Rouson put it succinctly in another comment in this thread which I agree with and which was the other point I was trying to convey that when one has more than one type per module, it can ".. lead to bloated, catch-all modules that might or might not have any discernible organization strategy such as collecting the procedures bound to one type into one part of the module."

> ..
>
> You may be right. Explicit examples are always very useful.
> But still.. finding the definitive answer about the desirability
> of friend functions could be an important topic by itself.
>

Hope the above comments make my views clearer. OO design is subjective to say the least. Being able to place a specific use case in perspective can help peg the discussion; otherwise, it can be all too abstract.

Richard Maine

unread,
Dec 23, 2015, 10:37:07 PM12/23/15
to
FortranFan <pare...@gmail.com> wrote:

> My point was not that Wolfgang Kilian would scoff at anything, rather that
> the point he made about some opinions out there suggesting "friend of a
> class" functionality as being a deficiency is usually held by those who
> find faults in almost all the popular OO languages (c.f. Tiobe Index) as
> not being "pure" enough and who want to design better programming
> languages , but what they come up with rarely get used in practical
> codes. Fortran has lost some serious ground to C++ in the last 2
> decades, even in HPC and scientific/technical computing domains.
> "Friend of a class" functionality in C++ is used safely and commonly in
> scientific and engineering applications. To me, that view is of little
> relevance to the Fortran world.

Then you might be surprised that there were discussions of exactly that
sort of issue in the Fortran standards committee. I don't recall what
concrete results came from it, but I definitely recall that there were
such discussions.

> I though I did so already: see my comment, ".. from a data encapsulation
> point of view, it is a safe starting point, especially for beginners in
> OO such as the OP here, to have only one "class" aka derived type with
> TBPs in a Fortran module." Damian Rouson put it succinctly in another
> comment in this thread which I agree with and which was the other point
> I was trying to convey that when one has more than one type per module,
> it can ".. lead to bloated, catch-all modules that might or might not
> have any discernible organization strategy such as collecting the
> procedures bound to one type into one part of the module."

It does not strike me as a particularly cogent argument that if we allow
so much as a single case of more than one class defined in a module, it
will inevitably lead to bloated, catch-all modules. Yes, you can take
just about any design idea to ridiculous extremes.

It was noted previously in this thread that a common style is to take a
single area of functionality and put it in a single module, and that
this sometimes involved multiple classes. That doesn't mean you have to
abandon all concepts of organizing things into modules. It is just a
different way of doing such organization. Just because an organization
is different from the one you espouse doesn't mean it inherently leads
to bloat. My bias probably shows because that's the style of module
organization I personally use.

As I noted previously, my Fortran coding style doesn't start with OO
concepts as the driving force behind all the organization. Rather the OO
fits within the organization derived from other things.

FortranFan

unread,
Dec 24, 2015, 2:20:31 AM12/24/15
to
On Wednesday, December 23, 2015 at 10:37:07 PM UTC-5, Richard Maine wrote:

> ..
>
> Then you might be surprised that there were discussions of exactly that
> sort of issue in the Fortran standards committee. ..

This thread is about OO. Let's put the purists aside (nobody likes them anyway :-)); the end product of the committee is a version of Fortran that falls quite a bit short in terms of OO functionality in this day and age (e.g., inadequate support for generics). Languages such as ADA offered much better support for OO well before Fortran committee seriously started considering it for 2003 standard. So pardon me if I take a dim view of any such discussions that may have taken place.

>
> ..
>
> It does not strike me as a particularly cogent argument that if we allow
> so much as a single case of more than one class defined in a module, it
> will inevitably lead to bloated, catch-all modules. ..

How did you arrive at "will inevitably" from "can"? What part of "OOD is very important", "review .. deep-class hierarchies and lazy classes .. in OO literature", "safe starting point .. beginners", "no hard and fast rules", etc. do you not understand? I wonder if you're finding it hard to separate the message from the messenger, since yours truly is only a Fortran enthusiast behind a nom de plume and no credentials.

Kernighan and Plauger wrote in 1978, "A module should do one thing well". By module, they meant it as a subroutine or a function. But the broader concept they were trying to convey back then still applies. If one avoids "lazy classes" (classes that don't pull much weight like the month type in OP's last example), then each class will have sufficient heft to it that can "fill up" a Fortran MODULE (and its SUBMODULEs) in terms of data and logic. Having more than one "class" in a Fortran MODULE can potentially add to complexity and make things difficult. Just as Kernighan and Plauger said, "combining too many functions in a module is a sure fire way to limit its usefulness", combining too many classes in a Fortran module might limit their usefulness. That does NOT mean it should never be done; caveat emptor.

Stefano Zaghi

unread,
Dec 24, 2015, 4:19:15 AM12/24/15
to
@Damian Rouson,

Please, stay here, do not leave us, your contributions is very appreciated.

My best regards.

P.S. @FortranFan: I also think that it is quite difficult here to distinguish messages from messangers.

Richard Maine

unread,
Dec 24, 2015, 11:55:45 AM12/24/15
to
FortranFan <pare...@gmail.com> wrote:

> I wonder if you're finding it hard to separate the message from the
> messenger, since yours truly is only a Fortran enthusiast behind a nom
> de plume and no credentials.

The dangers of theorizing without having any relevant data have been
mentioned here earlier. That was about Fortran, but it applies also to
people. For what its worth, I tend to give very little weight to
"credentials". I had no formal credentials of substance myself before I
joined the committee. I was just a programmer with interest in Fortran.
Never took even a single course in it.

I'll grant I do find it "awkward" having discussions with a
nom-de-plume, but I try to avoid letting that influence me.
I always use my real name and I try not to write things that I would not
want to have connected to me. Being human, I occasionally fail in that
part, but I accept the consequences.

In that regard, I see that I have said nothing actualy about the Fortran
language in this post. But then I think I've said what I have to say
about the Fortran topic at hand and I think I've posted (more than)
enough on it. So I'll stop.

Damian Rouson

unread,
Dec 24, 2015, 11:43:53 PM12/24/15
to
Thanks, Stefano. This is a very enlightening discussion and I'm benefiting from reading it. Mostly I just wanted to sensitize people to the notion that some of the language used in this forum can come across rather harsh and that it does alienate some people who would otherwise contribute. I'm hopeful that the message came through independent of the messenger.

Damian Rouson

unread,
Dec 25, 2015, 2:12:08 AM12/25/15
to
On Wednesday, December 23, 2015 at 8:12:19 PM UTC-7, FortranFan wrote:
>
> Fortran has lost some serious ground to C++ in the last 2 decades, even in HPC and scientific/technical computing domains.

While it is true that Fortran has lost some serious ground to C++, the data I've seen indicate that Fortran remains in the lead in HPC in terms of frequency of use. See, for example, the following data from one of the largest supercomputer centers of the U.S. Department of Energy:

https://dl.dropboxusercontent.com/u/7038972/nersc-user-data.pdf

Over the past decade or so, I've seen very similar data from U.S. Department of Defense centers and from European supercomputer centers (in particular, PRACE) and other sources. And there are some research communities where C++ has made very few inroads as far as I know. One example that I often use when I talk with non-Fortran programmers is "If you looked at a weather forecast today, you were almost certainly looking at the results of a Fortran program." And that 196-nation climate deal that was just struck in Paris? As far as I know, the predictions on which it is based came from Fortran programs as well. I think the extent to which Fortran has lost ground to C++ is significant, but probably not as significant as most people would expect.

Because comp.lang.fortran posts have a long life, I should mention that the above URL is just something I created for temporary use. I'll probably move the file to a more permanent location before long.

Damian

Wolfgang Kilian

unread,
Jan 7, 2016, 10:32:32 AM1/7/16
to
That should be a strategy to combine modern Fortran concepts in a most
productive way.

I have to admit that I'm theorizing on the part of submodules; my
favorite debugging compiler doesn't support submodules, yet. But I'm
optimistic.
0 new messages